Skip to content

Commit 29a3511

Browse files
authored
Merge pull request #726 from commercetools/datadog-middleware-test
add test for Datadog middleware
2 parents dddb9bb + 60af3f9 commit 29a3511

File tree

5 files changed

+280
-0
lines changed

5 files changed

+280
-0
lines changed

commercetools/commercetools-monitoring-datadog/src/main/java/com/commercetools/monitoring/datadog/DatadogMiddleware.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ public DatadogMiddleware(final ApiClient ddApiClient) {
4343
this.apiInstance = new MetricsApi(ddApiClient);
4444
}
4545

46+
public DatadogMiddleware(final MetricsApi apiInstance) {
47+
this.apiInstance = apiInstance;
48+
}
49+
4650
@Override
4751
public CompletableFuture<ApiHttpResponse<byte[]>> invoke(ApiHttpRequest request,
4852
Function<ApiHttpRequest, CompletableFuture<ApiHttpResponse<byte[]>>> next) {

commercetools/commercetools-monitoring-datadog/src/main/java/com/commercetools/monitoring/datadog/DatadogResponseSerializer.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ public class DatadogResponseSerializer implements ResponseSerializer {
2525

2626
private final MetricsApi apiInstance;
2727

28+
public DatadogResponseSerializer(final ResponseSerializer serializer, final MetricsApi apiInstance) {
29+
this.serializer = serializer;
30+
this.apiInstance = apiInstance;
31+
}
32+
2833
public DatadogResponseSerializer(final ResponseSerializer serializer, final ApiClient ddApiClient) {
2934
this.serializer = serializer;
3035
this.apiInstance = new MetricsApi(ddApiClient);
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
2+
package example;
3+
4+
import com.commercetools.api.models.common.Reference;
5+
import com.commercetools.api.models.product.ProductReference;
6+
import com.commercetools.monitoring.datadog.DatadogResponseSerializer;
7+
import com.datadog.api.client.ApiException;
8+
import com.datadog.api.client.v2.api.MetricsApi;
9+
import com.fasterxml.jackson.core.JsonProcessingException;
10+
11+
import io.vrap.rmf.base.client.ApiHttpHeaders;
12+
import io.vrap.rmf.base.client.ApiHttpResponse;
13+
import io.vrap.rmf.base.client.ResponseSerializer;
14+
15+
import org.assertj.core.api.Assertions;
16+
import org.junit.jupiter.api.Test;
17+
import org.mockito.Mockito;
18+
19+
public class ResponseSerializerTest {
20+
21+
@Test
22+
public void testSerialize() throws ApiException, JsonProcessingException {
23+
MetricsApi metricsApi = Mockito.mock(MetricsApi.class);
24+
Mockito.when(metricsApi.submitMetrics(Mockito.any())).thenReturn(null);
25+
DatadogResponseSerializer serializer = new DatadogResponseSerializer(ResponseSerializer.of(), metricsApi);
26+
27+
Reference reference = ProductReference.builder().id("abc").build();
28+
29+
serializer.toJsonByteArray(reference);
30+
31+
Mockito.verify(metricsApi).submitMetrics(Mockito.argThat(metricPayload -> {
32+
Assertions.assertThat(metricPayload).isNotNull();
33+
Assertions.assertThat(metricPayload.getSeries().get(0).getMetric())
34+
.isEqualTo("commercetools.json.serialization");
35+
return true;
36+
}));
37+
}
38+
39+
@Test
40+
public void testDeserialize() throws ApiException, JsonProcessingException {
41+
MetricsApi metricsApi = Mockito.mock(MetricsApi.class);
42+
Mockito.when(metricsApi.submitMetrics(Mockito.any())).thenReturn(null);
43+
DatadogResponseSerializer serializer = new DatadogResponseSerializer(ResponseSerializer.of(), metricsApi);
44+
45+
String responseBody = "{ \"typeId\": \"product\", \"id\": \"abc\" }";
46+
ApiHttpResponse<byte[]> response = new ApiHttpResponse<>(200, new ApiHttpHeaders(), responseBody.getBytes());
47+
48+
ApiHttpResponse<Reference> reference = serializer.convertResponse(response, Reference.class);
49+
50+
Assertions.assertThat(reference.getBody()).isInstanceOf(ProductReference.class);
51+
Mockito.verify(metricsApi).submitMetrics(Mockito.argThat(metricPayload -> {
52+
Assertions.assertThat(metricPayload).isNotNull();
53+
Assertions.assertThat(metricPayload.getSeries().get(0).getMetric())
54+
.isEqualTo("commercetools.json.deserialization");
55+
return true;
56+
}));
57+
}
58+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
2+
package example;
3+
4+
import static io.vrap.rmf.base.client.utils.ClientUtils.blockingWait;
5+
6+
import java.net.URI;
7+
import java.net.URISyntaxException;
8+
import java.time.Duration;
9+
import java.util.concurrent.CompletableFuture;
10+
import java.util.function.Function;
11+
12+
import com.commercetools.monitoring.datadog.DatadogMiddleware;
13+
import com.datadog.api.client.ApiException;
14+
import com.datadog.api.client.v2.api.MetricsApi;
15+
import com.tngtech.junit.dataprovider.DataProvider;
16+
import com.tngtech.junit.dataprovider.DataProviderExtension;
17+
import com.tngtech.junit.dataprovider.UseDataProvider;
18+
import com.tngtech.junit.dataprovider.UseDataProviderExtension;
19+
20+
import io.vrap.rmf.base.client.*;
21+
22+
import org.assertj.core.api.Assertions;
23+
import org.junit.jupiter.api.TestTemplate;
24+
import org.junit.jupiter.api.extension.ExtendWith;
25+
import org.mockito.Mockito;
26+
27+
@ExtendWith(DataProviderExtension.class)
28+
@ExtendWith(UseDataProviderExtension.class)
29+
public class TelemetryMiddlewareTest {
30+
31+
@DataProvider
32+
public static Object[][] responses() {
33+
return new Object[][] { { 200, 2 }, { 201, 2 }, { 400, 3 }, { 401, 3 }, { 403, 3 }, { 404, 3 }, { 409, 3 },
34+
{ 499, 3 }, { 500, 3 }, { 502, 3 }, { 503, 3 }, { 504, 3 }, { 599, 3 }, };
35+
}
36+
37+
@TestTemplate
38+
@UseDataProvider("responses")
39+
public void testCounts(int statusCode, int count) throws ApiException {
40+
MetricsApi metricsApi = Mockito.mock(MetricsApi.class);
41+
Mockito.when(metricsApi.submitMetrics(Mockito.any())).thenReturn(null);
42+
DatadogMiddleware middleware = new DatadogMiddleware(metricsApi);
43+
44+
final ApiHttpRequest request = new ApiHttpRequest(ApiHttpMethod.GET, URI.create("/"), new ApiHttpHeaders(),
45+
"".getBytes());
46+
47+
blockingWait(
48+
middleware.invoke(request,
49+
request1 -> CompletableFuture
50+
.completedFuture(new ApiHttpResponse<>(statusCode, new ApiHttpHeaders(), "".getBytes()))),
51+
Duration.ofSeconds(1));
52+
53+
Mockito.verify(metricsApi, Mockito.times(count)).submitMetrics(Mockito.argThat(metricPayload -> {
54+
Assertions.assertThat(metricPayload).isNotNull();
55+
Assertions.assertThat(metricPayload.getSeries().get(0).getMetric())
56+
.isIn("commercetools.client.duration", "commercetools.client.request.total",
57+
"commercetools.client.request.error");
58+
return true;
59+
}));
60+
}
61+
62+
@TestTemplate
63+
@UseDataProvider("responses")
64+
public void testHttpCounts(int statusCode, int count) throws URISyntaxException, ApiException {
65+
MetricsApi metricsApi = Mockito.mock(MetricsApi.class);
66+
Mockito.when(metricsApi.submitMetrics(Mockito.any())).thenReturn(null);
67+
DatadogMiddleware middleware = new DatadogMiddleware(metricsApi);
68+
69+
ApiHttpClient client = ClientBuilder
70+
.of(new TestHttpClient(request -> CompletableFuture
71+
.completedFuture(new ApiHttpResponse<>(statusCode, new ApiHttpHeaders(), "".getBytes()))))
72+
.withApiBaseUrl(new URI(""))
73+
.withTelemetryMiddleware(middleware)
74+
.withErrorMiddleware()
75+
.build();
76+
77+
final ApiHttpRequest request = new ApiHttpRequest(ApiHttpMethod.GET, URI.create("/"), new ApiHttpHeaders(),
78+
"".getBytes());
79+
try {
80+
blockingWait(client.execute(request), Duration.ofSeconds(1));
81+
}
82+
catch (ApiHttpException ignored) {
83+
}
84+
85+
Mockito.verify(metricsApi, Mockito.times(count)).submitMetrics(Mockito.argThat(metricPayload -> {
86+
Assertions.assertThat(metricPayload).isNotNull();
87+
Assertions.assertThat(metricPayload.getSeries().get(0).getMetric())
88+
.isIn("commercetools.client.duration", "commercetools.client.request.total",
89+
"commercetools.client.request.error");
90+
return true;
91+
}));
92+
}
93+
94+
static class TestHttpClient implements VrapHttpClient {
95+
private final Function<ApiHttpRequest, CompletableFuture<ApiHttpResponse<byte[]>>> next;
96+
97+
public TestHttpClient(Function<ApiHttpRequest, CompletableFuture<ApiHttpResponse<byte[]>>> next) {
98+
this.next = next;
99+
}
100+
101+
@Override
102+
public CompletableFuture<ApiHttpResponse<byte[]>> execute(ApiHttpRequest request) {
103+
return next.apply(request);
104+
}
105+
}
106+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
2+
package io.vrap.rmf.base.client.http;
3+
4+
import static io.vrap.rmf.base.client.utils.ClientUtils.blockingWait;
5+
6+
import java.net.URI;
7+
import java.net.URISyntaxException;
8+
import java.time.Duration;
9+
import java.util.concurrent.CompletableFuture;
10+
import java.util.function.Function;
11+
12+
import com.tngtech.junit.dataprovider.DataProvider;
13+
import com.tngtech.junit.dataprovider.DataProviderExtension;
14+
import com.tngtech.junit.dataprovider.UseDataProvider;
15+
import com.tngtech.junit.dataprovider.UseDataProviderExtension;
16+
17+
import io.vrap.rmf.base.client.*;
18+
import io.vrap.rmf.base.client.error.*;
19+
20+
import org.assertj.core.api.Assertions;
21+
import org.junit.jupiter.api.TestTemplate;
22+
import org.junit.jupiter.api.extension.ExtendWith;
23+
24+
@ExtendWith(DataProviderExtension.class)
25+
@ExtendWith(UseDataProviderExtension.class)
26+
public class TelemetryMiddlewareTest {
27+
28+
@DataProvider
29+
public static Object[][] responses() {
30+
return new Object[][] { { 200, 1, 0 }, { 201, 1, 0 }, { 400, 1, 1 }, { 401, 1, 1 }, { 403, 1, 1 },
31+
{ 404, 1, 1 }, { 409, 1, 1 }, { 499, 1, 1 }, { 500, 1, 1 }, { 502, 1, 1 }, { 503, 1, 1 }, { 504, 1, 1 },
32+
{ 599, 1, 1 }, };
33+
}
34+
35+
@TestTemplate
36+
@UseDataProvider("responses")
37+
public void testCounts(int statusCode, int count, int errorCount) {
38+
TestTelemetryMiddleware middleware = new TestTelemetryMiddleware();
39+
40+
final ApiHttpRequest request = new ApiHttpRequest(ApiHttpMethod.GET, URI.create("/"), new ApiHttpHeaders(),
41+
"".getBytes());
42+
43+
blockingWait(
44+
middleware.invoke(request,
45+
request1 -> CompletableFuture
46+
.completedFuture(new ApiHttpResponse<>(statusCode, new ApiHttpHeaders(), "".getBytes()))),
47+
Duration.ofSeconds(1));
48+
49+
Assertions.assertThat(middleware.count).isEqualTo(count);
50+
Assertions.assertThat(middleware.errorCount).isEqualTo(errorCount);
51+
}
52+
53+
@TestTemplate
54+
@UseDataProvider("responses")
55+
public void testHttpCounts(int statusCode, int count, int errorCount) throws URISyntaxException {
56+
TestTelemetryMiddleware middleware = new TestTelemetryMiddleware();
57+
58+
ApiHttpClient client = ClientBuilder
59+
.of(new TestHttpClient(request -> CompletableFuture
60+
.completedFuture(new ApiHttpResponse<>(statusCode, new ApiHttpHeaders(), "".getBytes()))))
61+
.withApiBaseUrl(new URI(""))
62+
.withTelemetryMiddleware(middleware)
63+
.withErrorMiddleware()
64+
.build();
65+
66+
final ApiHttpRequest request = new ApiHttpRequest(ApiHttpMethod.GET, URI.create("/"), new ApiHttpHeaders(),
67+
"".getBytes());
68+
try {
69+
blockingWait(client.execute(request), Duration.ofSeconds(1));
70+
}
71+
catch (ApiHttpException ignored) {
72+
}
73+
74+
Assertions.assertThat(middleware.count).isEqualTo(count);
75+
Assertions.assertThat(middleware.errorCount).isEqualTo(errorCount);
76+
}
77+
78+
static class TestHttpClient implements VrapHttpClient {
79+
private final Function<ApiHttpRequest, CompletableFuture<ApiHttpResponse<byte[]>>> next;
80+
81+
public TestHttpClient(Function<ApiHttpRequest, CompletableFuture<ApiHttpResponse<byte[]>>> next) {
82+
this.next = next;
83+
}
84+
85+
@Override
86+
public CompletableFuture<ApiHttpResponse<byte[]>> execute(ApiHttpRequest request) {
87+
return next.apply(request);
88+
}
89+
}
90+
91+
static class TestTelemetryMiddleware implements TelemetryMiddleware {
92+
93+
public long count = 0;
94+
public long errorCount = 0;
95+
@Override
96+
public CompletableFuture<ApiHttpResponse<byte[]>> invoke(ApiHttpRequest request,
97+
Function<ApiHttpRequest, CompletableFuture<ApiHttpResponse<byte[]>>> next) {
98+
return next.apply(request).thenApply(response -> {
99+
count++;
100+
if (response.getStatusCode() >= 400) {
101+
errorCount++;
102+
}
103+
return response;
104+
});
105+
}
106+
}
107+
}

0 commit comments

Comments
 (0)