1
1
package dev .openfeature .sdk ;
2
2
3
- import dev .openfeature .sdk .internal .AutoCloseableLock ;
4
- import dev .openfeature .sdk .internal .AutoCloseableReentrantReadWriteLock ;
5
- import lombok .extern .slf4j .Slf4j ;
6
-
7
- import javax .annotation .Nullable ;
8
3
import java .util .ArrayList ;
9
4
import java .util .Arrays ;
10
5
import java .util .List ;
6
+ import java .util .function .Consumer ;
7
+
8
+ import javax .annotation .Nullable ;
9
+
10
+ import dev .openfeature .sdk .internal .AutoCloseableLock ;
11
+ import dev .openfeature .sdk .internal .AutoCloseableReentrantReadWriteLock ;
12
+ import lombok .extern .slf4j .Slf4j ;
11
13
12
14
/**
13
- * A global singleton which holds base configuration for the OpenFeature library.
15
+ * A global singleton which holds base configuration for the OpenFeature
16
+ * library.
14
17
* Configuration here will be shared across all {@link Client}s.
15
18
*/
16
19
@ Slf4j
17
- public class OpenFeatureAPI {
20
+ public class OpenFeatureAPI implements EventHandling < OpenFeatureAPI > {
18
21
// package-private multi-read/single-write lock
19
22
static AutoCloseableReentrantReadWriteLock hooksLock = new AutoCloseableReentrantReadWriteLock ();
20
23
static AutoCloseableReentrantReadWriteLock contextLock = new AutoCloseableReentrantReadWriteLock ();
21
-
24
+ private EvaluationContext evaluationContext ;
22
25
private final List <Hook > apiHooks ;
23
-
24
26
private ProviderRepository providerRepository = new ProviderRepository ();
25
- private EvaluationContext evaluationContext ;
27
+ final EventEmitter emitter = new EventEmitter () ;
26
28
27
29
protected OpenFeatureAPI () {
28
30
this .apiHooks = new ArrayList <>();
@@ -49,16 +51,29 @@ public Metadata getProviderMetadata(String clientName) {
49
51
return getProvider (clientName ).getMetadata ();
50
52
}
51
53
54
+ /**
55
+ * {@inheritDoc}
56
+ */
52
57
public Client getClient () {
53
58
return getClient (null , null );
54
59
}
55
60
61
+ /**
62
+ * {@inheritDoc}
63
+ */
56
64
public Client getClient (@ Nullable String name ) {
57
65
return getClient (name , null );
58
66
}
59
67
68
+ /**
69
+ * {@inheritDoc}
70
+ */
60
71
public Client getClient (@ Nullable String name , @ Nullable String version ) {
61
- return new OpenFeatureClient (this , name , version );
72
+ return new OpenFeatureClient (this ,
73
+ () -> this .providerRepository .getProvider (name ).getState (),
74
+ this .providerRepository .getAndCacheEmitter (name ),
75
+ name ,
76
+ version );
62
77
}
63
78
64
79
/**
@@ -83,6 +98,7 @@ public EvaluationContext getEvaluationContext() {
83
98
* Set the default provider.
84
99
*/
85
100
public void setProvider (FeatureProvider provider ) {
101
+ propagateEventsIfSupported (provider , null );
86
102
providerRepository .setProvider (provider );
87
103
}
88
104
@@ -93,6 +109,7 @@ public void setProvider(FeatureProvider provider) {
93
109
* @param provider The provider to set.
94
110
*/
95
111
public void setProvider (String clientName , FeatureProvider provider ) {
112
+ propagateEventsIfSupported (provider , clientName );
96
113
providerRepository .setProvider (clientName , provider );
97
114
}
98
115
@@ -144,6 +161,37 @@ public void shutdown() {
144
161
providerRepository .shutdown ();
145
162
}
146
163
164
+ @ Override
165
+ public OpenFeatureAPI onProviderReady (Consumer <EventDetails > handler ) {
166
+ return this .on (ProviderEvent .PROVIDER_READY , handler );
167
+ }
168
+
169
+ @ Override
170
+ public OpenFeatureAPI onProviderConfigurationChanged (Consumer <EventDetails > handler ) {
171
+ return this .on (ProviderEvent .PROVIDER_CONFIGURATION_CHANGED , handler );
172
+ }
173
+
174
+ @ Override
175
+ public OpenFeatureAPI onProviderError (Consumer <EventDetails > handler ) {
176
+ return this .on (ProviderEvent .PROVIDER_ERROR , handler );
177
+ }
178
+
179
+ @ Override
180
+ public OpenFeatureAPI onProviderStale (Consumer <EventDetails > handler ) {
181
+ return this .on (ProviderEvent .PROVIDER_STALE , handler );
182
+ }
183
+
184
+ private OpenFeatureAPI on (ProviderEvent event , Consumer <EventDetails > consumer ) {
185
+ this .emitter .addHandler (event , consumer );
186
+ return this ;
187
+ }
188
+
189
+ private void propagateEventsIfSupported (FeatureProvider provider , @ Nullable String clientName ) {
190
+ if (EventProvider .isEventProvider (provider )) {
191
+ this .emitter .forwardEvents (((EventProvider ) provider ).getEventEmitter (), clientName );
192
+ }
193
+ }
194
+
147
195
/**
148
196
* This method is only here for testing as otherwise all tests after the API shutdown test would fail.
149
197
*/
0 commit comments