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

Commit

Permalink
prepare 7.2.6 release (#322)
Browse files Browse the repository at this point in the history
## [7.2.6] - 2024-02-09
### Added:
- LDReactorClient to adapt LDClient to reactive streams.

---------

Co-authored-by: Eli Bishop <eli@launchdarkly.com>
Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com>
Co-authored-by: Alex Engelberg <aengelberg@launchdarkly.com>
Co-authored-by: Anton Mostovoy <anton@mostovoy.net>
Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com>
Co-authored-by: LaunchDarklyCI <LaunchDarklyCI@users.noreply.github.com>
Co-authored-by: Gavin Whelan <gwhelan@launchdarkly.com>
Co-authored-by: ssrm <ssrm@users.noreply.github.com>
Co-authored-by: Harpo Roeder <hroeder@launchdarkly.com>
Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com>
Co-authored-by: Elliot <35050275+Apache-HB@users.noreply.github.com>
Co-authored-by: Robert J. Neal <rneal@launchdarkly.com>
Co-authored-by: Robert J. Neal <robertjneal@users.noreply.github.com>
Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>
Co-authored-by: Ember Stevens <ember.stevens@launchdarkly.com>
Co-authored-by: ember-stevens <79482775+ember-stevens@users.noreply.github.com>
Co-authored-by: Alex Engelberg <alex.benjamin.engelberg@gmail.com>
Co-authored-by: Louis Chan <lchan@launchdarkly.com>
Co-authored-by: Louis Chan <91093020+louis-launchdarkly@users.noreply.github.com>
Co-authored-by: Todd Anderson <tanderson@launchdarkly.com>
Co-authored-by: tanderson-ld <127344469+tanderson-ld@users.noreply.github.com>
Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>
Co-authored-by: ld-repository-standards[bot] <113625520+ld-repository-standards[bot]@users.noreply.github.com>
Co-authored-by: Kane Parkinson <93555788+kparkinson-ld@users.noreply.github.com>
Co-authored-by: Ryan Lamb <4955475+kinyoklion@users.noreply.github.com>
  • Loading branch information
26 people authored Feb 9, 2024
1 parent 508b895 commit cc9aa41
Show file tree
Hide file tree
Showing 5 changed files with 450 additions and 2 deletions.
11 changes: 9 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ ext.versions = [
"launchdarklyLogging": "1.1.0",
"okhttp": "4.9.3", // specify this for the SDK build instead of relying on the transitive dependency from okhttp-eventsource
"okhttpEventsource": "4.1.0",
"reactorCore":"3.3.22.RELEASE",
"slf4j": "1.7.21",
"snakeyaml": "2.0",
"jedis": "2.9.0",
Expand Down Expand Up @@ -142,7 +143,8 @@ libraries.internal = [
libraries.optional = [
"com.fasterxml.jackson.core:jackson-core:${versions.jackson}",
"com.fasterxml.jackson.core:jackson-databind:${versions.jackson}",
"org.slf4j:slf4j-api:${versions.slf4j}"
"org.slf4j:slf4j-api:${versions.slf4j}",
"io.projectreactor:reactor-core:${versions.reactorCore}",
]

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

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

compileJava {
classpath = configurations.internal + configurations.optional
}

compileJava.dependsOn 'generateJava'

jar {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package com.launchdarkly.sdk.server.integrations.reactor;

import com.launchdarkly.sdk.EvaluationDetail;
import com.launchdarkly.sdk.LDContext;
import com.launchdarkly.sdk.LDValue;
import com.launchdarkly.sdk.server.FeatureFlagsState;
import com.launchdarkly.sdk.server.FlagsStateOption;
import com.launchdarkly.sdk.server.LDClient;
import com.launchdarkly.sdk.server.LDConfig;
import com.launchdarkly.sdk.server.interfaces.BigSegmentStoreStatusProvider;
import com.launchdarkly.sdk.server.interfaces.DataSourceStatusProvider;
import com.launchdarkly.sdk.server.interfaces.DataStoreStatusProvider;
import com.launchdarkly.sdk.server.interfaces.FlagTracker;

import java.util.concurrent.Callable;

import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;

/**
* A thin wrapper of the {@link LDClient} that aims to adapt it to reactive stream programming.
*
* Methods that are potentially long running or that use IO have been wrapped to return {@link Mono}s and will be
* executed on the scheduler provided. Methods that do not have a risk of blocking have not been wrapped and are
* pass through.
*/
public final class LDReactorClient implements LDReactorClientInterface {

private final LDClient wrappedClient;
private final Scheduler scheduler;

/**
* Creates a client that uses the provided scheduler to execute functionality in a non-blocking manner.
*
* @param sdkKey the SDK key for your LaunchDarkly environment
* @param scheduler that will execute wrapped client methods
*/
public LDReactorClient(String sdkKey, Scheduler scheduler) {
this.wrappedClient = new LDClient(sdkKey);
this.scheduler = scheduler;
}

/**
* Creates a client that uses the provided scheduler to execute functionality in a non-blocking manner.
*
* @param sdkKey the SDK key for your LaunchDarkly environment
* @param config a client configuration object
* @param scheduler that will execute wrapped client methods
*/
public LDReactorClient(String sdkKey, LDConfig config, Scheduler scheduler) {
this.wrappedClient = new LDClient(sdkKey, config);
this.scheduler = scheduler;
}

@Override
public boolean isInitialized() {
return wrappedClient.isInitialized();
}

@Override
public void track(String eventName, LDContext context) {
wrappedClient.track(eventName, context);
}

@Override
public void trackData(String eventName, LDContext context, LDValue data) {
wrappedClient.trackData(eventName, context, data);
}

@Override
public void trackMetric(String eventName, LDContext context, LDValue data, double metricValue) {
wrappedClient.trackMetric(eventName, context, data, metricValue);
}

@Override
public void identify(LDContext context) {
wrappedClient.identify(context);
}

@Override
public Mono<FeatureFlagsState> allFlagsState(LDContext context, FlagsStateOption... options) {
return Mono.fromCallable(() -> wrappedClient.allFlagsState(context, options)).subscribeOn(this.scheduler);
}

@Override
public Mono<Boolean> boolVariation(String featureKey, LDContext context, boolean defaultValue) {
return Mono.fromCallable(() -> wrappedClient.boolVariation(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
}

@Override
public Mono<Integer> intVariation(String featureKey, LDContext context, int defaultValue) {
return Mono.fromCallable(() -> wrappedClient.intVariation(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
}

@Override
public Mono<Double> doubleVariation(String featureKey, LDContext context, double defaultValue) {
return Mono.fromCallable(() -> wrappedClient.doubleVariation(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
}

@Override
public Mono<String> stringVariation(String featureKey, LDContext context, String defaultValue) {
return Mono.fromCallable(() -> wrappedClient.stringVariation(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
}

@Override
public Mono<LDValue> jsonValueVariation(String featureKey, LDContext context, LDValue defaultValue) {
return Mono.fromCallable(() -> wrappedClient.jsonValueVariation(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
}

@Override
public Mono<EvaluationDetail<Boolean>> boolVariationDetail(String featureKey, LDContext context, boolean defaultValue) {
return Mono.fromCallable(() -> wrappedClient.boolVariationDetail(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
}

@Override
public Mono<EvaluationDetail<Integer>> intVariationDetail(String featureKey, LDContext context, int defaultValue) {
return Mono.fromCallable(() -> wrappedClient.intVariationDetail(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
}

@Override
public Mono<EvaluationDetail<Double>> doubleVariationDetail(String featureKey, LDContext context, double defaultValue) {
return Mono.fromCallable(() -> wrappedClient.doubleVariationDetail(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
}

@Override
public Mono<EvaluationDetail<String>> stringVariationDetail(String featureKey, LDContext context, String defaultValue) {
return Mono.fromCallable(() -> wrappedClient.stringVariationDetail(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
}

@Override
public Mono<EvaluationDetail<LDValue>> jsonValueVariationDetail(String featureKey, LDContext context, LDValue defaultValue) {
return Mono.fromCallable(() -> wrappedClient.jsonValueVariationDetail(featureKey, context, defaultValue)).subscribeOn(this.scheduler);
}

@Override
public boolean isFlagKnown(String featureKey) {
return wrappedClient.isFlagKnown(featureKey);
}

@Override
public FlagTracker getFlagTracker() {
return wrappedClient.getFlagTracker();
}

@Override
public BigSegmentStoreStatusProvider getBigSegmentStoreStatusProvider() {
return wrappedClient.getBigSegmentStoreStatusProvider();
}

@Override
public DataStoreStatusProvider getDataStoreStatusProvider() {
return wrappedClient.getDataStoreStatusProvider();
}

@Override
public DataSourceStatusProvider getDataSourceStatusProvider() {
return wrappedClient.getDataSourceStatusProvider();
}

@Override
public Mono<Void> close() {
return Mono.fromCallable((Callable<Void>) () -> {
wrappedClient.close();
return null;
}).subscribeOn(this.scheduler);
}

@Override
public void flush() {
wrappedClient.flush();
}

@Override
public boolean isOffline() {
return wrappedClient.isOffline();
}

@Override
public String secureModeHash(LDContext context) {
return wrappedClient.secureModeHash(context);
}

@Override
public String version() {
return wrappedClient.version();
}
}
Loading

0 comments on commit cc9aa41

Please sign in to comment.