From 42d35896b2cfc7f7acb9bb561cbd9fd20538c1ca Mon Sep 17 00:00:00 2001 From: Aaron Steinfeld Date: Fri, 7 Jun 2024 08:42:39 -0400 Subject: [PATCH] refactor: add support for client timeouts --- .../config/objectstore/ClientConfig.java | 11 +++ .../ContextuallyIdentifiedObjectStore.java | 66 ++++++------- .../objectstore/DefaultObjectStore.java | 70 ++++++++----- .../objectstore/IdentifiedObjectStore.java | 99 ++++++++++++------- .../IdentifiedObjectStoreWithFilter.java | 14 +++ ...ContextuallyIdentifiedObjectStoreTest.java | 10 +- .../objectstore/DefaultObjectStoreTest.java | 5 +- .../IdentifiedObjectStoreTest.java | 5 +- .../IdentifiedObjectStoreWithFilterTest.java | 5 +- 9 files changed, 177 insertions(+), 108 deletions(-) create mode 100644 object-store/src/main/java/org/hypertrace/config/objectstore/ClientConfig.java diff --git a/object-store/src/main/java/org/hypertrace/config/objectstore/ClientConfig.java b/object-store/src/main/java/org/hypertrace/config/objectstore/ClientConfig.java new file mode 100644 index 00000000..f70bea34 --- /dev/null +++ b/object-store/src/main/java/org/hypertrace/config/objectstore/ClientConfig.java @@ -0,0 +1,11 @@ +package org.hypertrace.config.objectstore; + +import java.time.Duration; +import lombok.Value; + +@Value +public class ClientConfig { + Duration timeout; + + public static ClientConfig DEFAULT = new ClientConfig(Duration.ofSeconds(5)); +} diff --git a/object-store/src/main/java/org/hypertrace/config/objectstore/ContextuallyIdentifiedObjectStore.java b/object-store/src/main/java/org/hypertrace/config/objectstore/ContextuallyIdentifiedObjectStore.java index 118c563c..5f93b7ab 100644 --- a/object-store/src/main/java/org/hypertrace/config/objectstore/ContextuallyIdentifiedObjectStore.java +++ b/object-store/src/main/java/org/hypertrace/config/objectstore/ContextuallyIdentifiedObjectStore.java @@ -1,14 +1,10 @@ package org.hypertrace.config.objectstore; import com.google.protobuf.Value; -import io.grpc.Status; import java.util.Optional; import java.util.function.Function; import org.hypertrace.config.service.change.event.api.ConfigChangeEventGenerator; import org.hypertrace.config.service.v1.ConfigServiceGrpc.ConfigServiceBlockingStub; -import org.hypertrace.config.service.v1.ContextSpecificConfig; -import org.hypertrace.config.service.v1.GetConfigRequest; -import org.hypertrace.config.service.v1.GetConfigResponse; import org.hypertrace.core.grpcutils.context.RequestContext; public abstract class ContextuallyIdentifiedObjectStore { @@ -16,26 +12,39 @@ public abstract class ContextuallyIdentifiedObjectStore { private final String resourceNamespace; private final String resourceName; private final Optional configChangeEventGenerator; + private final ClientConfig clientConfig; protected ContextuallyIdentifiedObjectStore( ConfigServiceBlockingStub configServiceBlockingStub, String resourceNamespace, String resourceName, ConfigChangeEventGenerator configChangeEventGenerator) { + this( + configServiceBlockingStub, + resourceNamespace, + resourceName, + configChangeEventGenerator, + ClientConfig.DEFAULT); + } + + protected ContextuallyIdentifiedObjectStore( + ConfigServiceBlockingStub configServiceBlockingStub, + String resourceNamespace, + String resourceName, + ConfigChangeEventGenerator configChangeEventGenerator, + ClientConfig clientConfig) { this.configServiceBlockingStub = configServiceBlockingStub; this.resourceNamespace = resourceNamespace; this.resourceName = resourceName; - this.configChangeEventGenerator = Optional.of(configChangeEventGenerator); + this.configChangeEventGenerator = Optional.ofNullable(configChangeEventGenerator); + this.clientConfig = clientConfig; } protected ContextuallyIdentifiedObjectStore( ConfigServiceBlockingStub configServiceBlockingStub, String resourceNamespace, String resourceName) { - this.configServiceBlockingStub = configServiceBlockingStub; - this.resourceNamespace = resourceNamespace; - this.resourceName = resourceName; - this.configChangeEventGenerator = Optional.empty(); + this(configServiceBlockingStub, resourceNamespace, resourceName, null); } protected abstract Optional buildDataFromValue(Value value); @@ -59,32 +68,9 @@ private IdentifiedObjectStore buildObjectStoreForContext(RequestContext conte } public Optional> getObject(RequestContext context) { - String configContext = this.getConfigContextFromRequestContext(context); - try { - GetConfigResponse getConfigResponse = - context.call( - () -> - this.configServiceBlockingStub.getConfig( - GetConfigRequest.newBuilder() - .setResourceName(this.resourceName) - .setResourceNamespace(this.resourceNamespace) - .addContexts(configContext) - .build())); - - ContextSpecificConfig contextSpecificConfig = - ContextSpecificConfig.newBuilder() - .setContext(configContext) - .setConfig(getConfigResponse.getConfig()) - .setCreationTimestamp(getConfigResponse.getCreationTimestamp()) - .setUpdateTimestamp(getConfigResponse.getUpdateTimestamp()) - .build(); - return ConfigObjectImpl.tryBuild(contextSpecificConfig, this::buildDataFromValue); - } catch (Exception exception) { - if (Status.fromThrowable(exception).equals(Status.NOT_FOUND)) { - return Optional.empty(); - } - throw exception; - } + return this.buildObjectStoreForContext(context) + .getObject(context, this.getConfigContextFromRequestContext(context)) + .map(Function.identity()); } public Optional getData(RequestContext context) { @@ -107,13 +93,17 @@ private class ContextAwareIdentifiedObjectStoreDelegate extends IdentifiedObject private final RequestContext requestContext; ContextAwareIdentifiedObjectStoreDelegate(RequestContext requestContext) { - super(configServiceBlockingStub, resourceNamespace, resourceName); - this.requestContext = requestContext; + this(requestContext, null); } ContextAwareIdentifiedObjectStoreDelegate( RequestContext requestContext, ConfigChangeEventGenerator configChangeEventGenerator) { - super(configServiceBlockingStub, resourceNamespace, resourceName, configChangeEventGenerator); + super( + configServiceBlockingStub, + resourceNamespace, + resourceName, + configChangeEventGenerator, + clientConfig); this.requestContext = requestContext; } diff --git a/object-store/src/main/java/org/hypertrace/config/objectstore/DefaultObjectStore.java b/object-store/src/main/java/org/hypertrace/config/objectstore/DefaultObjectStore.java index c09e29f4..ac84b471 100644 --- a/object-store/src/main/java/org/hypertrace/config/objectstore/DefaultObjectStore.java +++ b/object-store/src/main/java/org/hypertrace/config/objectstore/DefaultObjectStore.java @@ -1,8 +1,10 @@ package org.hypertrace.config.objectstore; import com.google.protobuf.Value; +import io.grpc.Deadline; import io.grpc.Status; import java.util.Optional; +import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.hypertrace.config.service.change.event.api.ConfigChangeEventGenerator; import org.hypertrace.config.service.v1.ConfigServiceGrpc.ConfigServiceBlockingStub; @@ -26,26 +28,39 @@ public abstract class DefaultObjectStore { private final String resourceNamespace; private final String resourceName; private final Optional configChangeEventGeneratorOptional; + private final ClientConfig clientConfig; protected DefaultObjectStore( ConfigServiceBlockingStub configServiceBlockingStub, String resourceNamespace, String resourceName, - ConfigChangeEventGenerator configChangeEventGenerator) { + ConfigChangeEventGenerator configChangeEventGenerator, + ClientConfig clientConfig) { this.configServiceBlockingStub = configServiceBlockingStub; this.resourceNamespace = resourceNamespace; this.resourceName = resourceName; - this.configChangeEventGeneratorOptional = Optional.of(configChangeEventGenerator); + this.configChangeEventGeneratorOptional = Optional.ofNullable(configChangeEventGenerator); + this.clientConfig = clientConfig; + } + + protected DefaultObjectStore( + ConfigServiceBlockingStub configServiceBlockingStub, + String resourceNamespace, + String resourceName, + ConfigChangeEventGenerator configChangeEventGenerator) { + this( + configServiceBlockingStub, + resourceNamespace, + resourceName, + configChangeEventGenerator, + ClientConfig.DEFAULT); } protected DefaultObjectStore( ConfigServiceBlockingStub configServiceBlockingStub, String resourceNamespace, String resourceName) { - this.configServiceBlockingStub = configServiceBlockingStub; - this.resourceNamespace = resourceNamespace; - this.resourceName = resourceName; - this.configChangeEventGeneratorOptional = Optional.empty(); + this(configServiceBlockingStub, resourceNamespace, resourceName, null); } protected abstract Optional buildDataFromValue(Value value); @@ -65,11 +80,13 @@ public Optional> getObject(RequestContext context) { GetConfigResponse getConfigResponse = context.call( () -> - this.configServiceBlockingStub.getConfig( - GetConfigRequest.newBuilder() - .setResourceName(this.resourceName) - .setResourceNamespace(this.resourceNamespace) - .build())); + this.configServiceBlockingStub + .withDeadline(getDeadline()) + .getConfig( + GetConfigRequest.newBuilder() + .setResourceName(this.resourceName) + .setResourceNamespace(this.resourceNamespace) + .build())); return ConfigObjectImpl.tryBuild( getConfigResponse.getConfig(), @@ -90,6 +107,7 @@ public Optional getData(RequestContext context) { context.call( () -> this.configServiceBlockingStub + .withDeadline(getDeadline()) .getConfig( GetConfigRequest.newBuilder() .setResourceName(this.resourceName) @@ -110,12 +128,14 @@ public ConfigObject upsertObject(RequestContext context, T data) { UpsertConfigResponse response = context.call( () -> - this.configServiceBlockingStub.upsertConfig( - UpsertConfigRequest.newBuilder() - .setResourceName(this.resourceName) - .setResourceNamespace(this.resourceNamespace) - .setConfig(this.buildValueFromData(data)) - .build())); + this.configServiceBlockingStub + .withDeadline(getDeadline()) + .upsertConfig( + UpsertConfigRequest.newBuilder() + .setResourceName(this.resourceName) + .setResourceNamespace(this.resourceNamespace) + .setConfig(this.buildValueFromData(data)) + .build())); ConfigObject upsertedObject = ConfigObjectImpl.tryBuild(response, this::buildDataFromValue) @@ -153,11 +173,13 @@ public Optional> deleteObject(RequestContext context) { context .call( () -> - this.configServiceBlockingStub.deleteConfig( - DeleteConfigRequest.newBuilder() - .setResourceName(this.resourceName) - .setResourceNamespace(this.resourceNamespace) - .build())) + this.configServiceBlockingStub + .withDeadline(getDeadline()) + .deleteConfig( + DeleteConfigRequest.newBuilder() + .setResourceName(this.resourceName) + .setResourceNamespace(this.resourceNamespace) + .build())) .getDeletedConfig(); ConfigObject object = ConfigObjectImpl.tryBuild(deletedConfig, this::buildDataFromValue) @@ -176,4 +198,8 @@ public Optional> deleteObject(RequestContext context) { throw exception; } } + + protected Deadline getDeadline() { + return Deadline.after(this.clientConfig.getTimeout().toMillis(), TimeUnit.MILLISECONDS); + } } diff --git a/object-store/src/main/java/org/hypertrace/config/objectstore/IdentifiedObjectStore.java b/object-store/src/main/java/org/hypertrace/config/objectstore/IdentifiedObjectStore.java index ebf68be7..72fdcec0 100644 --- a/object-store/src/main/java/org/hypertrace/config/objectstore/IdentifiedObjectStore.java +++ b/object-store/src/main/java/org/hypertrace/config/objectstore/IdentifiedObjectStore.java @@ -1,9 +1,11 @@ package org.hypertrace.config.objectstore; import com.google.protobuf.Value; +import io.grpc.Deadline; import io.grpc.Status; import java.util.List; import java.util.Optional; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.hypertrace.config.service.change.event.api.ConfigChangeEventGenerator; @@ -34,26 +36,39 @@ public abstract class IdentifiedObjectStore { private final String resourceNamespace; private final String resourceName; private final Optional configChangeEventGeneratorOptional; + private final ClientConfig clientConfig; protected IdentifiedObjectStore( ConfigServiceBlockingStub configServiceBlockingStub, String resourceNamespace, String resourceName, - ConfigChangeEventGenerator configChangeEventGenerator) { + ConfigChangeEventGenerator configChangeEventGenerator, + ClientConfig clientConfig) { this.configServiceBlockingStub = configServiceBlockingStub; this.resourceNamespace = resourceNamespace; this.resourceName = resourceName; - this.configChangeEventGeneratorOptional = Optional.of(configChangeEventGenerator); + this.configChangeEventGeneratorOptional = Optional.ofNullable(configChangeEventGenerator); + this.clientConfig = clientConfig; + } + + protected IdentifiedObjectStore( + ConfigServiceBlockingStub configServiceBlockingStub, + String resourceNamespace, + String resourceName, + ConfigChangeEventGenerator configChangeEventGenerator) { + this( + configServiceBlockingStub, + resourceNamespace, + resourceName, + configChangeEventGenerator, + ClientConfig.DEFAULT); } protected IdentifiedObjectStore( ConfigServiceBlockingStub configServiceBlockingStub, String resourceNamespace, String resourceName) { - this.configServiceBlockingStub = configServiceBlockingStub; - this.resourceNamespace = resourceNamespace; - this.resourceName = resourceName; - this.configChangeEventGeneratorOptional = Optional.empty(); + this(configServiceBlockingStub, resourceNamespace, resourceName, null); } protected abstract Optional buildDataFromValue(Value value); @@ -79,11 +94,13 @@ public List> getAllObjects(RequestContext context) { return context .call( () -> - this.configServiceBlockingStub.getAllConfigs( - GetAllConfigsRequest.newBuilder() - .setResourceName(this.resourceName) - .setResourceNamespace(this.resourceNamespace) - .build())) + this.configServiceBlockingStub + .withDeadline(getDeadline()) + .getAllConfigs( + GetAllConfigsRequest.newBuilder() + .setResourceName(this.resourceName) + .setResourceNamespace(this.resourceNamespace) + .build())) .getContextSpecificConfigsList() .stream() .map( @@ -107,12 +124,14 @@ public Optional> getObject(RequestContext context, Str GetConfigResponse getConfigResponse = context.call( () -> - this.configServiceBlockingStub.getConfig( - GetConfigRequest.newBuilder() - .setResourceName(this.resourceName) - .setResourceNamespace(this.resourceNamespace) - .addContexts(id) - .build())); + this.configServiceBlockingStub + .withDeadline(getDeadline()) + .getConfig( + GetConfigRequest.newBuilder() + .setResourceName(this.resourceName) + .setResourceNamespace(this.resourceNamespace) + .addContexts(id) + .build())); ContextSpecificConfig contextSpecificConfig = ContextSpecificConfig.newBuilder() @@ -138,13 +157,15 @@ public ContextualConfigObject upsertObject(RequestContext context, T data) { UpsertConfigResponse response = context.call( () -> - this.configServiceBlockingStub.upsertConfig( - UpsertConfigRequest.newBuilder() - .setResourceName(this.resourceName) - .setResourceNamespace(this.resourceNamespace) - .setContext(this.getContextFromData(data)) - .setConfig(this.buildValueFromData(data)) - .build())); + this.configServiceBlockingStub + .withDeadline(getDeadline()) + .upsertConfig( + UpsertConfigRequest.newBuilder() + .setResourceName(this.resourceName) + .setResourceNamespace(this.resourceNamespace) + .setContext(this.getContextFromData(data)) + .setConfig(this.buildValueFromData(data)) + .build())); return this.processUpsertResult(context, response) .orElseThrow(Status.INTERNAL::asRuntimeException); @@ -157,12 +178,14 @@ public Optional> deleteObject( requestContext .call( () -> - this.configServiceBlockingStub.deleteConfig( - DeleteConfigRequest.newBuilder() - .setResourceName(this.resourceName) - .setResourceNamespace(this.resourceNamespace) - .setContext(context) - .build())) + this.configServiceBlockingStub + .withDeadline(getDeadline()) + .deleteConfig( + DeleteConfigRequest.newBuilder() + .setResourceName(this.resourceName) + .setResourceNamespace(this.resourceNamespace) + .setContext(context) + .build())) .getDeletedConfig(); return Optional.of(processDeleteResult(requestContext, deletedConfig)); } catch (Exception exception) { @@ -189,8 +212,10 @@ public List> upsertObjects(RequestContext context, Lis return context .call( () -> - this.configServiceBlockingStub.upsertAllConfigs( - UpsertAllConfigsRequest.newBuilder().addAllConfigs(configs).build())) + this.configServiceBlockingStub + .withDeadline(getDeadline()) + .upsertAllConfigs( + UpsertAllConfigsRequest.newBuilder().addAllConfigs(configs).build())) .getUpsertedConfigsList() .stream() .map(upsertedConfig -> this.processUpsertResult(context, upsertedConfig)) @@ -213,8 +238,10 @@ public List> deleteObjects( return requestContext .call( () -> - this.configServiceBlockingStub.deleteConfigs( - DeleteConfigsRequest.newBuilder().addAllConfigs(configsToDelete).build())) + this.configServiceBlockingStub + .withDeadline(getDeadline()) + .deleteConfigs( + DeleteConfigsRequest.newBuilder().addAllConfigs(configsToDelete).build())) .getDeletedConfigsList() .stream() .map(deletedConfig -> processDeleteResult(requestContext, deletedConfig)) @@ -301,4 +328,8 @@ private void tryReportUpdate( }), this.buildValueForChangeEvent(result.getData()))); } + + protected Deadline getDeadline() { + return Deadline.after(this.clientConfig.getTimeout().toMillis(), TimeUnit.MILLISECONDS); + } } diff --git a/object-store/src/main/java/org/hypertrace/config/objectstore/IdentifiedObjectStoreWithFilter.java b/object-store/src/main/java/org/hypertrace/config/objectstore/IdentifiedObjectStoreWithFilter.java index 1a9764c3..eb86d472 100644 --- a/object-store/src/main/java/org/hypertrace/config/objectstore/IdentifiedObjectStoreWithFilter.java +++ b/object-store/src/main/java/org/hypertrace/config/objectstore/IdentifiedObjectStoreWithFilter.java @@ -23,6 +23,20 @@ protected IdentifiedObjectStoreWithFilter( super(configServiceBlockingStub, resourceNamespace, resourceName, configChangeEventGenerator); } + protected IdentifiedObjectStoreWithFilter( + ConfigServiceGrpc.ConfigServiceBlockingStub configServiceBlockingStub, + String resourceNamespace, + String resourceName, + ConfigChangeEventGenerator configChangeEventGenerator, + ClientConfig clientConfig) { + super( + configServiceBlockingStub, + resourceNamespace, + resourceName, + configChangeEventGenerator, + clientConfig); + } + public List> getAllObjects(RequestContext context, F filter) { return getAllObjects(context).stream() .flatMap(configObject -> filterObject(configObject, filter).stream()) diff --git a/object-store/src/test/java/org/hypertrace/config/objectstore/ContextuallyIdentifiedObjectStoreTest.java b/object-store/src/test/java/org/hypertrace/config/objectstore/ContextuallyIdentifiedObjectStoreTest.java index 02b792f0..af8e6c41 100644 --- a/object-store/src/test/java/org/hypertrace/config/objectstore/ContextuallyIdentifiedObjectStoreTest.java +++ b/object-store/src/test/java/org/hypertrace/config/objectstore/ContextuallyIdentifiedObjectStoreTest.java @@ -2,7 +2,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -24,6 +23,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Answers; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -34,13 +34,13 @@ class ContextuallyIdentifiedObjectStoreTest { private static final Instant TEST_CREATE_TIMESTAMP = Instant.ofEpochMilli(20); private static final Instant TEST_UPDATE_TIMESTAMP = Instant.ofEpochMilli(40); - @Mock ConfigServiceBlockingStub mockStub; + @Mock(answer = Answers.RETURNS_SELF) + ConfigServiceBlockingStub mockStub; ContextuallyIdentifiedObjectStore store; @BeforeEach void beforeEach() { - this.mockStub = mock(ConfigServiceBlockingStub.class); this.store = new TestObjectStore(this.mockStub); } @@ -85,8 +85,8 @@ void generatesConfigReadRequestForGetObject() { .build()); assertEquals( Optional.of( - new ConfigObjectImpl<>( - new TestObject("test"), TEST_CREATE_TIMESTAMP, TEST_UPDATE_TIMESTAMP)), + new ContextualConfigObjectImpl<>( + "my-tenant", new TestObject("test"), TEST_CREATE_TIMESTAMP, TEST_UPDATE_TIMESTAMP)), this.store.getObject(RequestContext.forTenantId("my-tenant"))); verify(this.mockStub, times(1)) diff --git a/object-store/src/test/java/org/hypertrace/config/objectstore/DefaultObjectStoreTest.java b/object-store/src/test/java/org/hypertrace/config/objectstore/DefaultObjectStoreTest.java index ef9ad86b..029a5940 100644 --- a/object-store/src/test/java/org/hypertrace/config/objectstore/DefaultObjectStoreTest.java +++ b/object-store/src/test/java/org/hypertrace/config/objectstore/DefaultObjectStoreTest.java @@ -3,7 +3,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -38,7 +37,8 @@ class DefaultObjectStoreTest { private static final Instant TEST_CREATE_TIMESTAMP = Instant.ofEpochMilli(20); private static final Instant TEST_UPDATE_TIMESTAMP = Instant.ofEpochMilli(40); - @Mock ConfigServiceBlockingStub mockStub; + @Mock(answer = Answers.RETURNS_SELF) + ConfigServiceBlockingStub mockStub; @Mock ConfigChangeEventGenerator configChangeEventGenerator; @@ -49,7 +49,6 @@ class DefaultObjectStoreTest { @BeforeEach void beforeEach() { - this.mockStub = mock(ConfigServiceBlockingStub.class); this.store = new TestObjectStore(this.mockStub, configChangeEventGenerator); } diff --git a/object-store/src/test/java/org/hypertrace/config/objectstore/IdentifiedObjectStoreTest.java b/object-store/src/test/java/org/hypertrace/config/objectstore/IdentifiedObjectStoreTest.java index d1116b55..0165fa65 100644 --- a/object-store/src/test/java/org/hypertrace/config/objectstore/IdentifiedObjectStoreTest.java +++ b/object-store/src/test/java/org/hypertrace/config/objectstore/IdentifiedObjectStoreTest.java @@ -3,7 +3,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -74,7 +73,8 @@ class IdentifiedObjectStoreTest { .putFields("rank", Values.of(2))) .build(); - @Mock ConfigServiceBlockingStub mockStub; + @Mock(answer = Answers.RETURNS_SELF) + ConfigServiceBlockingStub mockStub; @Mock ConfigChangeEventGenerator configChangeEventGenerator; @@ -85,7 +85,6 @@ class IdentifiedObjectStoreTest { @BeforeEach void beforeEach() { - this.mockStub = mock(ConfigServiceBlockingStub.class); this.store = new TestObjectStore(this.mockStub, configChangeEventGenerator); } diff --git a/object-store/src/test/java/org/hypertrace/config/objectstore/IdentifiedObjectStoreWithFilterTest.java b/object-store/src/test/java/org/hypertrace/config/objectstore/IdentifiedObjectStoreWithFilterTest.java index a85e5805..06a681c5 100644 --- a/object-store/src/test/java/org/hypertrace/config/objectstore/IdentifiedObjectStoreWithFilterTest.java +++ b/object-store/src/test/java/org/hypertrace/config/objectstore/IdentifiedObjectStoreWithFilterTest.java @@ -4,7 +4,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -114,7 +113,8 @@ private static Value convertToValue(TestInternalObject internalObject) { .build(); } - @Mock ConfigServiceBlockingStub mockStub; + @Mock(answer = Answers.RETURNS_SELF) + ConfigServiceBlockingStub mockStub; @Mock ConfigChangeEventGenerator configChangeEventGenerator; @@ -125,7 +125,6 @@ private static Value convertToValue(TestInternalObject internalObject) { @BeforeEach void beforeEach() { - this.mockStub = mock(ConfigServiceBlockingStub.class); this.store = new TestObjectStore(this.mockStub, configChangeEventGenerator); }