Skip to content
This repository was archived by the owner on May 30, 2024. It is now read-only.

Commit cc9aa41

Browse files
LaunchDarklyReleaseBoteli-darklyLaunchDarklyReleaseBotaengelbergantonmos
authored
prepare 7.2.6 release (#322)
## [7.2.6] - 2024-02-09 ### Added: - LDReactorClient to adapt LDClient to reactive streams. --------- Co-authored-by: Eli Bishop <[email protected]> Co-authored-by: LaunchDarklyReleaseBot <[email protected]> Co-authored-by: Alex Engelberg <[email protected]> Co-authored-by: Anton Mostovoy <[email protected]> Co-authored-by: LaunchDarklyCI <[email protected]> Co-authored-by: LaunchDarklyCI <[email protected]> Co-authored-by: Gavin Whelan <[email protected]> Co-authored-by: ssrm <[email protected]> Co-authored-by: Harpo Roeder <[email protected]> Co-authored-by: Ben Woskow <[email protected]> Co-authored-by: Elliot <[email protected]> Co-authored-by: Robert J. Neal <[email protected]> Co-authored-by: Robert J. Neal <[email protected]> Co-authored-by: Sam Stokes <[email protected]> Co-authored-by: Ember Stevens <[email protected]> Co-authored-by: ember-stevens <[email protected]> Co-authored-by: Alex Engelberg <[email protected]> Co-authored-by: Louis Chan <[email protected]> Co-authored-by: Louis Chan <[email protected]> Co-authored-by: Todd Anderson <[email protected]> Co-authored-by: tanderson-ld <[email protected]> Co-authored-by: Matthew M. Keeler <[email protected]> Co-authored-by: ld-repository-standards[bot] <113625520+ld-repository-standards[bot]@users.noreply.github.com> Co-authored-by: Kane Parkinson <[email protected]> Co-authored-by: Ryan Lamb <[email protected]>
1 parent 508b895 commit cc9aa41

File tree

5 files changed

+450
-2
lines changed

5 files changed

+450
-2
lines changed

build.gradle

+9-2
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ ext.versions = [
7777
"launchdarklyLogging": "1.1.0",
7878
"okhttp": "4.9.3", // specify this for the SDK build instead of relying on the transitive dependency from okhttp-eventsource
7979
"okhttpEventsource": "4.1.0",
80+
"reactorCore":"3.3.22.RELEASE",
8081
"slf4j": "1.7.21",
8182
"snakeyaml": "2.0",
8283
"jedis": "2.9.0",
@@ -142,7 +143,8 @@ libraries.internal = [
142143
libraries.optional = [
143144
"com.fasterxml.jackson.core:jackson-core:${versions.jackson}",
144145
"com.fasterxml.jackson.core:jackson-databind:${versions.jackson}",
145-
"org.slf4j:slf4j-api:${versions.slf4j}"
146+
"org.slf4j:slf4j-api:${versions.slf4j}",
147+
"io.projectreactor:reactor-core:${versions.reactorCore}",
146148
]
147149

148150
// Add dependencies to "libraries.test" that are used only in unit tests.
@@ -152,7 +154,8 @@ libraries.test = [
152154
"junit:junit:4.12",
153155
"com.fasterxml.jackson.core:jackson-core:${versions.jackson}",
154156
"com.fasterxml.jackson.core:jackson-databind:${versions.jackson}",
155-
"com.launchdarkly:test-helpers:2.0.1"
157+
"com.launchdarkly:test-helpers:2.0.1",
158+
"io.projectreactor:reactor-core:${versions.reactorCore}", // this is to make javadoc happy when using the test classpath
156159
]
157160

158161
configurations {
@@ -186,6 +189,10 @@ task generateJava(type: Copy) {
186189
filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: [VERSION: version.toString()])
187190
}
188191

192+
compileJava {
193+
classpath = configurations.internal + configurations.optional
194+
}
195+
189196
compileJava.dependsOn 'generateJava'
190197

191198
jar {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
package com.launchdarkly.sdk.server.integrations.reactor;
2+
3+
import com.launchdarkly.sdk.EvaluationDetail;
4+
import com.launchdarkly.sdk.LDContext;
5+
import com.launchdarkly.sdk.LDValue;
6+
import com.launchdarkly.sdk.server.FeatureFlagsState;
7+
import com.launchdarkly.sdk.server.FlagsStateOption;
8+
import com.launchdarkly.sdk.server.LDClient;
9+
import com.launchdarkly.sdk.server.LDConfig;
10+
import com.launchdarkly.sdk.server.interfaces.BigSegmentStoreStatusProvider;
11+
import com.launchdarkly.sdk.server.interfaces.DataSourceStatusProvider;
12+
import com.launchdarkly.sdk.server.interfaces.DataStoreStatusProvider;
13+
import com.launchdarkly.sdk.server.interfaces.FlagTracker;
14+
15+
import java.util.concurrent.Callable;
16+
17+
import reactor.core.publisher.Mono;
18+
import reactor.core.scheduler.Scheduler;
19+
20+
/**
21+
* A thin wrapper of the {@link LDClient} that aims to adapt it to reactive stream programming.
22+
*
23+
* Methods that are potentially long running or that use IO have been wrapped to return {@link Mono}s and will be
24+
* executed on the scheduler provided. Methods that do not have a risk of blocking have not been wrapped and are
25+
* pass through.
26+
*/
27+
public final class LDReactorClient implements LDReactorClientInterface {
28+
29+
private final LDClient wrappedClient;
30+
private final Scheduler scheduler;
31+
32+
/**
33+
* Creates a client that uses the provided scheduler to execute functionality in a non-blocking manner.
34+
*
35+
* @param sdkKey the SDK key for your LaunchDarkly environment
36+
* @param scheduler that will execute wrapped client methods
37+
*/
38+
public LDReactorClient(String sdkKey, Scheduler scheduler) {
39+
this.wrappedClient = new LDClient(sdkKey);
40+
this.scheduler = scheduler;
41+
}
42+
43+
/**
44+
* Creates a client that uses the provided scheduler to execute functionality in a non-blocking manner.
45+
*
46+
* @param sdkKey the SDK key for your LaunchDarkly environment
47+
* @param config a client configuration object
48+
* @param scheduler that will execute wrapped client methods
49+
*/
50+
public LDReactorClient(String sdkKey, LDConfig config, Scheduler scheduler) {
51+
this.wrappedClient = new LDClient(sdkKey, config);
52+
this.scheduler = scheduler;
53+
}
54+
55+
@Override
56+
public boolean isInitialized() {
57+
return wrappedClient.isInitialized();
58+
}
59+
60+
@Override
61+
public void track(String eventName, LDContext context) {
62+
wrappedClient.track(eventName, context);
63+
}
64+
65+
@Override
66+
public void trackData(String eventName, LDContext context, LDValue data) {
67+
wrappedClient.trackData(eventName, context, data);
68+
}
69+
70+
@Override
71+
public void trackMetric(String eventName, LDContext context, LDValue data, double metricValue) {
72+
wrappedClient.trackMetric(eventName, context, data, metricValue);
73+
}
74+
75+
@Override
76+
public void identify(LDContext context) {
77+
wrappedClient.identify(context);
78+
}
79+
80+
@Override
81+
public Mono<FeatureFlagsState> allFlagsState(LDContext context, FlagsStateOption... options) {
82+
return Mono.fromCallable(() -> wrappedClient.allFlagsState(context, options)).subscribeOn(this.scheduler);
83+
}
84+
85+
@Override
86+
public Mono<Boolean> boolVariation(String featureKey, LDContext context, boolean defaultValue) {
87+
return Mono.fromCallable(() -> wrappedClient.boolVariation(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
88+
}
89+
90+
@Override
91+
public Mono<Integer> intVariation(String featureKey, LDContext context, int defaultValue) {
92+
return Mono.fromCallable(() -> wrappedClient.intVariation(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
93+
}
94+
95+
@Override
96+
public Mono<Double> doubleVariation(String featureKey, LDContext context, double defaultValue) {
97+
return Mono.fromCallable(() -> wrappedClient.doubleVariation(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
98+
}
99+
100+
@Override
101+
public Mono<String> stringVariation(String featureKey, LDContext context, String defaultValue) {
102+
return Mono.fromCallable(() -> wrappedClient.stringVariation(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
103+
}
104+
105+
@Override
106+
public Mono<LDValue> jsonValueVariation(String featureKey, LDContext context, LDValue defaultValue) {
107+
return Mono.fromCallable(() -> wrappedClient.jsonValueVariation(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
108+
}
109+
110+
@Override
111+
public Mono<EvaluationDetail<Boolean>> boolVariationDetail(String featureKey, LDContext context, boolean defaultValue) {
112+
return Mono.fromCallable(() -> wrappedClient.boolVariationDetail(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
113+
}
114+
115+
@Override
116+
public Mono<EvaluationDetail<Integer>> intVariationDetail(String featureKey, LDContext context, int defaultValue) {
117+
return Mono.fromCallable(() -> wrappedClient.intVariationDetail(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
118+
}
119+
120+
@Override
121+
public Mono<EvaluationDetail<Double>> doubleVariationDetail(String featureKey, LDContext context, double defaultValue) {
122+
return Mono.fromCallable(() -> wrappedClient.doubleVariationDetail(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
123+
}
124+
125+
@Override
126+
public Mono<EvaluationDetail<String>> stringVariationDetail(String featureKey, LDContext context, String defaultValue) {
127+
return Mono.fromCallable(() -> wrappedClient.stringVariationDetail(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
128+
}
129+
130+
@Override
131+
public Mono<EvaluationDetail<LDValue>> jsonValueVariationDetail(String featureKey, LDContext context, LDValue defaultValue) {
132+
return Mono.fromCallable(() -> wrappedClient.jsonValueVariationDetail(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
133+
}
134+
135+
@Override
136+
public boolean isFlagKnown(String featureKey) {
137+
return wrappedClient.isFlagKnown(featureKey);
138+
}
139+
140+
@Override
141+
public FlagTracker getFlagTracker() {
142+
return wrappedClient.getFlagTracker();
143+
}
144+
145+
@Override
146+
public BigSegmentStoreStatusProvider getBigSegmentStoreStatusProvider() {
147+
return wrappedClient.getBigSegmentStoreStatusProvider();
148+
}
149+
150+
@Override
151+
public DataStoreStatusProvider getDataStoreStatusProvider() {
152+
return wrappedClient.getDataStoreStatusProvider();
153+
}
154+
155+
@Override
156+
public DataSourceStatusProvider getDataSourceStatusProvider() {
157+
return wrappedClient.getDataSourceStatusProvider();
158+
}
159+
160+
@Override
161+
public Mono<Void> close() {
162+
return Mono.fromCallable((Callable<Void>) () -> {
163+
wrappedClient.close();
164+
return null;
165+
}).subscribeOn(this.scheduler);
166+
}
167+
168+
@Override
169+
public void flush() {
170+
wrappedClient.flush();
171+
}
172+
173+
@Override
174+
public boolean isOffline() {
175+
return wrappedClient.isOffline();
176+
}
177+
178+
@Override
179+
public String secureModeHash(LDContext context) {
180+
return wrappedClient.secureModeHash(context);
181+
}
182+
183+
@Override
184+
public String version() {
185+
return wrappedClient.version();
186+
}
187+
}

0 commit comments

Comments
 (0)