예제 #1
0
  private void loadHistory() {
    StringBuilder jsonArrayString = new StringBuilder();
    try (BufferedReader reader = new BufferedReader(new FileReader(DEFAULT_PERSISTENCE_FILE))) {
      while (reader.ready()) {
        jsonArrayString.append(reader.readLine());
      }
    } catch (IOException e) {
      logger.error("Could not parse message.", e);
    }

    JSONArray jsonArray = new JSONArray();

    if (jsonArrayString.length() == 0) {
      return;
    }

    try {
      jsonArray = (JSONArray) MessageHelper.getJsonParser().parse(jsonArrayString.toString());
    } catch (ParseException e) {
      logger.error("Could not parse message.", e);
    }

    for (int i = 0; i < jsonArray.size(); i++) {
      JSONObject jsonObject = (JSONObject) jsonArray.get(i);
      Message message = MessageHelper.jsonObjectToMessage(jsonObject);
      messages.add(message);
    }
  }
예제 #2
0
 // +++++++
 private Response doPost(HttpExchange httpExchange) {
   try {
     Message message = MessageHelper.getClientMessage(httpExchange.getRequestBody());
     logger.info(String.format("Received new message from user: %s", message));
     messageStorage.addMessage(message);
     return Response.ok();
   } catch (ParseException e) {
     logger.error("Could not parse message.", e);
     return new Response(Constants.RESPONSE_CODE_BAD_REQUEST, "Incorrect request body");
   } catch (MessageExistException e) {
     logger.error("Message with same id exist.", e);
     return new Response(Constants.RESPONSE_CODE_BAD_REQUEST, "Message with same id exist");
   }
 }
예제 #3
0
 public void connect() {
   URL url = null;
   try {
     url = new URL(Constants.PROTOCOL, host, port, Constants.CONTEXT_PATH);
     url.openConnection(); // try connect to server
     connected = true;
     startListening();
     startMessageSending();
   } catch (MalformedURLException e) {
     logger.error("Could not build URL to server", e);
     throw new RuntimeException(e);
   } catch (IOException e) {
     logger.error(String.format("Could not connect to server on %s", url.toString()), e);
   }
 }
예제 #4
0
  private void startListening() {
    // if listener thread is alive and listening now, no need to recreate. Just reuse it.
    if (listenerThread != null && listenerThread.isAlive()) {
      return;
    }

    Runnable listeningAction =
        () -> {
          boolean running = true;
          while (connected && running) {
            List<String> list = getMessages();

            localHistory.addAll(list);

            try {
              Thread.sleep(POLLING_PERIOD_MILLIS);
            } catch (InterruptedException e) {
              logger.error("The message listening thread was interrupted", e);
              running = false;
            }
          }
        };
    listenerThread = new Thread(listeningAction);
    listenerThread.start();
  }
예제 #5
0
 private void checkConnected() {
   if (!connected) {
     RuntimeException notConnectedError = new RuntimeException("No connection to server");
     logger.error("No connection to server", notConnectedError);
     throw notConnectedError;
   }
 }
예제 #6
0
 public void sendMessage(String message) {
   checkConnected();
   HttpURLConnection outcomeConnection = null;
   try {
     CLIENT_LOGGER.info("start sending message \"" + message + "\"");
     outcomeConnection = prepareOutputConnection();
     byte[] buffer = MessageHelper.buildSendMessageRequestBody(message).getBytes();
     OutputStream outputStream = outcomeConnection.getOutputStream();
     outputStream.write(buffer, 0, buffer.length);
     outputStream.close();
     outcomeConnection.getInputStream(); // to send data to server
     CLIENT_LOGGER.info("message sent");
   } catch (ConnectException e) {
     logger.error("Connection error. Disconnecting...", e);
     CLIENT_LOGGER.error("connection error", e);
     disconnect();
   } catch (IOException e) {
     CLIENT_LOGGER.error("IOException", e);
     logger.error("IOException occurred while sending message", e);
   } finally {
     if (outcomeConnection != null) {
       outcomeConnection.disconnect();
     }
     CLIENT_LOGGER.info("stop sending message \"" + message + "\"");
   }
 }
예제 #7
0
 private boolean rewriteHistory() {
   try (Writer writer =
       new OutputStreamWriter(new FileOutputStream(DEFAULT_PERSISTENCE_FILE), "UTF-8")) {
     JSONArray array = MessageHelper.getJsonArrayOfMessages(messages);
     writer.write(array.toString());
     return true;
   } catch (IOException e) {
     logger.error("Could not parse message.", e);
     return false;
   }
 }
예제 #8
0
 /**
  * Parses token and extract encoded amount of messages (typically - index)
  *
  * @param token the token to be parsed
  * @return decoded amount messages (index)
  */
 public static int parseToken(String token) {
   if (!token.matches(TOKEN_FORMAT)) {
     throw new InvalidTokenException("Incorrect format of token");
   }
   String encodedIndex = token.substring(2, token.length() - 2);
   try {
     int stateCode = Integer.valueOf(encodedIndex);
     return decodeIndex(stateCode);
   } catch (NumberFormatException e) {
     logger.error("Could not parse token", e);
     throw new InvalidTokenException("Invalid encoded value: " + encodedIndex);
   }
 }
