diff --git a/src/main/java/com/fauna/client/FaunaClient.java b/src/main/java/com/fauna/client/FaunaClient.java index 0e00703e..ff5e9d2d 100644 --- a/src/main/java/com/fauna/client/FaunaClient.java +++ b/src/main/java/com/fauna/client/FaunaClient.java @@ -74,8 +74,8 @@ public Logger getLogger() { return this.logger; } - public Optional getStatsCollector() { - return Optional.ofNullable(this.statsCollector); + public StatsCollector getStatsCollector() { + return this.statsCollector; } public Optional getLastTransactionTs() { diff --git a/src/main/java/com/fauna/client/FaunaConfig.java b/src/main/java/com/fauna/client/FaunaConfig.java index 51eb8339..e8f008e2 100644 --- a/src/main/java/com/fauna/client/FaunaConfig.java +++ b/src/main/java/com/fauna/client/FaunaConfig.java @@ -86,7 +86,7 @@ public Handler getLogHandler() { /** * Gets the stats collector for the client. - * @return A log handler instance. + * @return A StatsCollector instance. */ public StatsCollector getStatsCollector() { return statsCollector; @@ -110,7 +110,7 @@ public static class Builder { private int maxContentionRetries = 3; private Duration clientTimeoutBuffer = Duration.ofSeconds(5); private Handler logHandler = defaultLogHandler(); - private StatsCollector statsCollector; + private StatsCollector statsCollector = new StatsCollectorImpl(); static Level getLogLevel(String debug) { if (debug == null || debug.isBlank()) { @@ -191,15 +191,6 @@ public Builder statsCollector(StatsCollector statsCollector) { return this; } - /** - * Set a default StatsCollector. - * @return The current Builder instance. - */ - public Builder defaultStatsCollector() { - this.statsCollector = new StatsCollectorImpl(); - return this; - } - /** * Builds and returns a new FaunaConfig instance. * diff --git a/src/main/java/com/fauna/client/FaunaStream.java b/src/main/java/com/fauna/client/FaunaStream.java index fd1f4c7b..f516ac22 100644 --- a/src/main/java/com/fauna/client/FaunaStream.java +++ b/src/main/java/com/fauna/client/FaunaStream.java @@ -64,9 +64,7 @@ public void onNext(List buffers) { JsonParser parser = JSON_FACTORY.createParser(buffer); StreamEvent event = StreamEvent.parse(parser, dataCodec); - if (statsCollector != null) { - statsCollector.add(event.getStats()); - } + statsCollector.add(event.getStats()); if (event.getType() == StreamEvent.EventType.ERROR) { ErrorInfo error = event.getError(); diff --git a/src/main/java/com/fauna/client/ScopedFaunaClient.java b/src/main/java/com/fauna/client/ScopedFaunaClient.java index 27049c88..71b92dbb 100644 --- a/src/main/java/com/fauna/client/ScopedFaunaClient.java +++ b/src/main/java/com/fauna/client/ScopedFaunaClient.java @@ -9,7 +9,7 @@ public class ScopedFaunaClient extends FaunaClient { public ScopedFaunaClient(FaunaClient client, FaunaScope scope) { - super(client.getFaunaSecret(), client.getLogger(), client.getStatsCollector().orElse(null)); + super(client.getFaunaSecret(), client.getLogger(), client.getStatsCollector().clone()); this.client = client; this.requestBuilder = client.getRequestBuilder().scopedRequestBuilder(scope.getToken(client.getFaunaSecret())); this.streamRequestBuilder = client.getStreamRequestBuilder().scopedRequestBuilder(scope.getToken(client.getFaunaSecret())); diff --git a/src/main/java/com/fauna/client/StatsCollector.java b/src/main/java/com/fauna/client/StatsCollector.java index 07321c9e..92fdb38a 100644 --- a/src/main/java/com/fauna/client/StatsCollector.java +++ b/src/main/java/com/fauna/client/StatsCollector.java @@ -21,4 +21,10 @@ public interface StatsCollector { * @return Stats object */ QueryStatsSummary readAndReset(); + + /** + * Clone the stats collector instance. + * @return A clone of the stats collector instance. + */ + StatsCollector clone(); } diff --git a/src/main/java/com/fauna/client/StatsCollectorImpl.java b/src/main/java/com/fauna/client/StatsCollectorImpl.java index 2c8da78d..2f969723 100644 --- a/src/main/java/com/fauna/client/StatsCollectorImpl.java +++ b/src/main/java/com/fauna/client/StatsCollectorImpl.java @@ -89,5 +89,10 @@ public QueryStatsSummary readAndReset() { rateLimitedWriteQueryCount.getAndSet(0) ); } + + @Override + public StatsCollector clone() { + return new StatsCollectorImpl(); + } } diff --git a/src/main/java/com/fauna/response/QueryResponse.java b/src/main/java/com/fauna/response/QueryResponse.java index 9758409e..f3d82052 100644 --- a/src/main/java/com/fauna/response/QueryResponse.java +++ b/src/main/java/com/fauna/response/QueryResponse.java @@ -149,7 +149,7 @@ public static QuerySuccess parseResponse(HttpResponse respo builder = handleField(builder, parser); } - if (statsCollector != null && builder.stats != null) { + if (builder.stats != null) { statsCollector.add(builder.stats); } diff --git a/src/test/java/com/fauna/client/FaunaClientTest.java b/src/test/java/com/fauna/client/FaunaClientTest.java index 3343d891..2501334c 100644 --- a/src/test/java/com/fauna/client/FaunaClientTest.java +++ b/src/test/java/com/fauna/client/FaunaClientTest.java @@ -39,6 +39,7 @@ import static com.fauna.query.builder.Query.fql; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -81,7 +82,7 @@ static HttpResponse mockResponse(String body) { void defaultClient() { FaunaClient client = Fauna.client(); assertTrue(client.getHttpClient().connectTimeout().isEmpty()); - assertTrue(client.getStatsCollector().isEmpty()); + assertNotNull(client.getStatsCollector()); assertEquals(URI.create("https://db.fauna.com/query/1"), client.getRequestBuilder().buildRequest( fql("hello"), QueryOptions.builder().build(), DefaultCodecProvider.SINGLETON, 1L).uri()); @@ -104,11 +105,10 @@ void customConfigBuilder() { void customConfigConstructor() { FaunaConfig cfg = FaunaConfig.builder() .secret("foo") - .defaultStatsCollector() .build(); FaunaClient client = Fauna.client(cfg); assertTrue(client.toString().startsWith("com.fauna.client.BaseFaunaClient")); - assertTrue(client.getStatsCollector().isPresent()); + assertNotNull(client.getStatsCollector()); } @Test diff --git a/src/test/java/com/fauna/client/FaunaConfigTest.java b/src/test/java/com/fauna/client/FaunaConfigTest.java index a9e20e48..2a9c0e5e 100644 --- a/src/test/java/com/fauna/client/FaunaConfigTest.java +++ b/src/test/java/com/fauna/client/FaunaConfigTest.java @@ -23,7 +23,7 @@ public void testDefaultFaunaConfig() { assertEquals(Level.WARNING, config.getLogHandler().getLevel()); assertEquals("", config.getSecret()); assertEquals(3, config.getMaxContentionRetries()); - assertNull(config.getStatsCollector()); + assertNotNull(config.getStatsCollector()); } @Test @@ -38,7 +38,6 @@ public void testOverridingDefaultFaunaConfig() { .logHandler(handler) .maxContentionRetries(1) .clientTimeoutBuffer(Duration.ofSeconds(1)) - .defaultStatsCollector() .build(); assertEquals("endpoint", config.getEndpoint()); assertEquals(Level.ALL, config.getLogHandler().getLevel()); diff --git a/src/test/java/com/fauna/e2e/E2EPaginationTest.java b/src/test/java/com/fauna/e2e/E2EPaginationTest.java index c545b130..c975dbc7 100644 --- a/src/test/java/com/fauna/e2e/E2EPaginationTest.java +++ b/src/test/java/com/fauna/e2e/E2EPaginationTest.java @@ -118,13 +118,12 @@ public void query_statsAreTrackedForExplicitPagination() { var cfg = FaunaConfig.builder() .secret("secret") .endpoint("http://localhost:8443") - .defaultStatsCollector() .build(); var client = Fauna.client(cfg); PageIterator iter = client.paginate(fql("Product.all()"), Product.class); iter.forEachRemaining(page -> {}); - var stats = client.getStatsCollector().get().read(); + var stats = client.getStatsCollector().read(); assertEquals(82, stats.getReadOps()); assertEquals(4, stats.getComputeOps()); } @@ -134,7 +133,6 @@ public void query_statsAreTrackedForFlattenedPagination() { var cfg = FaunaConfig.builder() .secret("secret") .endpoint("http://localhost:8443") - .defaultStatsCollector() .build(); var client = Fauna.client(cfg); PageIterator iter = client.paginate(fql("Product.all()"), Product.class); @@ -142,7 +140,7 @@ public void query_statsAreTrackedForFlattenedPagination() { for (Product p : (Iterable) () -> productIter) { } - var stats = client.getStatsCollector().get().read(); + var stats = client.getStatsCollector().read(); assertEquals(82, stats.getReadOps()); assertEquals(4, stats.getComputeOps()); } diff --git a/src/test/java/com/fauna/e2e/E2EQueryTest.java b/src/test/java/com/fauna/e2e/E2EQueryTest.java index ad43d026..50e37ba4 100644 --- a/src/test/java/com/fauna/e2e/E2EQueryTest.java +++ b/src/test/java/com/fauna/e2e/E2EQueryTest.java @@ -284,14 +284,13 @@ public void query_trackStatsOnSuccess() { var cfg = FaunaConfig.builder() .secret("secret") .endpoint("http://localhost:8443") - .defaultStatsCollector() .build(); var client = Fauna.client(cfg); var q = fql("Author.all().toArray()"); client.query(q, listOf(Author.class)); - var stats = client.getStatsCollector().get().read(); + var stats = client.getStatsCollector().read(); assertEquals(10, stats.getReadOps()); assertEquals(1, stats.getComputeOps()); } @@ -301,13 +300,12 @@ public void query_trackStatsOnFailure() throws IOException { var cfg = FaunaConfig.builder() .secret("secret") .endpoint("http://localhost:8443") - .defaultStatsCollector() .build(); var client = Fauna.client(cfg); var q = fql("Author.all().toArray()\nabort(null)"); assertThrows(AbortException.class, () -> client.query(q)); - var stats = client.getStatsCollector().get().read(); + var stats = client.getStatsCollector().read(); assertEquals(8, stats.getReadOps()); assertEquals(1, stats.getComputeOps()); } diff --git a/src/test/java/com/fauna/e2e/E2EStreamingTest.java b/src/test/java/com/fauna/e2e/E2EStreamingTest.java index 37984215..0f16971f 100644 --- a/src/test/java/com/fauna/e2e/E2EStreamingTest.java +++ b/src/test/java/com/fauna/e2e/E2EStreamingTest.java @@ -117,12 +117,11 @@ public void query_streamOfProduct() throws InterruptedException { var cfg = FaunaConfig.builder() .secret("secret") .endpoint("http://localhost:8443") - .defaultStatsCollector() .build(); var streamClient = Fauna.client(cfg); - FaunaStream stream = streamClient.stream(fql("Product.all().toStream()"), Product.class); - var stats = streamClient.getStatsCollector().get().readAndReset(); + FaunaStream stream = streamClient.stream(fql("Product.all().toStream()"), Product.class); + var stats = streamClient.getStatsCollector().readAndReset(); assertEquals(1, stats.getComputeOps()); InventorySubscriber inventory = new InventorySubscriber(); @@ -153,7 +152,7 @@ public void query_streamOfProduct() throws InterruptedException { stream.close(); assertTrue(stream.isClosed()); - stats = streamClient.getStatsCollector().get().read(); + stats = streamClient.getStatsCollector().read(); assertEquals(11, stats.getReadOps()); assertEquals(events, stats.getComputeOps()); } diff --git a/src/test/java/com/fauna/response/QueryResponseTest.java b/src/test/java/com/fauna/response/QueryResponseTest.java index 85c584fb..65b6ba46 100644 --- a/src/test/java/com/fauna/response/QueryResponseTest.java +++ b/src/test/java/com/fauna/response/QueryResponseTest.java @@ -9,6 +9,7 @@ import static org.mockito.Mockito.when; import com.fauna.beans.ClassWithAttributes; +import com.fauna.client.StatsCollectorImpl; import com.fauna.codec.Codec; import com.fauna.codec.CodecProvider; import com.fauna.codec.CodecRegistry; @@ -55,7 +56,7 @@ public void getFromResponseBody_Success() throws IOException { HttpResponse resp = mockResponse(body); when(resp.statusCode()).thenReturn(200); - QuerySuccess success = QueryResponse.parseResponse(resp, codec, null); + QuerySuccess success = QueryResponse.parseResponse(resp, codec, new StatsCollectorImpl()); assertEquals(baz.getFirstName(), success.getData().getFirstName()); assertEquals("PersonWithAttributes", success.getStaticType().get()); @@ -68,14 +69,14 @@ public void handleResponseWithInvalidJsonThrowsClientResponseException() { HttpResponse resp = mockResponse("{\"not valid json\""); when(resp.statusCode()).thenReturn(400); - ClientResponseException exc = assertThrows(ClientResponseException.class, () -> QueryResponse.parseResponse(resp, codecProvider.get(Object.class), null)); + ClientResponseException exc = assertThrows(ClientResponseException.class, () -> QueryResponse.parseResponse(resp, codecProvider.get(Object.class), new StatsCollectorImpl())); assertEquals("ClientResponseException HTTP 400: Failed to handle error response.", exc.getMessage()); } @Test public void handleResponseWithEmptyFieldsDoesNotThrow() { HttpResponse resp = mockResponse("{}"); - QuerySuccess response = QueryResponse.parseResponse(resp, codecProvider.get(Object.class), null); + QuerySuccess response = QueryResponse.parseResponse(resp, codecProvider.get(Object.class), new StatsCollectorImpl()); assertEquals(QuerySuccess.class, response.getClass()); assertNull(response.getSchemaVersion()); assertNull(response.getSummary());