package mineplex.servermonitor; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; public class ServerMonitor { private static Repository _repository = new Repository(); private static int _count = 0; public static void main (String args[]) { _repository.initialize(); while (true) { if (_count % 10 == 0) { for (ServerStatusData statusData : _repository.retrieveOldServerStatuses()) { System.out.println("----Old Server Status----> " + statusData.Address + ", " + statusData.Name); killServer(statusData); } List dynamicServers = new ArrayList(_repository.retrieveDynamicServers()); Collection serverGroups = _repository.retrieveServerGroups(); HashMap groupStatusList = _repository.retrieveGroupStatusData(); for (ServerGroupData serverGroup : serverGroups) { if (!groupStatusList.containsKey(serverGroup.Name)) { groupStatusList.put(serverGroup.Name, new GroupStatusData()); } GroupStatusData groupStatus = groupStatusList.get(serverGroup.Name); int serversToAdd = Math.max(serverGroup.RequiredTotalServers - groupStatus.getTotalServers(), serverGroup.RequiredJoinableServers - groupStatus.getJoinableCount()); int serversToKill = (groupStatus.getTotalServers() > serverGroup.RequiredTotalServers && groupStatus.getJoinableCount() > serverGroup.RequiredJoinableServers) ? Math.min(groupStatus.getJoinableCount() - serverGroup.RequiredJoinableServers, groupStatus.EmptyServers.size()) : 0; while (serversToAdd > 0) { int serverNum = groupStatus.getNextServerNumber(); Collections.sort(dynamicServers, new DynamicServerSorter()); DynamicServerData bestServer = getBestDynamicServer(dynamicServers, serverGroup); if (bestServer == null) { System.out.println("No best dynamic server available for group " + serverGroup.Name); break; } System.out.println("Adding server for Server Group " + serverGroup.Name + " Req Total: " + serverGroup.RequiredTotalServers + " Req Joinable: " + serverGroup.RequiredJoinableServers + " | Actual Total: " + groupStatus.getTotalServers() + " Actual Joinable: " + groupStatus.getJoinableCount()); startServer(bestServer, serverGroup, serverNum); serversToAdd--; } while (serversToKill > 0) { System.out.println("Killing excess server for Server Group " + serverGroup.Name + " Req Total: " + serverGroup.RequiredTotalServers + " Req Joinable: " + serverGroup.RequiredJoinableServers + " | Actual Total: " + groupStatus.getTotalServers() + " Actual Joinable: " + groupStatus.getJoinableCount()); killServer(groupStatus.EmptyServers.get(0)); serversToKill--; } } } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } _count++; _count %= 10000; } } private static DynamicServerData getBestDynamicServer(Collection dynamicServers, ServerGroupData serverGroup) { DynamicServerData bestServer = null; for (DynamicServerData serverData : dynamicServers) { System.out.println("Checking " + serverData.Name + " Cpu:" + serverData.AvailableCPU + " Ram:" + serverData.AvailableRAM); if (serverData.AvailableRAM > serverGroup.RequiredRAM && serverData.AvailableCPU > serverGroup.RequiredCPU) { if (bestServer == null) { bestServer = serverData; if (!serverData.ServerGroupCount.containsKey(serverGroup.Name)) break; } else if (serverData.ServerGroupCount.containsKey(serverGroup.Name)) { if (serverData.ServerGroupCount.get(serverGroup.Name) < bestServer.ServerGroupCount.get(serverGroup.Name)) bestServer = serverData; } } } return bestServer; } private static void killServer(ServerStatusData serverToKill) { String cmd = "/home/mineplex/easyRemoteKillServer.sh"; Process process = null; try { process = new ProcessBuilder(new String[] {"/bin/sh", cmd, serverToKill.Address, serverToKill.Name}).start(); process.wait(1000); BufferedReader reader=new BufferedReader(new InputStreamReader(process.getInputStream())); String line = reader.readLine(); while(line != null) { System.out.println(line); line=reader.readLine(); } } catch (Exception e) { e.printStackTrace(); } finally { if (process != null) { process.destroy(); } } _repository.removeServerRecord(serverToKill); System.out.println("Sent kill command to " + serverToKill.Address + " for " + serverToKill.Name); } private static void startServer(DynamicServerData serverSpace, ServerGroupData serverGroup, int serverNum) { String cmd = "/home/mineplex/easyRemoteStartServer.sh"; Process process = null; try { process = new ProcessBuilder(new String[] {"/bin/sh", cmd, serverSpace.Address, serverGroup.ScriptName, serverGroup.Prefix + "-" + serverNum, "1", serverSpace.US ? "us" : "eu"}).start(); process.wait(3000); BufferedReader reader=new BufferedReader(new InputStreamReader(process.getInputStream())); String line = reader.readLine(); while(line != null) { System.out.println(line); line=reader.readLine(); } } catch (Exception e) { e.printStackTrace(); } finally { if (process != null) { process.destroy(); } } serverSpace.setServerGroupCount(serverGroup, serverSpace.ServerGroupCount.containsKey(serverGroup.Name) ? (serverSpace.ServerGroupCount.get(serverGroup.Name) + 1) : 1); System.out.println("Sent start command (" + serverSpace.Address + "," + serverGroup.ScriptName + "," + serverGroup.Prefix + "-" + serverNum + ", 1," + (serverSpace.US ? "us" : "eu") + ")"); } }