Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@
</dependency>

<!-- test -->
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit-junit5</artifactId>
<version>1.4.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
Expand Down Expand Up @@ -242,12 +249,14 @@
<ignoredUnusedDeclaredDependencies>
<ignoredUnusedDeclaredDependency>com.github.spotbugs:*</ignoredUnusedDeclaredDependency>
<ignoredUnusedDeclaredDependency>org.junit*</ignoredUnusedDeclaredDependency>
<ignoredUnusedDeclaredDependency>com.tngtech.archunit*</ignoredUnusedDeclaredDependency>
<ignoredUnusedDeclaredDependency>org.simplify4u:slf4j2-mock*</ignoredUnusedDeclaredDependency>
</ignoredUnusedDeclaredDependencies>
<ignoredDependencies>
<ignoredDependency>com.google.guava*</ignoredDependency>
<ignoredDependency>io.cucumber*</ignoredDependency>
<ignoredDependency>org.junit*</ignoredDependency>
<ignoredDependency>com.tngtech.archunit*</ignoredDependency>
<ignoredDependency>com.google.code.findbugs*</ignoredDependency>
<ignoredDependency>com.github.spotbugs*</ignoredDependency>
<ignoredDependency>org.simplify4u:slf4j-mock-common:*</ignoredDependency>
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class OpenFeatureAPI implements EventBus<OpenFeatureAPI> {

protected OpenFeatureAPI() {
apiHooks = new ArrayList<>();
providerRepository = new ProviderRepository();
providerRepository = new ProviderRepository(this);
eventSupport = new EventSupport();
transactionContextPropagator = new NoOpTransactionContextPropagator();
}
Expand Down Expand Up @@ -333,7 +333,7 @@ public void shutdown() {
providerRepository.shutdown();
eventSupport.shutdown();

providerRepository = new ProviderRepository();
providerRepository = new ProviderRepository(this);
eventSupport = new EventSupport();
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/dev/openfeature/sdk/OpenFeatureClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ public Client onProviderStale(Consumer<EventDetails> handler) {
*/
@Override
public Client on(ProviderEvent event, Consumer<EventDetails> handler) {
OpenFeatureAPI.getInstance().addHandler(domain, event, handler);
openfeatureApi.addHandler(domain, event, handler);
return this;
}

Expand All @@ -516,7 +516,7 @@ public Client on(ProviderEvent event, Consumer<EventDetails> handler) {
*/
@Override
public Client removeHandler(ProviderEvent event, Consumer<EventDetails> handler) {
OpenFeatureAPI.getInstance().removeHandler(domain, event, handler);
openfeatureApi.removeHandler(domain, event, handler);
return this;
}
}
7 changes: 6 additions & 1 deletion src/main/java/dev/openfeature/sdk/ProviderRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ class ProviderRepository {
return thread;
});
private final Object registerStateManagerLock = new Object();
private final OpenFeatureAPI openFeatureAPI;

public ProviderRepository(OpenFeatureAPI openFeatureAPI) {
this.openFeatureAPI = openFeatureAPI;
}

FeatureProviderStateManager getFeatureProviderStateManager() {
return defaultStateManger.get();
Expand Down Expand Up @@ -205,7 +210,7 @@ private void initializeProvider(
FeatureProviderStateManager oldManager) {
try {
if (ProviderState.NOT_READY.equals(newManager.getState())) {
newManager.initialize(OpenFeatureAPI.getInstance().getEvaluationContext());
newManager.initialize(openFeatureAPI.getEvaluationContext());
afterInit.accept(newManager.getProvider());
}
shutDownOld(oldManager, afterShutdown);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package dev.openfeature.sdk;

import dev.openfeature.sdk.exceptions.FlagNotFoundError;

public class AlwaysBrokenWithDetailsProvider implements FeatureProvider {

private final String name = "always broken with details";

@Override
public Metadata getMetadata() {
return () -> {
throw new FlagNotFoundError(TestConstants.BROKEN_MESSAGE);
};
return () -> name;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import dev.openfeature.sdk.exceptions.FlagNotFoundError;

public class AlwaysBrokenProvider implements FeatureProvider {
public class AlwaysBrokenWithExceptionProvider implements FeatureProvider {

private final String name = "always broken";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@

import static org.junit.jupiter.api.Assertions.*;

import dev.openfeature.sdk.testutils.FeatureProviderTestUtils;
import org.junit.jupiter.api.Test;

class ClientProviderMappingTest {

@Test
void clientProviderTest() {
OpenFeatureAPI api = OpenFeatureAPI.getInstance();
OpenFeatureAPI api = new OpenFeatureAPI();

FeatureProviderTestUtils.setFeatureProvider("client1", new DoSomethingProvider());
FeatureProviderTestUtils.setFeatureProvider("client2", new NoOpProvider());
api.setProviderAndWait("client1", new DoSomethingProvider());
api.setProviderAndWait("client2", new NoOpProvider());

Client c1 = api.getClient("client1");
Client c2 = api.getClient("client2");
Expand Down
28 changes: 13 additions & 15 deletions src/test/java/dev/openfeature/sdk/DeveloperExperienceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,27 @@
import static org.mockito.Mockito.verify;

import dev.openfeature.sdk.fixtures.HookFixtures;
import dev.openfeature.sdk.testutils.FeatureProviderTestUtils;
import dev.openfeature.sdk.testutils.TestEventsProvider;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import lombok.SneakyThrows;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class DeveloperExperienceTest implements HookFixtures {
transient String flagKey = "mykey";
private OpenFeatureAPI api;

@BeforeEach
public void setUp() throws Exception {
api = new OpenFeatureAPI();
}

@Test
void simpleBooleanFlag() {
OpenFeatureAPI api = OpenFeatureAPI.getInstance();
api.setProviderAndWait(new TestEventsProvider());
Client client = api.getClient();
Boolean retval = client.getBooleanValue(flagKey, false);
Expand All @@ -34,7 +39,6 @@ void simpleBooleanFlag() {
void clientHooks() {
Hook<Boolean> exampleHook = mockBooleanHook();

OpenFeatureAPI api = OpenFeatureAPI.getInstance();
api.setProviderAndWait(new TestEventsProvider());
Client client = api.getClient();
client.addHooks(exampleHook);
Expand All @@ -48,7 +52,6 @@ void evalHooks() {
Hook<Boolean> clientHook = mockBooleanHook();
Hook<Boolean> evalHook = mockBooleanHook();

OpenFeatureAPI api = OpenFeatureAPI.getInstance();
api.setProviderAndWait(new TestEventsProvider());
Client client = api.getClient();
client.addHooks(clientHook);
Expand All @@ -69,7 +72,6 @@ void evalHooks() {
@Test
void providingContext() {

OpenFeatureAPI api = OpenFeatureAPI.getInstance();
api.setProviderAndWait(new TestEventsProvider());
Client client = api.getClient();
Map<String, Value> attributes = new HashMap<>();
Expand All @@ -86,8 +88,7 @@ void providingContext() {

@Test
void brokenProvider() {
OpenFeatureAPI api = OpenFeatureAPI.getInstance();
FeatureProviderTestUtils.setFeatureProvider(new AlwaysBrokenProvider());
api.setProviderAndWait(new AlwaysBrokenWithExceptionProvider());
Client client = api.getClient();
FlagEvaluationDetails<Boolean> retval = client.getBooleanDetails(flagKey, false);
assertEquals(ErrorCode.FLAG_NOT_FOUND, retval.getErrorCode());
Expand All @@ -99,23 +100,24 @@ void brokenProvider() {
@Test
void providerLockedPerTransaction() {

final String defaultValue = "string-value";
final OpenFeatureAPI api = new OpenFeatureAPI();

class MutatingHook implements Hook {

@Override
@SneakyThrows
// change the provider during a before hook - this should not impact the evaluation in progress
public Optional before(HookContext ctx, Map hints) {

FeatureProviderTestUtils.setFeatureProvider(TestEventsProvider.newInitializedTestEventsProvider());
api.setProviderAndWait(TestEventsProvider.newInitializedTestEventsProvider());

return Optional.empty();
}
}

final String defaultValue = "string-value";
final OpenFeatureAPI api = OpenFeatureAPI.getInstance();
final Client client = api.getClient();
FeatureProviderTestUtils.setFeatureProvider(new DoSomethingProvider());
api.setProviderAndWait(new DoSomethingProvider());
api.addHooks(new MutatingHook());

// if provider is changed during an evaluation transaction it should proceed with the original provider
Expand All @@ -132,7 +134,6 @@ public Optional before(HookContext ctx, Map hints) {
@Test
void setProviderAndWaitShouldPutTheProviderInReadyState() {
String domain = "domain";
OpenFeatureAPI api = OpenFeatureAPI.getInstance();
api.setProviderAndWait(domain, new TestEventsProvider());
Client client = api.getClient(domain);
assertThat(client.getProviderState()).isEqualTo(ProviderState.READY);
Expand All @@ -145,7 +146,6 @@ void setProviderAndWaitShouldPutTheProviderInReadyState() {
@Test
void shouldPutTheProviderInStateErrorAfterEmittingErrorEvent() {
String domain = "domain";
OpenFeatureAPI api = OpenFeatureAPI.getInstance();
TestEventsProvider provider = new TestEventsProvider();
api.setProviderAndWait(domain, provider);
Client client = api.getClient(domain);
Expand All @@ -161,7 +161,6 @@ void shouldPutTheProviderInStateErrorAfterEmittingErrorEvent() {
@Test
void shouldPutTheProviderInStateStaleAfterEmittingStaleEvent() {
String domain = "domain";
OpenFeatureAPI api = OpenFeatureAPI.getInstance();
TestEventsProvider provider = new TestEventsProvider();
api.setProviderAndWait(domain, provider);
Client client = api.getClient(domain);
Expand All @@ -177,7 +176,6 @@ void shouldPutTheProviderInStateStaleAfterEmittingStaleEvent() {
@Test
void shouldPutTheProviderInStateReadyAfterEmittingReadyEvent() {
String domain = "domain";
OpenFeatureAPI api = OpenFeatureAPI.getInstance();
TestEventsProvider provider = new TestEventsProvider();
api.setProviderAndWait(domain, provider);
Client client = api.getClient(domain);
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/dev/openfeature/sdk/EventProviderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void setup() {

@AfterAll
public static void resetDefaultProvider() {
OpenFeatureAPI.getInstance().setProviderAndWait(new NoOpProvider());
new OpenFeatureAPI().setProviderAndWait(new NoOpProvider());
}

@Test
Expand Down Expand Up @@ -91,7 +91,7 @@ void doesNotThrowWhenOnEmitSame() {
@DisplayName("should not deadlock on emit called during emit")
void doesNotDeadlockOnEmitStackedCalls() {
TestStackedEmitCallsProvider provider = new TestStackedEmitCallsProvider();
OpenFeatureAPI.getInstance().setProviderAndWait(provider);
new OpenFeatureAPI().setProviderAndWait(provider);
}

static class TestEventProvider extends EventProvider {
Expand Down
Loading
Loading