예제 #9
0
 public static String inputStreamToString(InputStream in) {
   byte[] buffer = new byte[1024];
   int length = 0;
   try (ByteArrayOutputStream outStream = new ByteArrayOutputStream()) {
     while ((length = in.read(buffer)) != -1) {
       outStream.write(buffer, 0, length);
     }
     return outStream.toString();
   } catch (IOException e) {
     logger.error("An error occurred while reading input stream", e);
     throw new RuntimeException(e);
   }
 }
예제 #10
0
  // ++++++
  private Response doPut(HttpExchange httpExchange) {
    try {
      JSONObject jsonObject =
          stringToJsonObject(inputStreamToString(httpExchange.getRequestBody()));

      Message message = new Message();
      message.setId(((String) jsonObject.get(Constants.Message.FIELD_ID)));
      message.setText(((String) jsonObject.get(Constants.Message.FIELD_TEXT)));

      // System.out.println(((long)jsonObject.get(Constants.Message.FIELD_TIMESTAMP_MODIFIED)));
      message.setTimestampModified(
          ((long) jsonObject.get(Constants.Message.FIELD_TIMESTAMP_MODIFIED)));

      logger.info(String.format("Received updated message from user: %s", message));
      if (messageStorage.updateMessage(message)) {
        return Response.ok();
      }
      return Response.badRequest("This message does not exist");
    } catch (ParseException e) {
      logger.error("Could not parse message.", e);
      return new Response(Constants.RESPONSE_CODE_BAD_REQUEST, "Incorrect request body");
    }
  }
예제 #11
0
  @Override
  public void handle(HttpExchange httpExchange) throws IOException {
    Response response;

    try {
      response = dispatch(httpExchange);
    } catch (Throwable e) {
      // WARNING! It's not a good practice to catch all exceptions via Throwable
      // or Exception classes. But if you want to handle and you know
      // how to handle them correctly, you may use such approach.
      // Useful when you use thread pool and don't want to corrupt a thread
      logger.error("An error occurred when dispatching request.", e);
      response =
          new Response(
              Constants.RESPONSE_CODE_INTERNAL_SERVER_ERROR, "Error while dispatching message");
    }
    sendResponse(httpExchange, response);
  }
예제 #12
0
  private void sendResponse(HttpExchange httpExchange, Response response) {
    try (OutputStream os = httpExchange.getResponseBody()) {
      byte[] bytes = response.getBody().getBytes();

      Headers headers = httpExchange.getResponseHeaders();
      headers.add(Constants.REQUEST_HEADER_ACCESS_CONTROL_ORIGIN, "*");
      httpExchange.sendResponseHeaders(response.getStatusCode(), bytes.length);

      os.write(bytes);
      // there is no need to close stream manually
      // as try-catch with auto-closable is used
      /**
       * {@see http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html}
       */
    } catch (IOException e) {
      logger.error("Could not send response", e);
    }
  }
예제 #13
0
  public List<String> getMessages() {
    CLIENT_LOGGER.info("start receiving messages");
    checkConnected();
    List<String> list = new ArrayList<>();
    HttpURLConnection incomeConnection = null;
    try {
      CLIENT_LOGGER.info("send request for receive messages");
      String query =
          String.format(
              "%s?%s=%s",
              Constants.CONTEXT_PATH,
              Constants.REQUEST_PARAM_TOKEN,
              MessageHelper.buildToken(localHistory.size()));
      URL url = new URL(Constants.PROTOCOL, host, port, query);
      incomeConnection = prepareInputConnection(url);
      CLIENT_LOGGER.info("response is received");
      String response = MessageHelper.inputStreamToString(incomeConnection.getInputStream());
      JSONObject jsonObject = MessageHelper.stringToJsonObject(response);
      JSONArray jsonArray = (JSONArray) jsonObject.get("messages");
      CLIENT_LOGGER.info("received " + jsonArray.size() + " messages");
      for (Object o : jsonArray) {
        logger.info(String.format("Message from server: %s", o));
        CLIENT_LOGGER.info("message from server: " + o);
        list.add(o.toString());
      }

      /** Here is an example how for cycle can be replaced with Java 8 Stream API */
      // jsonArray.forEach(System.out::println);
      // list = (List<String>)
      // jsonArray.stream().map(Object::toString).collect(Collectors.toList());

    } catch (ParseException e) {
      logger.error("Could not parse message", e);
      CLIENT_LOGGER.error("could not parse message", e);
    } catch (ConnectException e) {
      logger.error("Connection error. Disconnecting...", e);
      CLIENT_LOGGER.error("connection error", e);
      disconnect();
    } catch (IOException e) {
      logger.error("IOException occured while reading input message", e);
      CLIENT_LOGGER.error("IOException occured while reading input message", e);
    } finally {
      if (incomeConnection != null) {
        incomeConnection.disconnect();
      }
    }
    CLIENT_LOGGER.info("stop receiving messages");
    return list;
  }