public void stowRs()

in dicom_util/src/main/java/com/google/cloud/healthcare/DicomWebClientJetty.java [67:161]


  public void stowRs(InputStream in) throws DicomWebException {
    try {
      log.debug("STOW-RS to: " + stowPath);

      HTTP2Client client = new HTTP2Client();
      SslContextFactory sslContextFactory = new SslContextFactory.Client();
      client.addBean(sslContextFactory);
      client.start();

      HttpURI uri = new HttpURI(stowPath);

      FuturePromise<Session> sessionPromise = new FuturePromise<>();
      client.connect(sslContextFactory, new InetSocketAddress(uri.getHost(), CONNECT_PORT),
          new ServerSessionListener.Adapter(), sessionPromise);
      // Having a low timeout here causes flakyness when used with in transit compression.
      // This is likely due to the Stow thread sleeping and then waking up again between
      // the connect call and the session promise.get() call.
      // Reference: https://github.com/GoogleCloudPlatform/healthcare-dicom-dicomweb-adapter/issues/108
      Session session = sessionPromise.get(300, TimeUnit.SECONDS);

      // Prepare the request
      HttpFields requestFields = new HttpFields();
      if (credentials != null) {
        credentials.getRequestMetadata();
        requestFields.add(HttpHeader.AUTHORIZATION,
            "Bearer " + credentials.getAccessToken().getTokenValue());
      }
      requestFields.add(HttpHeader.CONTENT_TYPE,
          "application/dicom");
      requestFields.add(HttpHeader.ACCEPT,
          "application/dicom+json");
      MetaData.Request request = new MetaData.Request("POST", uri, HttpVersion.HTTP_2,
          requestFields);
      HeadersFrame headersFrame = new HeadersFrame(request, null, false);

      // Prepare the listener to receive the HTTP response frames.
      final StringBuilder resultBuilder = new StringBuilder();
      final CompletableFuture<Integer> responseCodeFuture = new CompletableFuture<>();
      final CompletableFuture<Boolean> doneFuture = new CompletableFuture<>();
      Stream.Listener responseListener = new Stream.Listener.Adapter() {
        @Override
        public void onReset(Stream stream, ResetFrame frame) {
          doneFuture.complete(false);
        }

        @Override
        public void onHeaders(Stream stream, HeadersFrame frame) {
          if (frame.getMetaData() instanceof Response) {
            responseCodeFuture.complete(((Response) frame.getMetaData()).getStatus());
          }
        }

        @Override
        public void onData(Stream stream, DataFrame frame, Callback callback) {
          byte[] bytes = new byte[frame.getData().remaining()];
          frame.getData().get(bytes);
          resultBuilder.append(new String(bytes, StandardCharsets.UTF_8));

          if (frame.isEndStream()) {
            doneFuture.complete(true);
          }

          callback.succeeded();
        }
      };

      FuturePromise<Stream> streamPromise = new FuturePromise<>();
      session.newStream(headersFrame, streamPromise, responseListener);
      Stream stream = streamPromise.get();

      DataStream dataStream = new DataStream(stream, in);
      try {
        dataStream.send();
      } catch (IOException e) {
        if (!doneFuture.isDone()) {
          throw e;
        }
      }

      doneFuture.get();
      client.stop();

      int httpStatus = responseCodeFuture.get();
      if (httpStatus != HttpStatus.OK_200) {
        String resp = resultBuilder.toString();
        throw new DicomWebException(
            "Http_" + httpStatus + ": " + resp, httpStatus, Status.ProcessingFailure);
      }
    } catch (Exception e) {
      if (e instanceof DicomWebException) {
        throw (DicomWebException) e;
      }
      throw new DicomWebException(e);
    }
  }