Skip to content

Commit 8ede978

Browse files
committed
update docs
1 parent 3da4c3b commit 8ede978

File tree

6 files changed

+195
-23
lines changed

6 files changed

+195
-23
lines changed

commercetools/commercetools-sdk-java-api/src/integrationTest/java/commercetools/utils/CommercetoolsTestUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ public class CommercetoolsTestUtils {
2121
static {
2222
ApiRootBuilder builder = ApiRootBuilder.ofEnvironmentVariables()
2323
.addConcurrentModificationMiddleware()
24-
.withPolicies(
25-
policyBuilder -> policyBuilder.withRetry(b -> b.maxRetries(5).statusCodes(singletonList(503))))
24+
.withRequestPolicies(policyBuilder -> policyBuilder.withAllOtherRequests(
25+
request -> request.withRetry(b -> b.maxRetries(5).statusCodes(singletonList(503)))))
2626
.withErrorMiddleware(ErrorMiddleware.ExceptionMode.UNWRAP_COMPLETION_EXCEPTION);
2727
projectApiRoot = builder.buildProjectRoot();
2828
}

commercetools/internal-docs/src/test/java/example/ExamplesTest.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@
5252
import org.junit.jupiter.api.Test;
5353
import org.slf4j.event.Level;
5454

55-
import dev.failsafe.Failsafe;
56-
import dev.failsafe.FailsafeExecutor;
5755
import reactor.netty.http.HttpProtocol;
5856

5957
public class ExamplesTest {
@@ -121,18 +119,14 @@ public void customUrls() {
121119
}
122120

123121
public void timeoutMiddleware() {
124-
dev.failsafe.Timeout<ApiHttpResponse<byte[]>> timeout = dev.failsafe.Timeout
125-
.<ApiHttpResponse<byte[]>> builder(Duration.ofSeconds(10))
126-
.build();
127-
FailsafeExecutor<ApiHttpResponse<byte[]>> failsafeExecutor = Failsafe.with(timeout);
128-
129122
ProjectApiRoot apiRoot = ApiRootBuilder.of()
130123
.defaultClient(ClientCredentials.of()
131124
.withClientId("your-client-id")
132125
.withClientSecret("your-client-secret")
133126
.build(),
134127
ServiceRegion.GCP_EUROPE_WEST1)
135-
.addMiddleware((request, next) -> failsafeExecutor.getStageAsync(() -> next.apply(request)))
128+
.withRequestPolicies(
129+
policies -> policies.withAllOtherRequests(request -> request.withTimeout(Duration.ofSeconds(10))))
136130
.build("my-project");
137131
}
138132

@@ -401,8 +395,12 @@ public void retry() {
401395
ProjectApiRoot apiRoot = ApiRootBuilder.of()
402396
.defaultClient(ClientCredentials.of().withClientId("clientId").withClientSecret("clientSecret").build(),
403397
ServiceRegion.GCP_EUROPE_WEST1)
404-
.withPolicies(policies -> policies.withRetry(builder -> builder.maxRetries(5)
405-
.statusCodes(Arrays.asList(BAD_GATEWAY_502, SERVICE_UNAVAILABLE_503, GATEWAY_TIMEOUT_504))))
398+
.withRequestPolicies(
399+
policies -> policies
400+
.withAllOtherRequests(
401+
request -> request.withRetry(builder -> builder.maxRetries(5)
402+
.statusCodes(Arrays.asList(BAD_GATEWAY_502, SERVICE_UNAVAILABLE_503,
403+
GATEWAY_TIMEOUT_504)))))
406404
.build("my-project");
407405
}
408406

@@ -590,7 +588,8 @@ public void httpConcurrentLimitation() {
590588
public void queueConcurrentLimitation() {
591589
ApiRootBuilder.of()
592590
// ...
593-
.withPolicies(policies -> policies.withBulkhead(64, Duration.ofSeconds(10)))
591+
.withRequestPolicies(policies -> policies
592+
.withAllOtherRequests(request -> request.withBulkhead(64, Duration.ofSeconds(10))))
594593
.build();
595594
}
596595

commercetools/internal-docs/src/test/java/example/MigrationV2.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ public void retry() {
4747
.defaultClient(ServiceRegion.GCP_EUROPE_WEST1.getApiUrl(),
4848
ClientCredentials.of().withClientId("clientId").withClientSecret("clientSecret").build(),
4949
ServiceRegion.GCP_EUROPE_WEST1.getOAuthTokenUrl())
50-
.withPolicies(policies -> policies.withRetry(builder -> builder
51-
.statusCodes(Arrays.asList(BAD_GATEWAY_502, SERVICE_UNAVAILABLE_503, GATEWAY_TIMEOUT_504))))
50+
.withRequestPolicies(policies -> policies
51+
.withAllOtherRequests(request -> request.withRetry(builder -> builder.statusCodes(
52+
Arrays.asList(BAD_GATEWAY_502, SERVICE_UNAVAILABLE_503, GATEWAY_TIMEOUT_504)))))
5253
.build("projectKey");
5354

5455
final CategoryPagedQueryResponse body = projectClient.categories().get().executeBlocking().getBody();

rmf/rmf-java-base/src/main/java/io/vrap/rmf/base/client/http/PolicyBuilder.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
*
1919
* <p>The PolicyBuilder allows the combination of different policies for failing requests.</p>
2020
*
21+
* <p>In case you need different policies based on the request use the {@link RequestPolicyBuilder} instead</p>
22+
*
2123
* <p>The order of policies matters. For example applying a {@link #withTimeout(Duration) timeout} before
2224
* {@link #withRetry(RetryPolicyBuilder)} retry} will time out across all requests whereas applying a timeout after the retry count
2325
* against every single request even the retried ones.</p>

rmf/rmf-java-base/src/main/java/io/vrap/rmf/base/client/http/RequestPolicyBuilder.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,33 +15,34 @@
1515
import dev.failsafe.spi.Scheduler;
1616

1717
/**
18-
* <h2>PolicyBuilder</h2>
18+
* <h2>RequestPolicyBuilder</h2>
1919
*
20-
* <p>The PolicyBuilder allows the combination of different policies for failing requests.</p>
20+
* <p>The RequestPolicyBuilder allows the combination of different policies for failing requests and apply them to matching
21+
* requests.</p>
2122
*
22-
* <p>The order of policies matters. For example applying a {@link #withTimeout(Duration) timeout} before
23-
* {@link #withRetry(RetryPolicyBuilder)} retry} will time out across all requests whereas applying a timeout after the retry count
23+
* <p>The order of policies matters. For example applying a {@link PolicyBuilder#withTimeout(Duration) timeout} before
24+
* {@link PolicyBuilder#withRetry(RetryPolicyBuilder)} retry} will time out across all requests whereas applying a timeout after the retry count
2425
* against every single request even the retried ones.</p>
2526
*
2627
* <h3 id="retry">Retry</h3>
2728
*
2829
* <h4>Retrying on HTTP status codes</h4>
2930
*
30-
* {@include.example io.vrap.rmf.base.client.http.PolicyMiddlewareTest#retryConfigurationStatusCodes()}
31+
* {@include.example io.vrap.rmf.base.client.http.RequestPolicyMiddlewareTest#retryConfigurationStatusCodes()}
3132
*
3233
* <h3>Retrying specific exceptions</h3>
3334
*
34-
* {@include.example io.vrap.rmf.base.client.http.PolicyMiddlewareTest#retryConfigurationExceptions()}
35+
* {@include.example io.vrap.rmf.base.client.http.RequestPolicyMiddlewareTest#retryConfigurationExceptions()}
3536
*
3637
* <h3 id="timeout">Timeout</h3>
3738
*
38-
* {@include.example io.vrap.rmf.base.client.http.PolicyMiddlewareTest#timeoutConfiguration()}
39+
* {@include.example io.vrap.rmf.base.client.http.RequestPolicyMiddlewareTest#timeoutConfiguration()}
3940
*
4041
* <h3 id="bulkhead">Bulkhead</h3>
4142
*
4243
* <p>Implementation of a Queue to limit the number of concurrent requests handled by the client</p>
4344
*
44-
* {@include.example io.vrap.rmf.base.client.http.PolicyMiddlewareTest#queueConfiguration()}
45+
* {@include.example io.vrap.rmf.base.client.http.RequestPolicyMiddlewareTest#queueConfiguration()}
4546
*/
4647
public class RequestPolicyBuilder {
4748

@@ -85,6 +86,13 @@ public RequestPolicyBuilder withRequestMatching(final Predicate<ApiHttpRequest>
8586
return new RequestPolicyBuilder(scheduler, policiesCopy);
8687
}
8788

89+
public RequestPolicyBuilder withAllOtherRequests(Function<PolicyBuilder, PolicyBuilder> fn) {
90+
Map<Predicate<ApiHttpRequest>, List<Policy<ApiHttpResponse<byte[]>>>> policiesCopy = new LinkedHashMap<>(
91+
policies);
92+
policiesCopy.put(apiHttpRequest -> true, fn.apply(PolicyBuilder.of()).getPolicies());
93+
return new RequestPolicyBuilder(scheduler, policiesCopy);
94+
}
95+
8896
public PolicyMiddleware build() {
8997
return PolicyMiddleware.of(new ArrayList<>(policies.entrySet()), scheduler);
9098
}
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
2+
package io.vrap.rmf.base.client.http;
3+
4+
import static io.vrap.rmf.base.client.utils.ClientUtils.blockingWait;
5+
import static java.util.Collections.singletonList;
6+
7+
import java.net.URI;
8+
import java.nio.charset.StandardCharsets;
9+
import java.time.Duration;
10+
import java.util.Arrays;
11+
import java.util.concurrent.CompletableFuture;
12+
import java.util.concurrent.CompletionException;
13+
import java.util.concurrent.atomic.AtomicInteger;
14+
15+
import io.vrap.rmf.base.client.*;
16+
import io.vrap.rmf.base.client.utils.json.JsonException;
17+
18+
import org.assertj.core.api.Assertions;
19+
import org.junit.jupiter.api.Test;
20+
21+
import dev.failsafe.TimeoutBuilder;
22+
23+
public class RequestPolicyMiddlewareTest {
24+
25+
@Test
26+
public void testWithStatusCode() {
27+
PolicyMiddleware middleware = RequestPolicyBuilder.of()
28+
.withRequestMatching(request -> request.getMethod() == ApiHttpMethod.GET,
29+
request -> request.withRetry(builder -> builder.maxRetries(1)))
30+
.build();
31+
32+
final ApiHttpRequest request = new ApiHttpRequest().withMethod(ApiHttpMethod.GET);
33+
AtomicInteger count = new AtomicInteger();
34+
35+
final ApiHttpResponse<byte[]> apiHttpResponse = blockingWait(middleware.invoke(request, request1 -> {
36+
count.getAndIncrement();
37+
return CompletableFuture.completedFuture(new ApiHttpResponse<>(503, null, null));
38+
}), Duration.ofSeconds(1));
39+
Assertions.assertThat(apiHttpResponse.getStatusCode()).isEqualTo(503);
40+
Assertions.assertThat(count.get()).isEqualTo(2);
41+
}
42+
43+
@Test
44+
public void testWithCoveredException() {
45+
PolicyMiddleware middleware = RequestPolicyBuilder.of()
46+
.withRequestMatching(request -> request.getMethod() == ApiHttpMethod.GET,
47+
request -> request.withRetry(builder -> builder.maxRetries(1)))
48+
.build();
49+
50+
final URI uri = URI.create("https://www.commercetools.com/");
51+
52+
final ApiHttpRequest request = new ApiHttpRequest(ApiHttpMethod.GET, uri, null, null);
53+
AtomicInteger count = new AtomicInteger();
54+
55+
Assertions.assertThatExceptionOfType(ApiHttpException.class).isThrownBy(() -> {
56+
blockingWait(middleware.invoke(request, request1 -> {
57+
count.getAndIncrement();
58+
return CompletableFuture.supplyAsync(() -> {
59+
throw new CompletionException(new ApiHttpException(503, null, null, null, null, request));
60+
});
61+
}), Duration.ofSeconds(1));
62+
}).matches(e -> e.getStatusCode() == 503);
63+
Assertions.assertThat(count.get()).isEqualTo(2);
64+
}
65+
66+
@Test
67+
public void testWithCoveredExceptionResponse() {
68+
PolicyMiddleware middleware = RequestPolicyBuilder.of()
69+
.withRequestMatching(request -> request.getMethod() == ApiHttpMethod.GET,
70+
request -> request.withRetry(builder -> builder.maxRetries(1)))
71+
.build();
72+
73+
final URI uri = URI.create("https://www.commercetools.com/");
74+
75+
final ApiHttpRequest request = new ApiHttpRequest(ApiHttpMethod.GET, uri, null, null);
76+
AtomicInteger count = new AtomicInteger();
77+
final ApiHttpResponse<byte[]> response = new ApiHttpResponse<>(503, new ApiHttpHeaders(),
78+
"{\"hello\": \"world\"}".getBytes(StandardCharsets.UTF_8), "Oops!");
79+
Assertions.assertThatExceptionOfType(ApiHttpException.class).isThrownBy(() -> {
80+
blockingWait(middleware.invoke(request, request1 -> {
81+
count.getAndIncrement();
82+
return CompletableFuture.supplyAsync(() -> {
83+
throw new CompletionException(new ApiHttpException(503, null, null, null, response, request));
84+
});
85+
}), Duration.ofSeconds(1));
86+
}).matches(e -> e.getStatusCode() == 503);
87+
Assertions.assertThat(count.get()).isEqualTo(2);
88+
}
89+
90+
@Test
91+
public void testUncoveredException() {
92+
PolicyMiddleware middleware = RequestPolicyBuilder.of()
93+
.withRequestMatching(request -> request.getMethod() == ApiHttpMethod.GET,
94+
request -> request.withRetry(builder -> builder.maxRetries(1)))
95+
.build();
96+
97+
final ApiHttpRequest request = new ApiHttpRequest();
98+
AtomicInteger count = new AtomicInteger();
99+
100+
Assertions.assertThatExceptionOfType(ApiHttpException.class).isThrownBy(() -> {
101+
blockingWait(middleware.invoke(request, request1 -> {
102+
count.getAndIncrement();
103+
return CompletableFuture.supplyAsync(() -> {
104+
throw new CompletionException(new ApiHttpException(504, null, null, null, null, request));
105+
});
106+
}), Duration.ofSeconds(1));
107+
}).matches(e -> e.getStatusCode() == 504);
108+
Assertions.assertThat(count.get()).isEqualTo(1);
109+
}
110+
111+
@Test
112+
public void testRetrySuccess() {
113+
PolicyMiddleware middleware = RequestPolicyBuilder.of()
114+
.withRequestMatching(request -> request.getMethod() == ApiHttpMethod.GET,
115+
request -> request.withRetry(builder -> builder.maxRetries(1)))
116+
.build();
117+
118+
final ApiHttpRequest request = new ApiHttpRequest();
119+
AtomicInteger count = new AtomicInteger();
120+
121+
final ApiHttpResponse<byte[]> apiHttpResponse = blockingWait(middleware.invoke(request, request1 -> {
122+
count.getAndIncrement();
123+
return CompletableFuture.completedFuture(new ApiHttpResponse<>(200, null, null));
124+
}), Duration.ofSeconds(1));
125+
Assertions.assertThat(apiHttpResponse.getStatusCode()).isEqualTo(200);
126+
Assertions.assertThat(count.get()).isEqualTo(1);
127+
}
128+
129+
public void retryConfigurationStatusCodes() {
130+
final ApiHttpClient build = ClientBuilder.of()
131+
// ...
132+
.withRequestPolicies(policyBuilder -> policyBuilder
133+
.withAllOtherRequests(request -> request.withRetry(retry -> retry.maxRetries(3)
134+
.statusCodes(Arrays.asList(HttpStatusCode.SERVICE_UNAVAILABLE_503,
135+
HttpStatusCode.INTERNAL_SERVER_ERROR_500)))))
136+
.build();
137+
}
138+
139+
public void retryConfigurationExceptions() {
140+
final ApiHttpClient build = ClientBuilder.of()
141+
// ...
142+
.withRequestPolicies(policyBuilder -> policyBuilder.withAllOtherRequests(request -> request
143+
.withRetry(retry -> retry.maxRetries(3).failures(singletonList(JsonException.class)))))
144+
.build();
145+
}
146+
147+
public void queueConfiguration() {
148+
final ApiHttpClient build = ClientBuilder.of()
149+
// ...
150+
.withRequestPolicies(policyBuilder -> policyBuilder
151+
.withAllOtherRequests(request -> request.withBulkhead(64, Duration.ofSeconds(10))))
152+
.build();
153+
}
154+
155+
public void timeoutConfiguration() {
156+
final ApiHttpClient build = ClientBuilder.of()
157+
// ...
158+
.withRequestPolicies(policyBuilder -> policyBuilder.withAllOtherRequests(
159+
request -> request.withTimeout(Duration.ofSeconds(10), TimeoutBuilder::withInterrupt)))
160+
.build();
161+
}
162+
}

0 commit comments

Comments
 (0)