/**
  * Read content
  *
  * @return content
  */
 protected byte[] read() {
   ByteArrayOutputStream content = new ByteArrayOutputStream();
   final byte[] buffer = new byte[8196];
   int read;
   try {
     InputStream input = request.getInputStream();
     while ((read = input.read(buffer)) != -1) content.write(buffer, 0, read);
   } catch (IOException e) {
     throw new RuntimeException(e);
   }
   return content.toByteArray();
 }
  private void putMessage(final Request jettyRequest, final HttpServletResponse response)
      throws IOException {
    final String topic = jettyRequest.getParameter("topic");
    try {
      // Validation should be done on client side already
      final int partition = Integer.parseInt(jettyRequest.getParameter("partition"));
      final int flag = Integer.parseInt(jettyRequest.getParameter("flag"));
      int checkSum = -1;
      if (StringUtils.isNotBlank(jettyRequest.getParameter("checksum"))) {
        checkSum = Integer.parseInt(jettyRequest.getParameter("checksum"));
      }
      // This stream should be handle by Jetty server and therefore it is
      // out of scope here without care close
      final InputStream inputStream = jettyRequest.getInputStream();
      final int dataLength = Integer.parseInt(jettyRequest.getParameter("length"));
      final byte[] data = new byte[dataLength];

      inputStream.read(data);
      this.doResponseHeaders(response, "text/plain");
      final PutCommand putCommand = this.convert2PutCommand(topic, partition, data, flag, checkSum);
      this.commandProcessor.processPutCommand(
          putCommand,
          null,
          new PutCallback() {

            @Override
            public void putComplete(final ResponseCommand resp) {
              final BooleanCommand responseCommand = (BooleanCommand) resp;
              response.setStatus(responseCommand.getCode());
              try {
                response.getWriter().write(responseCommand.getErrorMsg());
              } catch (final IOException e) {
                logger.error("Write response failed", e);
              }
            }
          });

    } catch (final Exception e) {
      logger.error("Put message failed", e);
      response.setStatus(HttpStatus.InternalServerError);
      response.getWriter().write(e.getMessage());
    }
  }
  private int handlePut(Request baseRequest, HttpServletResponse response) throws IOException {
    if (!artifactCache.isPresent()) {
      response.getWriter().write("Serving local cache is disabled for this instance.");
      return HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
    }

    Path temp = null;
    try {
      projectFilesystem.mkdirs(projectFilesystem.getBuckPaths().getScratchDir());
      temp =
          projectFilesystem.createTempFile(
              projectFilesystem.getBuckPaths().getScratchDir(), "incoming_upload", ".tmp");

      StoreResponseReadResult storeRequest;
      try (DataInputStream requestInputData = new DataInputStream(baseRequest.getInputStream());
          OutputStream tempFileOutputStream = projectFilesystem.newFileOutputStream(temp)) {
        storeRequest =
            HttpArtifactCacheBinaryProtocol.readStoreRequest(
                requestInputData, tempFileOutputStream);
      }

      if (!storeRequest.getActualHashCode().equals(storeRequest.getExpectedHashCode())) {
        response.getWriter().write("Checksum mismatch.");
        return HttpServletResponse.SC_NOT_ACCEPTABLE;
      }

      artifactCache
          .get()
          .store(
              ArtifactInfo.builder()
                  .setRuleKeys(storeRequest.getRuleKeys())
                  .setMetadata(storeRequest.getMetadata())
                  .build(),
              BorrowablePath.notBorrowablePath(temp));
      return HttpServletResponse.SC_ACCEPTED;
    } finally {
      if (temp != null) {
        projectFilesystem.deleteFileAtPathIfExists(temp);
      }
    }
  }
    /**
     * The handler for the HTTP requesst
     *
     * @param target target
     * @param baseRequest request
     * @param httpRequest request
     * @param httpResponse response
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void handle(
        String target,
        Request baseRequest,
        HttpServletRequest httpRequest,
        HttpServletResponse httpResponse)
        throws IOException, ServletException {

      Onem2mRequestPrimitiveClientBuilder clientBuilder = new Onem2mRequestPrimitiveClientBuilder();
      String headerValue;

      clientBuilder.setProtocol(Onem2m.Protocol.HTTP);

      Onem2mStats.getInstance().endpointInc(baseRequest.getRemoteAddr());
      Onem2mStats.getInstance().inc(Onem2mStats.HTTP_REQUESTS);

      String contentType = httpRequest.getContentType();
      if (contentType == null) contentType = "json";
      contentType = contentType.toLowerCase();
      if (contentType.contains("json")) {
        clientBuilder.setContentFormat(Onem2m.ContentFormat.JSON);
      } else if (contentType.contains("xml")) {
        clientBuilder.setContentFormat(Onem2m.ContentFormat.XML);
      } else {
        httpResponse.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE);
        httpResponse.getWriter().println("Unsupported media type: " + contentType);
        httpResponse.setContentType("text/json;charset=utf-8");
        baseRequest.setHandled(true);
        Onem2mStats.getInstance().inc(Onem2mStats.HTTP_REQUESTS_ERROR);
        return;
      }

      clientBuilder.setTo(httpRequest.getRequestURI());

      // pull fields out of the headers
      headerValue = httpRequest.getHeader(Onem2m.HttpHeaders.X_M2M_ORIGIN);
      if (headerValue != null) {
        clientBuilder.setFrom(headerValue);
      }
      headerValue = httpRequest.getHeader(Onem2m.HttpHeaders.X_M2M_RI);
      if (headerValue != null) {
        clientBuilder.setRequestIdentifier(headerValue);
      }
      headerValue = httpRequest.getHeader(Onem2m.HttpHeaders.X_M2M_NM);
      if (headerValue != null) {
        clientBuilder.setName(headerValue);
      }
      headerValue = httpRequest.getHeader(Onem2m.HttpHeaders.X_M2M_GID);
      if (headerValue != null) {
        clientBuilder.setGroupRequestIdentifier(headerValue);
      }
      headerValue = httpRequest.getHeader(Onem2m.HttpHeaders.X_M2M_RTU);
      if (headerValue != null) {
        clientBuilder.setResponseType(headerValue);
      }
      headerValue = httpRequest.getHeader(Onem2m.HttpHeaders.X_M2M_OT);
      if (headerValue != null) {
        clientBuilder.setOriginatingTimestamp(headerValue);
      }

      // the contentType string can have ty=val attached to it so we should handle this case
      Boolean resourceTypePresent = false;
      String contentTypeResourceString = parseContentTypeForResourceType(contentType);
      if (contentTypeResourceString != null) {
        resourceTypePresent =
            clientBuilder.parseQueryStringIntoPrimitives(contentTypeResourceString);
      }
      String method = httpRequest.getMethod().toLowerCase();
      // look in query string if didnt find it in contentType header
      if (!resourceTypePresent) {
        resourceTypePresent =
            clientBuilder.parseQueryStringIntoPrimitives(httpRequest.getQueryString());
      } else {
        clientBuilder.parseQueryStringIntoPrimitives(httpRequest.getQueryString());
      }
      if (resourceTypePresent && !method.contentEquals("post")) {
        httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        httpResponse.getWriter().println("Specifying resource type not permitted.");
        Onem2mStats.getInstance().inc(Onem2mStats.HTTP_REQUESTS_ERROR);
        return;
      }

      // take the entire payload text and put it in the CONTENT field; it is the representation of
      // the resource
      String cn = IOUtils.toString(baseRequest.getInputStream()).trim();
      if (cn != null && !cn.contentEquals("")) {
        clientBuilder.setPrimitiveContent(cn);
      }

      switch (method) {
        case "get":
          clientBuilder.setOperationRetrieve();
          Onem2mStats.getInstance().inc(Onem2mStats.HTTP_REQUESTS_RETRIEVE);
          break;
        case "post":
          if (resourceTypePresent) {
            clientBuilder.setOperationCreate();
            Onem2mStats.getInstance().inc(Onem2mStats.HTTP_REQUESTS_CREATE);
          } else {
            clientBuilder.setOperationNotify();
            Onem2mStats.getInstance().inc(Onem2mStats.HTTP_REQUESTS_NOTIFY);
          }
          break;
        case "put":
          clientBuilder.setOperationUpdate();
          Onem2mStats.getInstance().inc(Onem2mStats.HTTP_REQUESTS_UPDATE);
          break;
        case "delete":
          clientBuilder.setOperationDelete();
          Onem2mStats.getInstance().inc(Onem2mStats.HTTP_REQUESTS_DELETE);
          break;
        default:
          httpResponse.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
          httpResponse.getWriter().println("Unsupported method type: " + method);
          httpResponse.setContentType("text/json;charset=utf-8");
          baseRequest.setHandled(true);
          Onem2mStats.getInstance().inc(Onem2mStats.HTTP_REQUESTS_ERROR);
          return;
      }

      // invoke the service request
      Onem2mRequestPrimitiveClient onem2mRequest = clientBuilder.build();
      ResponsePrimitive onem2mResponse = Onem2m.serviceOnenm2mRequest(onem2mRequest, onem2mService);

      // now place the fields from the onem2m result response back in the http fields, and send
      sendHttpResponseFromOnem2mResponse(httpResponse, onem2mResponse);

      httpResponse.addHeader("Access-Control-Allow-Origin", "*");
      httpResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS");

      baseRequest.setHandled(true);
    }