public final class SphereClientTuningDocumentation extends Object
The BlockingSphereClient
can wait for responses with BlockingSphereClient.executeBlocking(SphereRequest)
. This method enforces a timeout for resilience
and throws directly SphereException
s. For creation refer to BlockingSphereClient
.
import io.sphere.sdk.client.BlockingSphereClient;
import io.sphere.sdk.client.SphereRequest;
import io.sphere.sdk.projects.Project;
import io.sphere.sdk.projects.queries.ProjectGet;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
public class BlockingClientValueGetDemo { public static void demo(final BlockingSphereClient client, final String expectedProjectKey) { final SphereRequest<Project> sphereRequest = ProjectGet.of(); final Project project = client.executeBlocking(sphereRequest);//returns result directly, no CompletionStage assertThat(project.getKey()).isEqualTo(expectedProjectKey); } }
See the test code.
Here follow some examples how to NOT use the SphereClient
:
This examples lacks a timeout, so in an unfortunate case the thread is blocked forever:
import java.util.concurrent.CompletionStage;
public class WrongBlockingWithJoin { public static <T> T demo(final SphereClient client, final SphereRequest<T> sphereRequest) { //WRONG please don't do this final CompletionStage<T> completionStage = client.execute(sphereRequest); return completionStage.toCompletableFuture().join(); } }
See the test code.
The following examples are even worse because they lack a timeout and they need to deal with checked exceptions:
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
public class WrongBlockingWithGetAndSwallowing { public static <T> T demo(final SphereClient client, final SphereRequest<T> sphereRequest) { //WRONG!!! please don't do this !!!!! it swallows the exceptions try { final CompletionStage<T> completionStage = client.execute(sphereRequest); return completionStage.toCompletableFuture().get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } return null; } }
See the test code.
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
public class WrongBlockingWithGetAndSignature { //NOT a good idea public static <T> T demo(final SphereClient client, final SphereRequest<T> sphereRequest) throws ExecutionException, InterruptedException { //UNCOOL and contagious final CompletionStage<T> completionStage = client.execute(sphereRequest); return completionStage.toCompletableFuture().get(); } }
See the test code.
TimeoutSphereClientDecorator
.
RetrySphereClientDecorator
.
QueueSphereClientDecorator
.
The clients are interfaces which have a default implementation (add "Impl" to the interface name).
This enables you to use the decorator pattern to configure the cross concern behaviour of the client:
The following listing shows a pimped client which updates metrics on responses, retries commands and sets default values:
import io.sphere.sdk.commands.Command;
import io.sphere.sdk.queries.PagedQueryResult;
import io.sphere.sdk.queries.Query;
import java.util.concurrent.CompletionStage;
import java.util.function.Function;
public class WrappedClientDemo implements SphereClient { private final SphereClient client; private final MetricComponent metricComponent; public WrappedClientDemo(final SphereClient client, final MetricComponent metricComponent) { this.client = client; this.metricComponent = metricComponent; } @SuppressWarnings("unchecked") @Override public <T> CompletionStage<T> execute(SphereRequest<T> sphereRequest) { final CompletionStage<T> result; final CompletionStage<T> intermediateResult = filtered(client.execute(sphereRequest)); if (sphereRequest instanceof Query) { final Function<Throwable, T> provideEmptyResultOnException = exception -> (T) PagedQueryResult.empty(); result = intermediateResult.exceptionally(provideEmptyResultOnException); } else if (sphereRequest instanceof Command) { final Function<Throwable, T> retry = exception -> (T) client.execute(sphereRequest); result = intermediateResult.exceptionally(retry); } else { result = intermediateResult; } return result; } //this method will be called for every request private <T> CompletionStage<T> filtered(final CompletionStage<T> future) { future.whenComplete(Email::writeEmailToDevelopers); future.whenComplete(metricComponent::incrementFailureRequests); future.whenComplete(metricComponent::incrementSuccessfulRequests); return future; } @Override public void close() { client.close(); } @Override public SphereApiConfig getConfig() { return client.getConfig(); } }
See the test code.
HttpClient
is an abstraction to perform http requests.
io.sphere.sdk.http.AsyncHttpClientAdapter#of(AsyncHttpClient)
wraps an AsyncHttpClient
as HttpClient
.
The following example creates a configured HTTP client and initializes a SphereClient
with it.
import io.sphere.sdk.http.AsyncHttpClientAdapter;
import io.sphere.sdk.http.HttpClient;
import io.sphere.sdk.http.HttpRequest;
import io.sphere.sdk.http.HttpResponse;
import org.asynchttpclient.AsyncHttpClient;
import org.asynchttpclient.AsyncHttpClientConfig;
import org.asynchttpclient.DefaultAsyncHttpClient;
import org.asynchttpclient.DefaultAsyncHttpClientConfig;
import org.junit.Test;
import java.util.concurrent.CompletionStage;
import static io.sphere.sdk.http.HttpMethod.GET;
import static org.assertj.core.api.Assertions.assertThat;
public class CustomClientConfigDemoIntegrationTest { /** * Creates a {@link HttpClient} that can be used by the {@link SphereClient}. * @return new http client with custom settings */ public static HttpClient createCustomHttpClient() { final AsyncHttpClientConfig httpClientConfig = new DefaultAsyncHttpClientConfig.Builder() .setEnabledProtocols(new String[]{"TLSv1.2"})//required //examples for configuration .setMaxConnections(500) .setConnectTimeout(10000) // .setProxyServer(proxy) .build(); final AsyncHttpClient asyncHttpClient = new DefaultAsyncHttpClient(httpClientConfig); return AsyncHttpClientAdapter.of(asyncHttpClient); } /** * Shows the initialization of a {@link SphereClient} with a custom {@link HttpClient} provider. */ private void demoCreateClient() { final SphereClient sphereClient = SphereClientFactory.of(CustomClientConfigDemoIntegrationTest::createCustomHttpClient) .createClient("your projectKey", "your clientId", "your clientSecret"); } @Test public void customClient() { final HttpClient httpClient = createCustomHttpClient(); final CompletionStage<HttpResponse> completionStage = httpClient.execute(HttpRequest.of(GET, "https://commercetools.com")); final HttpResponse httpResponse = completionStage.toCompletableFuture().join(); assertThat(httpResponse.getStatusCode()).isLessThanOrEqualTo(302); httpClient.close(); } }
See the test code.
For configuration parameters refer to github.com/AsyncHttpClient/async-http-client.