@Override
  public void getArtifact(
      ArtifactApi.GetArtifactRequest request,
      StreamObserver<ArtifactApi.GetArtifactResponse> responseObserver) {
    try {
      InputStream inputStream = getArtifact(request.getArtifact());
      byte[] buffer = new byte[bufferSize];
      int bytesRead;
      while ((bytesRead = inputStream.read(buffer)) > 0) {
        responseObserver.onNext(
            ArtifactApi.GetArtifactResponse.newBuilder()
                .setData(ByteString.copyFrom(buffer, 0, bytesRead))
                .build());
      }
      responseObserver.onCompleted();
    } catch (IOException exn) {
      exn.printStackTrace();
      responseObserver.onError(exn);
    } catch (UnsupportedOperationException exn) {
      responseObserver.onError(
          new StatusException(Status.INVALID_ARGUMENT.withDescription(exn.getMessage())));
    }
  }
@SuppressWarnings("InlineMeInliner") // inline `Strings.repeat()` - Java 11+ API only
  @Test
  public void testRetrieveArtifacts() throws IOException, InterruptedException {
    Map<String, String> artifacts =
        ImmutableMap.of(
            "a.txt", "a", "b.txt", "bbb", "c.txt", Strings.repeat("cxy", TEST_BUFFER_SIZE * 3 / 4));
    stageFiles(artifacts);
    for (Map.Entry<String, String> artifact : artifacts.entrySet()) {
      assertEquals(
          artifact.getValue(),
          getArtifact(fileArtifact(Paths.get(stagingDir.toString(), artifact.getKey()))));
    }
  }