From 5e3ae40d0389a347a3d88042e757e971c2007147 Mon Sep 17 00:00:00 2001 From: Michael Rausch Date: Fri, 22 Sep 2017 00:01:13 +1200 Subject: [PATCH] Made discovery more reliable & added docs/tests - Added unit tests - Added documentation for discovery classes - Improved error handling Tags: #story[1281] --- src/main/java/seng302/App.java | 59 +++++---- .../discoveryServer/DiscoveryServer.java | 117 ++++++++++++++++++ .../DiscoveryServerClient.java} | 54 ++++++-- .../util}/ReadableByteInputStream.java | 18 ++- .../util}/ServerListing.java | 8 +- .../util}/ServerRepoStreamParser.java | 2 +- .../util}/ServerTable.java | 42 +++++-- .../seng302/gameServer/ServerAdvertiser.java | 11 +- .../messages/ServerRegistrationMessage.java | 2 +- .../serverRepository/ServerRepository.java | 86 ------------- .../controllers/LobbyController.java | 6 +- .../controllers/ServerListController.java | 21 +++- .../visualiser/controllers/ViewManager.java | 1 - .../serverDiscovery/ServerTableTest.java | 57 +++++++++ .../serverDiscovery/testStreamParser.java | 31 +++++ 15 files changed, 360 insertions(+), 155 deletions(-) create mode 100644 src/main/java/seng302/discoveryServer/DiscoveryServer.java rename src/main/java/seng302/{serverRepository/ServerRepositoryClient.java => discoveryServer/DiscoveryServerClient.java} (53%) rename src/main/java/seng302/{serverRepository => discoveryServer/util}/ReadableByteInputStream.java (63%) rename src/main/java/seng302/{serverRepository => discoveryServer/util}/ServerListing.java (93%) rename src/main/java/seng302/{serverRepository => discoveryServer/util}/ServerRepoStreamParser.java (98%) rename src/main/java/seng302/{serverRepository => discoveryServer/util}/ServerTable.java (61%) delete mode 100644 src/main/java/seng302/serverRepository/ServerRepository.java create mode 100644 src/test/java/seng302/serverDiscovery/ServerTableTest.java create mode 100644 src/test/java/seng302/serverDiscovery/testStreamParser.java diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index 9616b7a0..870369dc 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -10,7 +10,7 @@ import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import seng302.serverRepository.ServerRepository; +import seng302.discoveryServer.DiscoveryServer; import seng302.visualiser.controllers.ViewManager; public class App extends Application { @@ -27,45 +27,52 @@ public class App extends Application { .getLogger(Logger.ROOT_LOGGER_NAME); options.addOption("debugLevel", true, "Set the application debug level"); - options.addOption("runAsCache", false, "Run as a server cache for server discovery"); + options.addOption("runAsDiscoveryServer", false, "Run as a discovery server"); + options.addOption("discoveryDevMode", false, "Use a local discovery server"); cmd = parser.parse(options, args); - if (cmd.hasOption("runAsCache")){ + if (cmd.hasOption("runAsDiscoveryServer")){ isRunningAsCache = true; + rootLogger.setLevel(Level.ALL); + return; + } + + if (cmd.hasOption("discoveryDevMode")) { + DiscoveryServer.DISCOVERY_SERVER = "localhost"; } if (cmd.hasOption("debugLevel")) { - switch (cmd.getOptionValue("debugLevel")) { - case "DEBUG": - rootLogger.setLevel(Level.DEBUG); - break; + switch (cmd.getOptionValue("debugLevel")) { + case "DEBUG": + rootLogger.setLevel(Level.DEBUG); + break; - case "ALL": - rootLogger.setLevel(Level.ALL); - break; + case "ALL": + rootLogger.setLevel(Level.ALL); + break; - case "WARNING": - rootLogger.setLevel(Level.WARN); - break; + case "WARNING": + rootLogger.setLevel(Level.WARN); + break; - case "ERROR": - rootLogger.setLevel(Level.ERROR); - break; + case "ERROR": + rootLogger.setLevel(Level.ERROR); + break; - case "INFO": - rootLogger.setLevel(Level.INFO); + case "INFO": + rootLogger.setLevel(Level.INFO); - case "TRACE": - rootLogger.setLevel(Level.TRACE); + case "TRACE": + rootLogger.setLevel(Level.TRACE); - default: - rootLogger.setLevel(Level.ALL); - } - } else { - rootLogger.setLevel(Level.WARN); + default: + rootLogger.setLevel(Level.ALL); } + } else { + rootLogger.setLevel(Level.WARN); + } } @Override @@ -85,7 +92,7 @@ public class App extends Application { launch(args); } else{ - ServerRepository serverRepository = new ServerRepository(); + new DiscoveryServer(); } } } diff --git a/src/main/java/seng302/discoveryServer/DiscoveryServer.java b/src/main/java/seng302/discoveryServer/DiscoveryServer.java new file mode 100644 index 00000000..2c184e8b --- /dev/null +++ b/src/main/java/seng302/discoveryServer/DiscoveryServer.java @@ -0,0 +1,117 @@ +package seng302.discoveryServer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import seng302.gameServer.messages.Message; +import seng302.gameServer.messages.RoomCodeRequest; +import seng302.gameServer.messages.ServerRegistrationMessage; +import seng302.model.stream.packets.PacketType; +import seng302.discoveryServer.util.ServerListing; +import seng302.discoveryServer.util.ServerRepoStreamParser; +import seng302.discoveryServer.util.ServerTable; + +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Arrays; +import java.util.Random; + +public class DiscoveryServer { + public static final String ANSI_GREEN = "\u001B[32m"; + public static final String ANSI_YELLOW = "\u001B[33m"; + public static final String ANSI_BLUE = "\u001B[34m"; + public static final String ANSI_RESET = "\u001B[0m"; + public static String DISCOVERY_SERVER = "party.sydney.srv.michaelrausch.nz"; + + private ServerTable serverTable; + public static final Integer PORT_NUMBER = 9969; + + private final Logger logger = LoggerFactory.getLogger(DiscoveryServer.class); + + private void displayHeader(){ + String selectedColor = Arrays.asList(ANSI_BLUE, ANSI_GREEN, ANSI_YELLOW).get(new Random().nextInt(2)); + System.out.println(selectedColor); + System.out.println(" .ccccc. \n" + + " .cc;'coooxkl;. \n" + + " .:c:::c:,,,,,;c;;,.'. \n" + + " .clc,',:,..:xxocc;'..c; \n" + + " .c:,';:ox:..:c,,,,,,...cd, \n" + + " .c:'.,oxxxxl::l:.,loll;..;ol. \n" + + " ;Oc..:xxxxxxxxx:.,llll,....oc \n" + + " .,;,',:loxxxxxxxxx:.,llll;.,,.'ld, \n" + + " .lo;..:xxxxxxxxxxxx:.'cllc,.:l:'cO; \n" + + " .:;...'cxxxxxxxxxxxxoc;,::,..cdl;;l' \n" + + " .cl;':,'';oxxxxxxdxxxxxx:....,cooc,cO; \n" + + " .,,,::;,lxoc:,,:lxxxxxxxxxxxo:,,;lxxl;'oNc \n" + + " .cdxo;':lxxxxxxc'';cccccoxxxxxxxxxxxxo,.;lc. " + ANSI_YELLOW + "Party-Parrots-At-Sea Discovery Server v0.1 " + selectedColor +"\n" + + " .loc'.'lxxxxxxxxocc;''''';ccoxxxxxxxxx:..oc \n" + + "olc,..',:cccccccccccc:;;;;;;;;:ccccccccc,.'c, \n" + + "Ol;......................................;l' "); + System.out.println(ANSI_RESET); + } + + public DiscoveryServer() throws Exception { + displayHeader(); + serverTable = new ServerTable(); + + ServerSocket serverSocket; + + try{ + serverSocket = new ServerSocket(PORT_NUMBER); + } + catch(java.net.BindException e){ + logger.error("FATAL - Could not bind socket, are you sure there isn't already an instance running?"); + System.exit(1); + return; + } + + logger.info("Started successfully - Now accepting connections"); + + while (true){ + Socket clientSocket = serverSocket.accept(); + + parseRequest(clientSocket); + + clientSocket.close(); + } + } + + + private void parseRequest(Socket clientSocket) throws Exception { + ServerRepoStreamParser parser = new ServerRepoStreamParser(clientSocket.getInputStream()); + + if (clientSocket.isConnected() && !clientSocket.isClosed()){ + PacketType parsePacketResult = parser.parse(); + + switch (parsePacketResult){ + case SERVER_REGISTRATION: + ServerListing listing = parser.getServerListing(); + + if (!serverTable.getAllServers().contains(listing)){ + listing.setRoomCode(serverTable.getNextRoomCode().toString()); + } + + serverTable.addServer(listing); + + Message serverRegMessage = new RoomCodeRequest(listing.getRoomCode()); + clientSocket.getOutputStream().write(serverRegMessage.getBuffer()); + break; + + case ROOM_CODE_REQUEST: + String desiredRoomCode = parser.getRoomCode(); + + ServerListing serverListing = serverTable.getServerByRoomCode(desiredRoomCode); + Message response; + + if (serverListing != null){ + response = new ServerRegistrationMessage(serverListing.getServerName(), serverListing.getMapName(), serverListing.getAddress(), serverListing.getPortNumber(), 0, 0, desiredRoomCode); + } + else{ + response = new ServerRegistrationMessage("", "", "", 0, 0, 0, ""); + } + + clientSocket.getOutputStream().write(response.getBuffer()); + break; + } + } + } +} diff --git a/src/main/java/seng302/serverRepository/ServerRepositoryClient.java b/src/main/java/seng302/discoveryServer/DiscoveryServerClient.java similarity index 53% rename from src/main/java/seng302/serverRepository/ServerRepositoryClient.java rename to src/main/java/seng302/discoveryServer/DiscoveryServerClient.java index 85d8135a..d2008efc 100644 --- a/src/main/java/seng302/serverRepository/ServerRepositoryClient.java +++ b/src/main/java/seng302/discoveryServer/DiscoveryServerClient.java @@ -1,24 +1,39 @@ -package seng302.serverRepository; +package seng302.discoveryServer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import seng302.gameServer.messages.Message; import seng302.gameServer.messages.RoomCodeRequest; import seng302.gameServer.messages.ServerRegistrationMessage; import seng302.model.stream.packets.PacketType; +import seng302.discoveryServer.util.ServerListing; +import seng302.discoveryServer.util.ServerRepoStreamParser; import java.net.Socket; import java.util.Timer; import java.util.TimerTask; -public class ServerRepositoryClient { +public class DiscoveryServerClient { + private final Integer UPDATE_INTERVAL_MS = 5000; private static String roomCode = null; private Timer serverListingUpdateTimer; + private Logger logger = LoggerFactory.getLogger(DiscoveryServerClient.class); - public ServerRepositoryClient() { + public DiscoveryServerClient() { } + /** + * Register the server with the discovery server + * @param serverListing The listing to register + */ public void register(ServerListing serverListing){ + if (serverListingUpdateTimer != null){ + serverListingUpdateTimer.cancel(); + serverListingUpdateTimer = null; + } + serverListingUpdateTimer = new Timer(); serverListingUpdateTimer.schedule(new TimerTask() { @@ -27,19 +42,28 @@ public class ServerRepositoryClient { try { sendRegistrationUpdate(serverListing); } catch (Exception e) { - e.printStackTrace();//todo proper error handling + logger.debug("Could not update server listing"); } } - }, 0, 5000); + }, 0, UPDATE_INTERVAL_MS); } + /** + * Stop updating the server registration updates + */ public void unregister(){ serverListingUpdateTimer.cancel(); } + /** + * Gets the connection information for a server given a room code + * + * @param roomCode The room code to search for + * @return The ServerListing, or null if there was an error + * @throws Exception . + */ public ServerListing getServerForRoomCode(String roomCode) throws Exception { - // TODO replace localhost with server - Socket socket = new Socket("localhost", 9999); + Socket socket = new Socket(DiscoveryServer.DISCOVERY_SERVER, DiscoveryServer.PORT_NUMBER); ServerRepoStreamParser parser = new ServerRepoStreamParser(socket.getInputStream()); Message request = new RoomCodeRequest(roomCode); //roomCode); @@ -48,7 +72,7 @@ public class ServerRepositoryClient { PacketType packetType = parser.parse(); if (packetType != PacketType.SERVER_REGISTRATION){ - System.out.println("Wrong packet type"); + logger.debug("Wrong packet received in response to a room code request"); return null; } @@ -57,8 +81,14 @@ public class ServerRepositoryClient { return parser.getServerListing(); } + /** + * Sends a registration update to the discovery server. + * + * @param serverListing The server listing to send + * @throws Exception IF there was an error sending the update + */ private void sendRegistrationUpdate(ServerListing serverListing) throws Exception { - Socket socket = new Socket("localhost", 9999); + Socket socket = new Socket(DiscoveryServer.DISCOVERY_SERVER, DiscoveryServer.PORT_NUMBER); ServerRepoStreamParser parser = new ServerRepoStreamParser(socket.getInputStream()); Message req = new ServerRegistrationMessage(serverListing); @@ -68,18 +98,22 @@ public class ServerRepositoryClient { PacketType packetType = parser.parse(); if (packetType != PacketType.ROOM_CODE_REQUEST){ + socket.close(); return; } String roomCode = parser.getRoomCode(); if (roomCode.length() != 0){ - ServerRepositoryClient.roomCode = roomCode; + DiscoveryServerClient.roomCode = roomCode; } socket.close(); } + /** + * @return The last room code received by the client + */ public static String getRoomCode(){ return roomCode; } diff --git a/src/main/java/seng302/serverRepository/ReadableByteInputStream.java b/src/main/java/seng302/discoveryServer/util/ReadableByteInputStream.java similarity index 63% rename from src/main/java/seng302/serverRepository/ReadableByteInputStream.java rename to src/main/java/seng302/discoveryServer/util/ReadableByteInputStream.java index 4695d7e7..088a2d9a 100644 --- a/src/main/java/seng302/serverRepository/ReadableByteInputStream.java +++ b/src/main/java/seng302/discoveryServer/util/ReadableByteInputStream.java @@ -1,4 +1,4 @@ -package seng302.serverRepository; +package seng302.discoveryServer.util; import java.io.InputStream; @@ -9,6 +9,12 @@ public class ReadableByteInputStream { this.is = is; } + /** + * Get n bytes from the input stream + * @param n number of bytes + * @return the bytes read + * @throws Exception . + */ public byte[] getBytes(int n) throws Exception { byte[] bytes = new byte[n]; for (int i = 0; i < n; i++) { @@ -17,12 +23,22 @@ public class ReadableByteInputStream { return bytes; } + /** + * Skip n bytes + * @param n number of bytes to skip + * @throws Exception + */ public void skipBytes(long n) throws Exception { for (int i = 0; i < n; i++) { readByte(); } } + /** + * Read the next byte from the stream + * @return The byte that was read + * @throws Exception . + */ public int readByte() throws Exception { int currentByte = is.read(); diff --git a/src/main/java/seng302/serverRepository/ServerListing.java b/src/main/java/seng302/discoveryServer/util/ServerListing.java similarity index 93% rename from src/main/java/seng302/serverRepository/ServerListing.java rename to src/main/java/seng302/discoveryServer/util/ServerListing.java index 58d223e6..a4924d02 100644 --- a/src/main/java/seng302/serverRepository/ServerListing.java +++ b/src/main/java/seng302/discoveryServer/util/ServerListing.java @@ -1,7 +1,7 @@ -package seng302.serverRepository; +package seng302.discoveryServer.util; public class ServerListing { - private static final int SERVER_TTL_DEFAULT = 10; + public final static int SERVER_TTL_DEFAULT = 10; private String serverName = ""; private String mapName = ""; @@ -106,4 +106,8 @@ public class ServerListing { public String getAddress() { return address; } + + public void setTtl(Integer ttl){ + this.ttl = ttl; + } } diff --git a/src/main/java/seng302/serverRepository/ServerRepoStreamParser.java b/src/main/java/seng302/discoveryServer/util/ServerRepoStreamParser.java similarity index 98% rename from src/main/java/seng302/serverRepository/ServerRepoStreamParser.java rename to src/main/java/seng302/discoveryServer/util/ServerRepoStreamParser.java index 80e374b0..2de2d7b1 100644 --- a/src/main/java/seng302/serverRepository/ServerRepoStreamParser.java +++ b/src/main/java/seng302/discoveryServer/util/ServerRepoStreamParser.java @@ -1,4 +1,4 @@ -package seng302.serverRepository; +package seng302.discoveryServer.util; import seng302.gameServer.messages.Message; diff --git a/src/main/java/seng302/serverRepository/ServerTable.java b/src/main/java/seng302/discoveryServer/util/ServerTable.java similarity index 61% rename from src/main/java/seng302/serverRepository/ServerTable.java rename to src/main/java/seng302/discoveryServer/util/ServerTable.java index 6f662b68..ba6e1101 100644 --- a/src/main/java/seng302/serverRepository/ServerTable.java +++ b/src/main/java/seng302/discoveryServer/util/ServerTable.java @@ -1,12 +1,14 @@ -package seng302.serverRepository; +package seng302.discoveryServer.util; -import com.sun.corba.se.spi.activation.Server; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.*; public class ServerTable { private List servers; private int lastRoomCode = 4020; + private Logger logger = LoggerFactory.getLogger(ServerTable.class); public ServerTable(){ servers = new ArrayList<>(); @@ -17,9 +19,11 @@ public class ServerTable { updateServers(); } }, 0, 1000); - } + /** + * Update the servers TTL values, and then remove expired servers + */ private void updateServers() { List serversToRemove = new ArrayList<>(); @@ -27,38 +31,52 @@ public class ServerTable { server.decrementTtl(); if (server.hasTtlExpired()){ + logger.debug("Removed expired server - " + server.getServerName()); serversToRemove.add(server); } } - for (ServerListing server : serversToRemove){ - System.out.println("Removing " + server.getServerName()); - servers.remove(server); - } + servers.removeAll(serversToRemove); } + /** + * Add a server to the table + * @param server The server to add + */ public void addServer(ServerListing server){ if (servers.contains(server)){ updateTtlForServer(server); return; } - + logger.debug("Added new server - " + server.getServerName()); servers.add(server); } + /** + * Update the TTL for a given server to the default TTL value + * @param server The server to update + */ private void updateTtlForServer(ServerListing server) { for (ServerListing serverListing : servers){ if (server.equals(serverListing)){ - System.out.println("Refreshing TTL For " + server.getServerName()); serverListing.refreshTtl(); } } } + /** + * @return All the servers in the table + */ public List getAllServers(){ return Collections.unmodifiableList(servers); } + /** + * Get a server from the table given its room code + * @param roomCode The room code to search for + * @return The ServerListing of the found server, or null + * the server wasn't found + */ public ServerListing getServerByRoomCode(String roomCode){ for (ServerListing serverListing : servers){ if (serverListing.getRoomCode().equals(roomCode)){ @@ -69,11 +87,11 @@ public class ServerTable { return null; } + /** + * @return The next available room code + */ public Integer getNextRoomCode(){ - System.out.println(lastRoomCode); lastRoomCode += 1; return lastRoomCode; } - - } diff --git a/src/main/java/seng302/gameServer/ServerAdvertiser.java b/src/main/java/seng302/gameServer/ServerAdvertiser.java index b32dc0de..479ffca6 100644 --- a/src/main/java/seng302/gameServer/ServerAdvertiser.java +++ b/src/main/java/seng302/gameServer/ServerAdvertiser.java @@ -1,10 +1,7 @@ package seng302.gameServer; -import com.sun.org.apache.xpath.internal.operations.Bool; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import seng302.serverRepository.ServerListing; -import seng302.serverRepository.ServerRepositoryClient; +import seng302.discoveryServer.util.ServerListing; +import seng302.discoveryServer.DiscoveryServerClient; import javax.jmdns.JmDNS; import javax.jmdns.ServiceInfo; @@ -38,14 +35,14 @@ public class ServerAdvertiser { private static ServerAdvertiser instance = null; private static JmDNS jmdnsInstance = null; private ServiceInfo serviceInfo; // Note: Whenever this is changed, our service will be re-registered on the network. - private ServerRepositoryClient repositoryClient; + private DiscoveryServerClient repositoryClient; private Hashtable props; private ServerAdvertiser() throws IOException{ jmdnsInstance = JmDNS.create(InetAddress.getByName(getLocalHostIp())); - repositoryClient = new ServerRepositoryClient(); + repositoryClient = new DiscoveryServerClient(); props = new Hashtable<>(); props.put("map", ""); diff --git a/src/main/java/seng302/gameServer/messages/ServerRegistrationMessage.java b/src/main/java/seng302/gameServer/messages/ServerRegistrationMessage.java index ab083147..42e762e6 100644 --- a/src/main/java/seng302/gameServer/messages/ServerRegistrationMessage.java +++ b/src/main/java/seng302/gameServer/messages/ServerRegistrationMessage.java @@ -1,6 +1,6 @@ package seng302.gameServer.messages; -import seng302.serverRepository.ServerListing; +import seng302.discoveryServer.util.ServerListing; public class ServerRegistrationMessage extends Message { private int size; diff --git a/src/main/java/seng302/serverRepository/ServerRepository.java b/src/main/java/seng302/serverRepository/ServerRepository.java deleted file mode 100644 index 0ba7c49e..00000000 --- a/src/main/java/seng302/serverRepository/ServerRepository.java +++ /dev/null @@ -1,86 +0,0 @@ -package seng302.serverRepository; - -import seng302.gameServer.messages.Message; -import seng302.gameServer.messages.RoomCodeRequest; -import seng302.gameServer.messages.ServerRegistrationMessage; -import seng302.model.stream.packets.PacketType; - -import java.net.ServerSocket; -import java.net.Socket; -import java.util.Timer; -import java.util.TimerTask; - -public class ServerRepository { - private ServerTable serverTable; - - public ServerRepository() throws Exception { - System.out.println(" -- Starting Server Repository -- "); - serverTable = new ServerTable(); - - ServerSocket serverSocket = new ServerSocket(9999); - - -// // TODO Remove later, this is for testing -// new Timer().schedule(new TimerTask() { -// @Override -// public void run() { -// try { -// System.out.println("Starting repo client"); -// new ServerRepositoryClient(); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// } -// }, 5000); - - - - while (true){ - Socket clientSocket = serverSocket.accept(); - - parseRequest(clientSocket); - - clientSocket.close(); - } - } - - - private void parseRequest(Socket clientSocket) throws Exception { - ServerRepoStreamParser parser = new ServerRepoStreamParser(clientSocket.getInputStream()); - - if (clientSocket.isConnected() && !clientSocket.isClosed()){ - PacketType parsePacketResult = parser.parse(); - - switch (parsePacketResult){ - case SERVER_REGISTRATION: - ServerListing listing = parser.getServerListing(); - - if (!serverTable.getAllServers().contains(listing)){ - listing.setRoomCode(serverTable.getNextRoomCode().toString()); - } - - serverTable.addServer(listing); - - Message serverRegMessage = new RoomCodeRequest(listing.getRoomCode()); - clientSocket.getOutputStream().write(serverRegMessage.getBuffer()); - break; - - case ROOM_CODE_REQUEST: - String desiredRoomCode = parser.getRoomCode(); - - ServerListing serverListing = serverTable.getServerByRoomCode(desiredRoomCode); - Message response; - - if (serverListing != null){ - response = new ServerRegistrationMessage(serverListing.getServerName(), serverListing.getMapName(), serverListing.getAddress(), serverListing.getPortNumber(), 0, 0, desiredRoomCode); - } - else{ - response = new ServerRegistrationMessage("", "", "", 0, 0, 0, ""); - } - - clientSocket.getOutputStream().write(response.getBuffer()); - break; - } - } - } -} diff --git a/src/main/java/seng302/visualiser/controllers/LobbyController.java b/src/main/java/seng302/visualiser/controllers/LobbyController.java index a00c4610..a3cf0bfb 100644 --- a/src/main/java/seng302/visualiser/controllers/LobbyController.java +++ b/src/main/java/seng302/visualiser/controllers/LobbyController.java @@ -22,7 +22,7 @@ import seng302.model.RaceState; import seng302.model.mark.CompoundMark; import seng302.model.mark.Corner; import seng302.model.stream.xml.parser.RaceXMLData; -import seng302.serverRepository.ServerRepositoryClient; +import seng302.discoveryServer.DiscoveryServerClient; import seng302.utilities.Sounds; import seng302.visualiser.GameView; import seng302.visualiser.controllers.cells.PlayerCell; @@ -83,8 +83,8 @@ public class LobbyController implements Initializable { serverName.setText(ViewManager.getInstance().getProperty("serverName")); mapName.setText(ViewManager.getInstance().getProperty("mapName")); - if (ServerRepositoryClient.getRoomCode() != null){ - setRoomCode(ServerRepositoryClient.getRoomCode()); + if (DiscoveryServerClient.getRoomCode() != null){ + setRoomCode(DiscoveryServerClient.getRoomCode()); } ViewManager.getInstance().getPlayerList().addListener((ListChangeListener) c -> Platform.runLater(this::refreshPlayerList)); diff --git a/src/main/java/seng302/visualiser/controllers/ServerListController.java b/src/main/java/seng302/visualiser/controllers/ServerListController.java index a21b8ad4..833fa9af 100644 --- a/src/main/java/seng302/visualiser/controllers/ServerListController.java +++ b/src/main/java/seng302/visualiser/controllers/ServerListController.java @@ -15,6 +15,7 @@ import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; import javafx.geometry.Pos; +import javafx.scene.control.Alert; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.input.KeyCode; @@ -22,9 +23,10 @@ import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import seng302.discoveryServer.DiscoveryServer; import seng302.gameServer.ServerDescription; -import seng302.serverRepository.ServerListing; -import seng302.serverRepository.ServerRepositoryClient; +import seng302.discoveryServer.util.ServerListing; +import seng302.discoveryServer.DiscoveryServerClient; import seng302.utilities.Sounds; import seng302.visualiser.ServerListener; import seng302.visualiser.ServerListenerDelegate; @@ -169,10 +171,19 @@ public class ServerListController implements Initializable, ServerListenerDelega private void connectToRoomCode(String roomCode){ try { - ServerListing serverListing = new ServerRepositoryClient().getServerForRoomCode(roomCode); + ServerListing serverListing = new DiscoveryServerClient().getServerForRoomCode(roomCode); ViewManager.getInstance().getGameClient().runAsClient(serverListing.getAddress(), serverListing.getPortNumber()); - } catch (Exception e) { - e.printStackTrace(); + } + catch (java.net.ConnectException e){ + //TODO Add proper dialog + logger.warn("Couldn't connect to discovery server"); + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setHeaderText("Couldn't connect to discovery server"); + alert.setContentText("Couldn't connect to " + DiscoveryServer.DISCOVERY_SERVER); + alert.showAndWait(); + } + catch (Exception e) { + logger.warn("Error discovering room code"); } } diff --git a/src/main/java/seng302/visualiser/controllers/ViewManager.java b/src/main/java/seng302/visualiser/controllers/ViewManager.java index 23942294..e2427107 100644 --- a/src/main/java/seng302/visualiser/controllers/ViewManager.java +++ b/src/main/java/seng302/visualiser/controllers/ViewManager.java @@ -20,7 +20,6 @@ import javafx.stage.Stage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import seng302.gameServer.ServerAdvertiser; -import seng302.serverRepository.ServerRepositoryClient; import seng302.utilities.BonjourInstallChecker; import seng302.utilities.Sounds; import seng302.visualiser.GameClient; diff --git a/src/test/java/seng302/serverDiscovery/ServerTableTest.java b/src/test/java/seng302/serverDiscovery/ServerTableTest.java new file mode 100644 index 00000000..320b1ad4 --- /dev/null +++ b/src/test/java/seng302/serverDiscovery/ServerTableTest.java @@ -0,0 +1,57 @@ +package seng302.serverDiscovery; + +import org.junit.BeforeClass; +import org.junit.Test; +import seng302.discoveryServer.util.ServerListing; +import seng302.discoveryServer.util.ServerTable; + +import java.util.Objects; + +import static org.junit.Assert.assertTrue; + +public class ServerTableTest { + private static ServerTable serverTable; + + @BeforeClass + public static void setup(){ + serverTable = new ServerTable(); + } + + @Test + public void testAddServer(){ + ServerListing listing = new ServerListing("", "", "", 12, 12); + serverTable.addServer(listing); + + assertTrue(serverTable.getAllServers().contains(listing)); + } + + @Test + public void testGetNextRoomCodeIsUnique(){ + assertTrue(!Objects.equals(serverTable.getNextRoomCode(), serverTable.getNextRoomCode())); + } + + @Test + public void testGetServerRoomCode(){ + ServerListing listing = new ServerListing("123", "", "", 12, 12); + listing.setRoomCode(serverTable.getNextRoomCode().toString()); + serverTable.addServer(listing); + + ServerListing result = serverTable.getServerByRoomCode(listing.getRoomCode()); + + assertTrue(result.equals(listing)); + } + + @Test + public void testServersRemovedOnExpiry() throws InterruptedException { + ServerListing listing = new ServerListing("432", "221", "", 12, 12); + listing.setTtl(1); + + serverTable.addServer(listing); + + listing.decrementTtl(); + + Thread.sleep(1000); + + assertTrue(!serverTable.getAllServers().contains(listing)); + } +} diff --git a/src/test/java/seng302/serverDiscovery/testStreamParser.java b/src/test/java/seng302/serverDiscovery/testStreamParser.java new file mode 100644 index 00000000..d927f50f --- /dev/null +++ b/src/test/java/seng302/serverDiscovery/testStreamParser.java @@ -0,0 +1,31 @@ +package seng302.serverDiscovery; + +import org.junit.Test; +import seng302.gameServer.messages.Message; +import seng302.gameServer.messages.RoomCodeRequest; +import seng302.model.stream.packets.PacketType; +import seng302.discoveryServer.util.ServerRepoStreamParser; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import static org.junit.Assert.assertTrue; + +public class testStreamParser { + private static ServerRepoStreamParser parser; + private static InputStream inputStream; + + private static void setupWithByteArray(byte[] bytes){ + inputStream = new ByteArrayInputStream(bytes); + parser = new ServerRepoStreamParser(inputStream); + } + + @Test + public void testParseRoomCodeRequest() throws Exception { + Message roomCodeMsg = new RoomCodeRequest("1234"); + setupWithByteArray(roomCodeMsg.getBuffer()); + + assertTrue(parser.parse() == PacketType.ROOM_CODE_REQUEST); + assertTrue(parser.getRoomCode().equals("1234")); + } +}