Skip to content

Commit 4bc6f66

Browse files
committed
return provider delegate
Signed-off-by: christian.lutnik <[email protected]>
1 parent e3c1d30 commit 4bc6f66

File tree

7 files changed

+103
-17
lines changed

7 files changed

+103
-17
lines changed

src/main/java/dev/openfeature/sdk/OpenFeatureAPI.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,17 @@ public Client getClient(String domain) {
103103
*/
104104
public Client getClient(String domain, String version) {
105105
return new OpenFeatureClient(
106-
() -> providerRepository.getProvider(domain),
106+
new ProviderAccessor() {
107+
@Override
108+
public FeatureProvider getProvider() {
109+
return providerRepository.getProvider(domain);
110+
}
111+
112+
@Override
113+
public ProviderState getProviderState() {
114+
return providerRepository.getProviderState(domain);
115+
}
116+
},
107117
this,
108118
domain,
109119
version
@@ -416,7 +426,7 @@ void removeHandler(String domain, ProviderEvent event, Consumer<EventDetails> ha
416426
void addHandler(String domain, ProviderEvent event, Consumer<EventDetails> handler) {
417427
try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) {
418428
// if the provider is in the state associated with event, run immediately
419-
if (Optional.ofNullable(this.providerRepository.getProvider(domain).getState())
429+
if (Optional.ofNullable(this.providerRepository.getProviderState(domain))
420430
.orElse(ProviderState.READY).matchesEvent(event)) {
421431
eventSupport.runHandler(handler, EventDetails.builder().domain(domain).build());
422432
}

src/main/java/dev/openfeature/sdk/OpenFeatureClient.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public OpenFeatureClient(
6363

6464
@Override
6565
public ProviderState getProviderState() {
66-
return providerAccessor.getProvider().getState();
66+
return providerAccessor.getProviderState();
6767
}
6868

6969
/**
@@ -123,10 +123,11 @@ private <T> FlagEvaluationDetails<T> evaluateFlag(FlagValueType type, String key
123123
try {
124124
// openfeatureApi.getProvider() must be called once to maintain a consistent reference
125125
provider = providerAccessor.getProvider();
126-
if (ProviderState.NOT_READY.equals(provider.getState())) {
126+
ProviderState state = providerAccessor.getProviderState();
127+
if (ProviderState.NOT_READY.equals(state)) {
127128
throw new ProviderNotReadyError("provider not yet initialized");
128129
}
129-
if (ProviderState.FATAL.equals(provider.getState())) {
130+
if (ProviderState.FATAL.equals(state)) {
130131
throw new FatalError("provider is in an irrecoverable error state");
131132
}
132133

src/main/java/dev/openfeature/sdk/ProviderAccessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/**
44
* Provides access to the future provider for the domain of the client.
55
*/
6-
@FunctionalInterface
76
public interface ProviderAccessor {
87
FeatureProvider getProvider();
8+
ProviderState getProviderState();
99
}

src/main/java/dev/openfeature/sdk/ProviderRepository.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class ProviderRepository {
3434
* Return the default provider.
3535
*/
3636
public FeatureProvider getProvider() {
37-
return defaultProvider.get();
37+
return defaultProvider.get().getDelegate();
3838
}
3939

4040
/**
@@ -44,7 +44,13 @@ public FeatureProvider getProvider() {
4444
* @return A named {@link FeatureProvider}
4545
*/
4646
public FeatureProvider getProvider(String domain) {
47-
return Optional.ofNullable(domain).map(this.providers::get).orElse(this.defaultProvider.get());
47+
if (domain == null) return defaultProvider.get().getDelegate();
48+
StatefulFeatureProvider fromMap = this.providers.get(domain);
49+
if (fromMap == null) {
50+
return this.defaultProvider.get().getDelegate();
51+
} else {
52+
return fromMap.getDelegate();
53+
}
4854
}
4955

5056
public ProviderState getProviderState() {

src/test/java/dev/openfeature/sdk/OpenFeatureAPITest.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,17 @@ void settingTransactionalContextPropagatorToNullErrors() {
8282

8383
@Test
8484
void setEvaluationContextShouldAllowChaining() {
85-
OpenFeatureClient client = new OpenFeatureClient(() -> null, api, "name", "version");
85+
OpenFeatureClient client = new OpenFeatureClient(new ProviderAccessor() {
86+
@Override
87+
public FeatureProvider getProvider() {
88+
return null;
89+
}
90+
91+
@Override
92+
public ProviderState getProviderState() {
93+
return ProviderState.READY;
94+
}
95+
}, api, "name", "version");
8696
EvaluationContext ctx = new ImmutableContext("targeting key", new HashMap<>());
8797
OpenFeatureClient result = client.setEvaluationContext(ctx);
8898
assertEquals(client, result);

src/test/java/dev/openfeature/sdk/OpenFeatureClientTest.java

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,17 @@ void shouldNotThrowExceptionIfHookHasDifferentTypeArgumentThanHookContext() {
4141
when(api.getProvider(any())).thenReturn(provider);
4242
when(api.getHooks()).thenReturn(Arrays.asList(mockBooleanHook(), mockStringHook()));
4343

44-
OpenFeatureClient client = new OpenFeatureClient(() -> provider, api, "name", "version");
44+
OpenFeatureClient client = new OpenFeatureClient(new ProviderAccessor() {
45+
@Override
46+
public FeatureProvider getProvider() {
47+
return provider;
48+
}
49+
50+
@Override
51+
public ProviderState getProviderState() {
52+
return ProviderState.READY;
53+
}
54+
}, api, "name", "version");
4555

4656
FlagEvaluationDetails<Boolean> actual = client.getBooleanDetails("feature key", Boolean.FALSE);
4757

@@ -71,7 +81,17 @@ void mergeContextTest() {
7181
when(api.getProvider(any())).thenReturn(mockProvider);
7282

7383

74-
OpenFeatureClient client = new OpenFeatureClient(() -> mockProvider, api, "name", "version");
84+
OpenFeatureClient client = new OpenFeatureClient(new ProviderAccessor() {
85+
@Override
86+
public FeatureProvider getProvider() {
87+
return mockProvider;
88+
}
89+
90+
@Override
91+
public ProviderState getProviderState() {
92+
return ProviderState.READY;
93+
}
94+
}, api, "name", "version");
7595
client.setEvaluationContext(ctx);
7696

7797
FlagEvaluationDetails<Boolean> result = client.getBooleanDetails(flag, defaultValue);
@@ -83,7 +103,17 @@ void mergeContextTest() {
83103
@DisplayName("addHooks should allow chaining by returning the same client instance")
84104
void addHooksShouldAllowChaining() {
85105
OpenFeatureAPI api = mock(OpenFeatureAPI.class);
86-
OpenFeatureClient client = new OpenFeatureClient(() -> null, api, "name", "version");
106+
OpenFeatureClient client = new OpenFeatureClient(new ProviderAccessor() {
107+
@Override
108+
public FeatureProvider getProvider() {
109+
return null;
110+
}
111+
112+
@Override
113+
public ProviderState getProviderState() {
114+
return ProviderState.READY;
115+
}
116+
}, api, "name", "version");
87117
Hook<?> hook1 = Mockito.mock(Hook.class);
88118
Hook<?> hook2 = Mockito.mock(Hook.class);
89119

@@ -95,7 +125,17 @@ void addHooksShouldAllowChaining() {
95125
@DisplayName("setEvaluationContext should allow chaining by returning the same client instance")
96126
void setEvaluationContextShouldAllowChaining() {
97127
OpenFeatureAPI api = mock(OpenFeatureAPI.class);
98-
OpenFeatureClient client = new OpenFeatureClient(() -> null, api, "name", "version");
128+
OpenFeatureClient client = new OpenFeatureClient(new ProviderAccessor() {
129+
@Override
130+
public FeatureProvider getProvider() {
131+
return null;
132+
}
133+
134+
@Override
135+
public ProviderState getProviderState() {
136+
return ProviderState.READY;
137+
}
138+
}, api, "name", "version");
99139
EvaluationContext ctx = new ImmutableContext("targeting key", new HashMap<>());
100140

101141
OpenFeatureClient result = client.setEvaluationContext(ctx);
@@ -107,7 +147,17 @@ void setEvaluationContextShouldAllowChaining() {
107147
void shouldNotCallEvaluationMethodsWhenProviderIsInFatalErrorState() {
108148
MockProvider mockProvider = new MockProvider(ProviderState.FATAL);
109149
OpenFeatureAPI api = mock(OpenFeatureAPI.class);
110-
OpenFeatureClient client = new OpenFeatureClient(() -> mockProvider, api, "name", "version");
150+
OpenFeatureClient client = new OpenFeatureClient(new ProviderAccessor() {
151+
@Override
152+
public FeatureProvider getProvider() {
153+
return mockProvider;
154+
}
155+
156+
@Override
157+
public ProviderState getProviderState() {
158+
return ProviderState.FATAL;
159+
}
160+
}, api, "name", "version");
111161
FlagEvaluationDetails<Boolean> details = client.getBooleanDetails("key", true);
112162

113163
assertThat(mockProvider.isEvaluationCalled()).isFalse();
@@ -119,7 +169,17 @@ void shouldNotCallEvaluationMethodsWhenProviderIsInFatalErrorState() {
119169
void shouldNotCallEvaluationMethodsWhenProviderIsInNotReadyState() {
120170
MockProvider mockProvider = new MockProvider(ProviderState.NOT_READY);
121171
OpenFeatureAPI api = mock(OpenFeatureAPI.class);
122-
OpenFeatureClient client = new OpenFeatureClient(() -> mockProvider, api, "name", "version");
172+
OpenFeatureClient client = new OpenFeatureClient(new ProviderAccessor() {
173+
@Override
174+
public FeatureProvider getProvider() {
175+
return mockProvider;
176+
}
177+
178+
@Override
179+
public ProviderState getProviderState() {
180+
return ProviderState.NOT_READY;
181+
}
182+
}, api, "name", "version");
123183
FlagEvaluationDetails<Boolean> details = client.getBooleanDetails("key", true);
124184

125185
assertThat(mockProvider.isEvaluationCalled()).isFalse();

src/test/java/dev/openfeature/sdk/ProviderRepositoryTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ void shouldRejectNullAsDefaultProvider() {
5555
@Test
5656
@DisplayName("should have NoOpProvider set as default on initialization")
5757
void shouldHaveNoOpProviderSetAsDefaultOnInitialization() {
58-
assertThat(((StatefulFeatureProvider)providerRepository.getProvider()).getDelegate())
59-
.isInstanceOf(NoOpProvider.class);
58+
assertThat(providerRepository.getProvider()).isInstanceOf(NoOpProvider.class);
6059
}
6160

6261
@Test

0 commit comments

Comments
 (0)