From 0c23268ed36e54d1080fac60d8957d23456ce8de Mon Sep 17 00:00:00 2001 From: Louis Vallat Date: Mon, 16 Nov 2020 22:39:58 +0100 Subject: [PATCH] [WIP] Communication should be working fine now. Signed-off-by: Louis Vallat --- .../java/xyz/vallat/louis/MoviesQuoteBot.java | 6 ++ .../xyz/vallat/louis/codes/ExitCodes.java | 5 +- .../louis/env/EnvironmentVariables.java | 1 + .../java/xyz/vallat/louis/sockets/Client.java | 4 -- .../vallat/louis/sockets/CommandsClient.java | 67 +++++++++++++++++++ .../{Server.java => CommandsServer.java} | 46 ++++++++----- .../vallat/louis/sockets/SocketsCommand.java | 3 + 7 files changed, 110 insertions(+), 22 deletions(-) delete mode 100644 src/main/java/xyz/vallat/louis/sockets/Client.java create mode 100644 src/main/java/xyz/vallat/louis/sockets/CommandsClient.java rename src/main/java/xyz/vallat/louis/sockets/{Server.java => CommandsServer.java} (55%) diff --git a/src/main/java/xyz/vallat/louis/MoviesQuoteBot.java b/src/main/java/xyz/vallat/louis/MoviesQuoteBot.java index 0ccc690..863f8d2 100644 --- a/src/main/java/xyz/vallat/louis/MoviesQuoteBot.java +++ b/src/main/java/xyz/vallat/louis/MoviesQuoteBot.java @@ -6,6 +6,8 @@ import org.slf4j.LoggerFactory; import xyz.vallat.louis.codes.ExitCodes; import xyz.vallat.louis.database.DBManager; import xyz.vallat.louis.discord.DiscordManager; +import xyz.vallat.louis.sockets.CommandsClient; +import xyz.vallat.louis.sockets.CommandsServer; import xyz.vallat.louis.subtitles.OpenSubtitles; import java.io.File; @@ -42,6 +44,7 @@ public class MoviesQuoteBot { DBManager.initDatabase(); OpenSubtitles.login(); DiscordManager.login(); + CommandsServer.start(); Runtime.getRuntime().addShutdownHook(new Thread(() -> { logger.info("Received shut down signal. Bye!"); @@ -87,5 +90,8 @@ public class MoviesQuoteBot { } private static void reimportAllSubtitleLines() { + CommandsClient.checkVersions(); + CommandsClient.setMaintenanceMode(true); + CommandsClient.setMaintenanceMode(false); } } diff --git a/src/main/java/xyz/vallat/louis/codes/ExitCodes.java b/src/main/java/xyz/vallat/louis/codes/ExitCodes.java index 6b364af..f59f40f 100644 --- a/src/main/java/xyz/vallat/louis/codes/ExitCodes.java +++ b/src/main/java/xyz/vallat/louis/codes/ExitCodes.java @@ -6,7 +6,10 @@ public enum ExitCodes { CANNOT_INITIALIZE_LANGUAGES(3), CANNOT_GET_PROPERTY(4), CANNOT_START_SOCKET_SERVER(5), - URGENT_EXIT_REQUIRED(6); + SOCKET_SERVER_MISBEHAVED(6), + SOCKET_SERVER_AND_CLIENT_VERSION_MISMATCH(7), + SOCKET_SERVER_COMMUNICATION_FAILURE(8), + URGENT_EXIT_REQUIRED(9); private final int value; diff --git a/src/main/java/xyz/vallat/louis/env/EnvironmentVariables.java b/src/main/java/xyz/vallat/louis/env/EnvironmentVariables.java index 0307aff..4a17881 100644 --- a/src/main/java/xyz/vallat/louis/env/EnvironmentVariables.java +++ b/src/main/java/xyz/vallat/louis/env/EnvironmentVariables.java @@ -11,6 +11,7 @@ public enum EnvironmentVariables { OS_PASSWORD("OPEN_SUBTITLES_PASSWORD"), OS_USER_AGENT("OPEN_SUBTITLES_USER_AGENT"), SOCKET_PORT("SOCKET_PORT"), + SOCKET_HOST("SOCKET_HOST"), OMDB_API_KEY("OMDB_API_KEY"); private final String value; diff --git a/src/main/java/xyz/vallat/louis/sockets/Client.java b/src/main/java/xyz/vallat/louis/sockets/Client.java deleted file mode 100644 index ce6da78..0000000 --- a/src/main/java/xyz/vallat/louis/sockets/Client.java +++ /dev/null @@ -1,4 +0,0 @@ -package xyz.vallat.louis.sockets; - -public class Client { -} diff --git a/src/main/java/xyz/vallat/louis/sockets/CommandsClient.java b/src/main/java/xyz/vallat/louis/sockets/CommandsClient.java new file mode 100644 index 0000000..7909d5b --- /dev/null +++ b/src/main/java/xyz/vallat/louis/sockets/CommandsClient.java @@ -0,0 +1,67 @@ +package xyz.vallat.louis.sockets; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import xyz.vallat.louis.MoviesQuoteBot; +import xyz.vallat.louis.codes.ExitCodes; +import xyz.vallat.louis.env.EnvironmentVariables; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.Socket; + +import static xyz.vallat.louis.sockets.CommandsServer.PORT; + +public class CommandsClient { + + private static final Logger logger = LoggerFactory.getLogger(CommandsClient.class.getCanonicalName()); + private static final String SOCKET_HOST = System.getenv(EnvironmentVariables.SOCKET_HOST.getValue()) == null ? + "localhost" : System.getenv(EnvironmentVariables.SOCKET_HOST.getValue()); + + private static String sendMessage(String message) { + logger.debug("Sending message '{}'.", message); + try (Socket clientSocket = new Socket(SOCKET_HOST, PORT)) { + PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); + BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + out.println(message); + String response = in.readLine(); + logger.debug("Received response '{}'.", response); + return response; + } catch (IOException e) { + logger.error("An error happened while trying to communicate with server.", e); + } + return null; + } + + public static void checkVersions() { + String message = sendMessage(SocketsCommand.VERSION_REQUEST.getName()); + if (message == null) cannotCommunicateWithServer(); + else if (!message.equals(MoviesQuoteBot.VERSION)) { + logger.error("Version mismatch between server and client! Got answer '{}'. Exiting.", message); + System.exit(ExitCodes.SOCKET_SERVER_AND_CLIENT_VERSION_MISMATCH.getValue()); + } + } + + public static void setMaintenanceMode(boolean mode) { + String message = sendMessage(mode ? + SocketsCommand.MAINTENANCE_MODE_ON.getName() : SocketsCommand.MAINTENANCE_MODE_OFF.getName()); + if (message == null) cannotCommunicateWithServer(); + else if (!message.equals(SocketsCommand.OK.getName())) { + if (!message.equals(SocketsCommand.UNRECOGNIZED_COMMAND.getName())) + logger.error("Unrecognized answer: '{}'.", message); + serverIsMisbehaving(); + } + } + + private static void serverIsMisbehaving() { + logger.error("The server is misbehaving. Exiting."); + System.exit(ExitCodes.SOCKET_SERVER_MISBEHAVED.getValue()); + } + + private static void cannotCommunicateWithServer() { + logger.error("Cannot communicate with server. Exiting."); + System.exit(ExitCodes.SOCKET_SERVER_COMMUNICATION_FAILURE.getValue()); + } +} diff --git a/src/main/java/xyz/vallat/louis/sockets/Server.java b/src/main/java/xyz/vallat/louis/sockets/CommandsServer.java similarity index 55% rename from src/main/java/xyz/vallat/louis/sockets/Server.java rename to src/main/java/xyz/vallat/louis/sockets/CommandsServer.java index 81af821..a4d2bdc 100644 --- a/src/main/java/xyz/vallat/louis/sockets/Server.java +++ b/src/main/java/xyz/vallat/louis/sockets/CommandsServer.java @@ -6,19 +6,16 @@ import xyz.vallat.louis.MoviesQuoteBot; import xyz.vallat.louis.codes.ExitCodes; import xyz.vallat.louis.env.EnvironmentVariables; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; +import java.io.*; import java.net.ServerSocket; import java.net.Socket; import static xyz.vallat.louis.MoviesQuoteBot.KILL_SWITCH_FILE; -public class Server { +public class CommandsServer { - private static final Logger logger = LoggerFactory.getLogger(Server.class.getCanonicalName()); - private static final int PORT; + public static final int PORT; + private static final Logger logger = LoggerFactory.getLogger(CommandsServer.class.getCanonicalName()); static { int port = 8888; @@ -30,7 +27,7 @@ public class Server { PORT = port; } - private Server() { + private CommandsServer() { } public static void start() { @@ -41,15 +38,10 @@ public class Server { logger.info("Waiting for connections on port '{}'...", PORT); Socket socket = serverSocket.accept(); logger.info("Connected!"); - BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); - String message = reader.readLine(); - logger.debug("Received message '{}'.", message); - if (message.equals(SocketsCommand.KILL_SWITCH_URGENT.getName())) everythingIsOkay = false; - else if (message.equals(SocketsCommand.MAINTENANCE_MODE_ON.getName())) - MoviesQuoteBot.switchToMaintenanceMode(); - else if (message.equals(SocketsCommand.MAINTENANCE_MODE_OFF.getName())) - MoviesQuoteBot.switchToNormalOperations(); - else logger.warn("Be careful, I received a message that I don't understand: '{}'.", message); + BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + PrintWriter out = new PrintWriter(socket.getOutputStream(), true); + String message = in.readLine(); + everythingIsOkay = computeMessage(out, message); } catch (IOException e) { everythingIsOkay = false; logger.error("Cannot start socket server.", e); @@ -68,4 +60,24 @@ public class Server { }); } + private static boolean computeMessage(PrintWriter out, String message) { + boolean everythingIsOkay = true; + logger.debug("Received message '{}'.", message); + if (message.equals(SocketsCommand.KILL_SWITCH_URGENT.getName())) { + everythingIsOkay = false; + out.println(SocketsCommand.OK.getName()); + } else if (message.equals(SocketsCommand.MAINTENANCE_MODE_ON.getName())) { + MoviesQuoteBot.switchToMaintenanceMode(); + out.println(SocketsCommand.OK.getName()); + } else if (message.equals(SocketsCommand.MAINTENANCE_MODE_OFF.getName())) { + MoviesQuoteBot.switchToNormalOperations(); + out.println(SocketsCommand.OK.getName()); + } else if (message.equals(SocketsCommand.VERSION_REQUEST.getName())) out.println(MoviesQuoteBot.VERSION); + else { + logger.warn("Be careful, I received a message that I don't understand: '{}'.", message); + out.println(SocketsCommand.UNRECOGNIZED_COMMAND.getName()); + } + return everythingIsOkay; + } + } diff --git a/src/main/java/xyz/vallat/louis/sockets/SocketsCommand.java b/src/main/java/xyz/vallat/louis/sockets/SocketsCommand.java index d10e382..d4f99d4 100644 --- a/src/main/java/xyz/vallat/louis/sockets/SocketsCommand.java +++ b/src/main/java/xyz/vallat/louis/sockets/SocketsCommand.java @@ -3,6 +3,9 @@ package xyz.vallat.louis.sockets; public enum SocketsCommand { MAINTENANCE_MODE_ON("maintenance_engaged"), MAINTENANCE_MODE_OFF("maintenance_disengaged"), + VERSION_REQUEST("papers_please"), + OK("okay"), + UNRECOGNIZED_COMMAND("i_dont_think_so"), KILL_SWITCH_URGENT("big_red_button_pressed"); private final String name;