public static SphereClient of(final SphereApiConfig config, final HttpClient httpClient, final SphereAccessTokenSupplier tokenSupplier) { return new SphereClientImpl(config, tokenSupplier, httpClient); } }
@Override protected void internalClose() { closeQuietly(tokenSupplier); closeQuietly(httpClient); }
@Override public <T> CompletableFuture<T> execute(final SphereRequest<T> sphereRequest) { final CompletableFuture<String> tokenFuture = tokenSupplier.get(); return tokenFuture.thenCompose(token -> execute(sphereRequest, token)); }
@Override public <T> CompletionStage<T> execute(final SphereRequest<T> sphereRequest) { final HttpRequestIntent httpRequest = sphereRequest.httpRequestIntent(); final HttpResponse httpResponse = function.apply(httpRequest); try { final T t = SphereClientImpl.parse(sphereRequest, objectMapper, sphereApiConfig, httpResponse, null); return CompletableFutureUtils.successful(t); } catch (final Exception e) { return CompletableFutureUtils.failed(e); } }
private <T> CompletableFuture<T> executeWithRecover(final SphereRequest<T> sphereRequest, final HttpRequest httpRequest, final int ttl) { final CompletionStage<T> intermediateResult = httpClient.execute(httpRequest).thenApplyAsync(httpResponse -> { try { return processHttpResponse(sphereRequest, objectMapper, config, httpResponse, httpRequest); } catch (final SphereException e) { fillExceptionWithData(sphereRequest, httpResponse, e, config, httpRequest); throw e; } }); final CompletableFuture<T> result = new CompletableFuture<T>(); intermediateResult.whenCompleteAsync((value, throwable) -> { if (throwable != null) { if (throwable.getCause() instanceof InvalidTokenException && ttl > 0 && tokenSupplier instanceof RefreshableSphereAccessTokenSupplier) { final RefreshableSphereAccessTokenSupplier supplier = (RefreshableSphereAccessTokenSupplier) tokenSupplier; final CompletionStage<T> nextAttemptCompletionStage = supplier.getNewToken().thenComposeAsync(token -> execute(sphereRequest, token, ttl - 1)); CompletableFutureUtils.transferResult(nextAttemptCompletionStage, result); } else { result.completeExceptionally(throwable); } } else { result.complete(value); } }); return result; }
private <T> CompletionStage<T> execute(final SphereRequest<T> sphereRequest, final String token) { final HttpRequest httpRequest = createHttpRequest(sphereRequest, token); final SphereInternalLogger logger = getLogger(httpRequest); logger.debug(() -> sphereRequest); logger.trace(() -> { final String output; if (httpRequest.getBody() != null && httpRequest.getBody() instanceof StringHttpRequestBody) { final StringHttpRequestBody body = (StringHttpRequestBody) httpRequest.getBody(); final String unformattedJson = body.getSecuredBody(); output = "send: " + unformattedJson + "\nformatted: " + SphereJsonUtils.prettyPrint(unformattedJson); } else { output = "no request body present"; } return output; }); return httpClient.execute(httpRequest).thenApply(httpResponse -> { try { return processHttpResponse(sphereRequest, objectMapper, config, httpResponse); } catch (final SphereException e) { fillExceptionWithData(sphereRequest, httpResponse, e, config); throw e; } }); }
/** * Raw client creation. * See also SphereClientFactory. * * @param config SPHERE.IO project and location * @param httpClient client to execute requests * @param tokenSupplier delivery of access tokens * @return sphere client */ static SphereClient of(final SphereApiConfig config, final HttpClient httpClient, final SphereAccessTokenSupplier tokenSupplier) { return SphereClientImpl.of(config, httpClient, tokenSupplier); } }
private static <T> SphereException createExceptionFor(final HttpResponse httpResponse, final SphereRequest<T> sphereRequest, final ObjectMapper objectMapper, final SphereApiConfig config) { final SphereException sphereException = ExceptionFactory.of().createException(httpResponse, sphereRequest, objectMapper); fillExceptionWithData(sphereRequest, httpResponse, sphereException, config); return sphereException; }
static <T> T parse(final HttpResponse httpResponse, final SphereRequest<T> sphereRequest, final ObjectMapper objectMapper, final SphereApiConfig config) { final T result; if (!sphereRequest.canHandleResponse(httpResponse)) { final SphereException sphereException = createExceptionFor(httpResponse, sphereRequest, objectMapper, config); throw sphereException; } else { try { result = sphereRequest.resultMapper().apply(httpResponse); } catch (final JsonException e) { final byte[] bytes = httpResponse.getResponseBody().get(); throw new JsonException("Cannot parse " + bytesToString(bytes), e); } } return result; }
@Override public <T> CompletionStage<T> execute(final SphereRequest<T> sphereRequest) { rejectExcutionIfClosed("Client is already closed."); try { final int ttl = 1; return tokenSupplier.get().thenComposeAsync(token -> execute(sphereRequest, token, ttl)); } catch (final Throwable throwable) { return CompletableFutureUtils.failed(throwable); } }
private <T> CompletionStage<T> execute(final SphereRequest<T> sphereRequest, final String token, final int ttl) { final HttpRequest httpRequest = createHttpRequest(sphereRequest, token); final SphereInternalLogger logger = getLogger(httpRequest); logger.debug(() -> sphereRequest); logger.trace(() -> { final String output; final String httpMethodAndUrl = httpRequest.getHttpMethod() + " " + httpRequest.getUrl(); if (httpRequest.getBody() != null && httpRequest.getBody() instanceof StringHttpRequestBody) { final StringHttpRequestBody body = (StringHttpRequestBody) httpRequest.getBody(); final String unformattedBody = body.getSecuredBody(); final boolean isJsonRequest = httpRequest.getHeaders().findFlatHeader(HttpHeaders.CONTENT_TYPE).map(ct -> ct.toLowerCase().contains("json")).orElse(true); if (isJsonRequest) { String prettyPrint; try { prettyPrint = SphereJsonUtils.prettyPrint(unformattedBody); } catch (final JsonException e) { classLogger.warn("pretty print failed", e); prettyPrint = unformattedBody; } output = "send: " + httpMethodAndUrl + "\nformatted: " + prettyPrint; } else { output = "send: " + httpRequest.getHttpMethod() + " " + httpRequest.getUrl() + " " + unformattedBody; } } else { output = httpMethodAndUrl + " <no body>"; } return output; }); return executeWithRecover(sphereRequest, httpRequest, ttl); }
private <T> CompletableFuture<T> execute(final SphereRequest<T> sphereRequest, final String token) { final HttpRequest httpRequest = createHttpRequest(sphereRequest, token); final SphereInternalLogger logger = getLogger(httpRequest); logger.debug(() -> sphereRequest); logger.trace(() -> { final String output; if (httpRequest.getBody().isPresent() && httpRequest.getBody().get() instanceof StringHttpRequestBody) { final StringHttpRequestBody body = (StringHttpRequestBody) httpRequest.getBody().get(); final String unformattedJson = body.getString(); output = "send: " + unformattedJson + "\nformatted: " + JsonUtils.prettyPrintJsonStringSecure(unformattedJson); } else { output = "no request body present"; } return output; }); return httpClient. execute(httpRequest). thenApply(preProcess(sphereRequest, objectMapper, config)); }
@Override public <T> CompletionStage<T> execute(final SphereRequest<T> sphereRequest) { final HttpRequestIntent httpRequest = sphereRequest.httpRequestIntent(); final HttpResponse httpResponse = function.apply(httpRequest); try { final T t = SphereClientImpl.parse(sphereRequest, objectMapper, sphereApiConfig, httpResponse, null); return CompletableFutureUtils.successful(t); } catch (final Exception e) { return CompletableFutureUtils.failed(e); } }
private <T> CompletableFuture<T> executeWithRecover(final SphereRequest<T> sphereRequest, final HttpRequest httpRequest, final int ttl) { final CompletionStage<T> intermediateResult = httpClient.execute(httpRequest).thenApplyAsync(httpResponse -> { try { return processHttpResponse(sphereRequest, objectMapper, config, httpResponse, httpRequest); } catch (final SphereException e) { fillExceptionWithData(sphereRequest, httpResponse, e, config, httpRequest); throw e; } }); final CompletableFuture<T> result = new CompletableFuture<T>(); intermediateResult.whenCompleteAsync((value, throwable) -> { if (throwable != null) { if (throwable.getCause() instanceof InvalidTokenException && ttl > 0 && tokenSupplier instanceof RefreshableSphereAccessTokenSupplier) { final RefreshableSphereAccessTokenSupplier supplier = (RefreshableSphereAccessTokenSupplier) tokenSupplier; final CompletionStage<T> nextAttemptCompletionStage = supplier.getNewToken().thenComposeAsync(token -> execute(sphereRequest, token, ttl - 1)); CompletableFutureUtils.transferResult(nextAttemptCompletionStage, result); } else { result.completeExceptionally(throwable); } } else { result.complete(value); } }); return result; }
/** * Raw client creation. * See also SphereClientFactory. * * @param config SPHERE.IO project and location * @param httpClient client to execute requests * @param tokenSupplier delivery of access tokens * @return sphere client */ public static SphereClient of(final SphereApiConfig config, final HttpClient httpClient, final SphereAccessTokenSupplier tokenSupplier) { return SphereClientImpl.of(config, httpClient, tokenSupplier); } }
private static <T> SphereException createExceptionFor(final HttpResponse httpResponse, final SphereRequest<T> sphereRequest, final ObjectMapper objectMapper, final SphereApiConfig config) { final SphereException sphereException = ExceptionFactory.of().createException(httpResponse, sphereRequest, objectMapper); fillExceptionWithData(sphereRequest, httpResponse, sphereException, config); return sphereException; }
static <T> T parse(final SphereRequest<T> sphereRequest, final ObjectMapper objectMapper, final SphereApiConfig config, final HttpResponse httpResponse, final HttpRequest httpRequest) { final T result; if (!sphereRequest.canDeserialize(httpResponse)) { final SphereException sphereException = createExceptionFor(httpResponse, sphereRequest, objectMapper, config, httpRequest); throw sphereException; } else { try { result = sphereRequest.deserialize(httpResponse); } catch (final JsonException e) { final byte[] bytes = httpResponse.getResponseBody(); e.addNote("Cannot parse " + bytesToString(bytes)); throw e; } } return result; }
@Override public <T> CompletionStage<T> execute(final SphereRequest<T> sphereRequest) { rejectExcutionIfClosed("Client is already closed."); try { final int ttl = 1; return tokenSupplier.get().thenComposeAsync(token -> execute(sphereRequest, token, ttl)); } catch (final Throwable throwable) { return CompletableFutureUtils.failed(throwable); } }
private <T> CompletionStage<T> execute(final SphereRequest<T> sphereRequest, final String token, final int ttl) { final HttpRequest httpRequest = createHttpRequest(sphereRequest, token); final SphereInternalLogger logger = getLogger(httpRequest); logger.debug(() -> sphereRequest); logger.trace(() -> { final String output; final String httpMethodAndUrl = httpRequest.getHttpMethod() + " " + httpRequest.getUrl(); if (httpRequest.getBody() != null && httpRequest.getBody() instanceof StringHttpRequestBody) { final StringHttpRequestBody body = (StringHttpRequestBody) httpRequest.getBody(); final String unformattedBody = body.getSecuredBody(); final boolean isJsonRequest = httpRequest.getHeaders().findFlatHeader(HttpHeaders.CONTENT_TYPE).map(ct -> ct.toLowerCase().contains("json")).orElse(true); if (isJsonRequest) { String prettyPrint; try { prettyPrint = SphereJsonUtils.prettyPrint(unformattedBody); } catch (final JsonException e) { classLogger.warn("pretty print failed", e); prettyPrint = unformattedBody; } output = "send: " + httpMethodAndUrl + "\nformatted: " + prettyPrint; } else { output = "send: " + httpRequest.getHttpMethod() + " " + httpRequest.getUrl() + " " + unformattedBody; } } else { output = httpMethodAndUrl + " <no body>"; } return output; }); return executeWithRecover(sphereRequest, httpRequest, ttl); }
private static <T> T processHttpResponse(final SphereRequest<T> sphereRequest, final ObjectMapper objectMapper, final SphereApiConfig config, final HttpResponse httpResponse) { final SphereInternalLogger logger = getLogger(httpResponse); logger.debug(() -> httpResponse); logger.trace(() -> httpResponse.getStatusCode() + "\n" + Optional.ofNullable(httpResponse.getResponseBody()).map(body -> SphereJsonUtils.prettyPrint(bytesToString(body))).orElse("No body present.") + "\n"); final List<String> notices = httpResponse.getHeaders().getHeadersAsMap().get(SphereHttpHeaders.X_DEPRECATION_NOTICE); if (notices != null) { notices.stream().forEach(message -> logger.warn(() -> "Deprecation notice : " + message)); } return parse(sphereRequest, objectMapper, config, httpResponse); }