X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/b09677a46c4ecf07f305892b51a927e4d7341793..f39983f78acf438049cd709c17ddb3e9ccefedef:/src/main/java/org/asamk/signal/commands/JsonRpcDispatcherCommand.java diff --git a/src/main/java/org/asamk/signal/commands/JsonRpcDispatcherCommand.java b/src/main/java/org/asamk/signal/commands/JsonRpcDispatcherCommand.java index 4ca90628..6e0c3173 100644 --- a/src/main/java/org/asamk/signal/commands/JsonRpcDispatcherCommand.java +++ b/src/main/java/org/asamk/signal/commands/JsonRpcDispatcherCommand.java @@ -31,9 +31,8 @@ import org.slf4j.LoggerFactory; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; public class JsonRpcDispatcherCommand implements LocalCommand { @@ -43,35 +42,49 @@ public class JsonRpcDispatcherCommand implements LocalCommand { private static final int IO_ERROR = -3; private static final int UNTRUSTED_KEY_ERROR = -4; - private final OutputWriter outputWriter; + @Override + public String getName() { + return "jsonRpc"; + } - public static void attachToSubparser(final Subparser subparser) { + @Override + public void attachToSubparser(final Subparser subparser) { subparser.help("Take commands from standard input as line-delimited JSON RPC while receiving messages."); subparser.addArgument("--ignore-attachments") .help("Don’t download attachments of received messages.") .action(Arguments.storeTrue()); } - public JsonRpcDispatcherCommand(final OutputWriter outputWriter) { - this.outputWriter = outputWriter; - } - @Override - public Set getSupportedOutputTypes() { - return Set.of(OutputType.JSON); + public List getSupportedOutputTypes() { + return List.of(OutputType.JSON); } @Override - public void handleCommand(final Namespace ns, final Manager m) throws CommandException { - final boolean ignoreAttachments = ns.getBoolean("ignore-attachments"); + public void handleCommand( + final Namespace ns, final Manager m, final OutputWriter outputWriter + ) throws CommandException { + final boolean ignoreAttachments = Boolean.TRUE.equals(ns.getBoolean("ignore-attachments")); + m.setIgnoreAttachments(ignoreAttachments); final var objectMapper = Util.createJsonObjectMapper(); final var jsonRpcSender = new JsonRpcSender((JsonWriter) outputWriter); - final var receiveThread = receiveMessages(s -> jsonRpcSender.sendRequest(JsonRpcRequest.forNotification( - "receive", - objectMapper.valueToTree(s), - null)), m, ignoreAttachments); + final var receiveMessageHandler = new JsonReceiveMessageHandler(m, + s -> jsonRpcSender.sendRequest(JsonRpcRequest.forNotification("receive", + objectMapper.valueToTree(s), + null))); + m.addReceiveHandler(receiveMessageHandler); + + // Maybe this should be handled inside the Manager + while (!m.hasCaughtUpWithOldMessages()) { + try { + synchronized (m) { + m.wait(); + } + } catch (InterruptedException ignored) { + } + } final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); @@ -85,11 +98,7 @@ public class JsonRpcDispatcherCommand implements LocalCommand { jsonRpcReader.readRequests((method, params) -> handleRequest(m, objectMapper, method, params), response -> logger.debug("Received unexpected response for id {}", response.getId())); - receiveThread.interrupt(); - try { - receiveThread.join(); - } catch (InterruptedException ignored) { - } + m.removeReceiveHandler(receiveMessageHandler); } private JsonNode handleRequest( @@ -104,7 +113,7 @@ public class JsonRpcDispatcherCommand implements LocalCommand { result[0] = s; }; - var command = Commands.getCommand(method, commandOutputWriter); + var command = Commands.getCommand(method); if (!(command instanceof JsonRpcCommand)) { throw new JsonRpcException(new JsonRpcResponse.Error(JsonRpcResponse.Error.METHOD_NOT_FOUND, "Method not implemented", @@ -112,7 +121,7 @@ public class JsonRpcDispatcherCommand implements LocalCommand { } try { - parseParamsAndRunCommand(m, objectMapper, params, (JsonRpcCommand) command); + parseParamsAndRunCommand(m, objectMapper, params, commandOutputWriter, (JsonRpcCommand) command); } catch (JsonMappingException e) { throw new JsonRpcException(new JsonRpcResponse.Error(JsonRpcResponse.Error.INVALID_REQUEST, e.getMessage(), @@ -135,7 +144,11 @@ public class JsonRpcDispatcherCommand implements LocalCommand { } private void parseParamsAndRunCommand( - final Manager m, final ObjectMapper objectMapper, final TreeNode params, final JsonRpcCommand command + final Manager m, + final ObjectMapper objectMapper, + final TreeNode params, + final OutputWriter outputWriter, + final JsonRpcCommand command ) throws CommandException, JsonMappingException { T requestParams = null; final var requestType = command.getRequestType(); @@ -148,28 +161,6 @@ public class JsonRpcDispatcherCommand implements LocalCommand { throw new AssertionError(e); } } - command.handleCommand(requestParams, m); - } - - private Thread receiveMessages( - JsonWriter jsonWriter, Manager m, boolean ignoreAttachments - ) { - final var thread = new Thread(() -> { - while (!Thread.interrupted()) { - try { - final var receiveMessageHandler = new JsonReceiveMessageHandler(m, jsonWriter); - m.receiveMessages(1, TimeUnit.HOURS, false, ignoreAttachments, receiveMessageHandler); - break; - } catch (IOException e) { - logger.warn("Receiving messages failed, retrying", e); - } catch (InterruptedException e) { - break; - } - } - }); - - thread.start(); - - return thread; + command.handleCommand(requestParams, m, outputWriter); } }