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
6 changes: 3 additions & 3 deletions .github/workflows/sdk-spec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ permissions:
jobs:
sdk-spec:
# Keep the ref in `uses:` and `spec-ref` in sync.
uses: Flagsmith/sdk-spec/.github/workflows/run-spec.yml@v0.7.0
uses: Flagsmith/sdk-spec/.github/workflows/run-spec.yml@v0.9.0
with:
spec-ref: v0.7.0
spec-ref: v0.9.0
language: java
tags: core or local-evaluation
tags: core events local-evaluation
76 changes: 76 additions & 0 deletions sdk-spec/Steps.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import com.flagsmith.exceptions.FlagsmithClientError;
import com.flagsmith.models.BaseFlag;
import com.flagsmith.models.Flags;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -47,6 +49,35 @@ static FlagsmithClient createClientWithLocalEvaluation(String environmentKey, St
.build();
}

// Create the SDK client with events enabled
static FlagsmithClient createClientWithEvents(
String environmentKey, String apiUrl, String eventsUrl) {
return FlagsmithClient.newBuilder()
.setApiKey(environmentKey)
.withConfiguration(
FlagsmithConfig.newBuilder()
.baseUri(apiUrl)
.withEnableEvents(true)
.eventsUri(eventsUrl)
.build())
.build();
}

// Create the SDK client with local evaluation and events enabled
static FlagsmithClient createClientWithLocalEvaluationAndEvents(
String environmentKey, String apiUrl, String eventsUrl) {
return FlagsmithClient.newBuilder()
.setApiKey(environmentKey)
.withConfiguration(
FlagsmithConfig.newBuilder()
.baseUri(apiUrl)
.withLocalEvaluation(true)
.withEnableEvents(true)
.eventsUri(eventsUrl)
.build())
.build();
}

// When the application gets the environment flags
static List<SpecFlag> getEnvironmentFlags(FlagsmithClient flagsmith)
throws FlagsmithClientError {
Expand All @@ -59,4 +90,49 @@ static List<SpecFlag> getIdentityFlags(
throws FlagsmithClientError {
return asSpecFlags(flagsmith.getIdentityFlags(identifier, traits));
}

// When the application gets the experiment flag "{feature}" for identity "{identifier}" with traits:
static List<SpecFlag> getExperimentFlag(
FlagsmithClient flagsmith, String feature, String identifier, Map<String, Object> traits)
throws FlagsmithClientError {
return Collections.singletonList(
new SpecFlag(flagsmith.getExperimentFlag(feature, identifier, traits)));
}

// When the application tracks event "{event}" for identity "{identifier}" with value {value} and metadata:
static void trackEvent(
FlagsmithClient flagsmith,
String event,
String identifier,
Object value,
Map<String, Object> metadata) {
flagsmith.trackEvent(event, identifier, value, null, metadata);
}

// When the application tracks an exposure of feature "{feature}" for identity "{identifier}" with value {value} and metadata:
static void trackExposureEvent(
FlagsmithClient flagsmith,
String feature,
String identifier,
Object value,
Map<String, Object> metadata) {
flagsmith.trackExposureEvent(feature, identifier, value, null, metadata);
}

// When the application tracks events "event_{first}" to "event_{last}" for identity "{identifier}"
static void trackEvents(FlagsmithClient flagsmith, int first, int last, String identifier) {
for (int number = first; number <= last; number++) {
flagsmith.trackEvent("event_" + number, identifier);
}
}

// When the application flushes events
static void flushEvents(FlagsmithClient flagsmith) throws Exception {
flagsmith.flushEvents().get();
}

// When the application closes the client with a timeout of {timeout} seconds
static void close(FlagsmithClient flagsmith, int timeout) {
flagsmith.close(timeout, TimeUnit.SECONDS);
}
}
28 changes: 24 additions & 4 deletions src/main/java/com/flagsmith/FlagsmithClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.AccessLevel;
Expand Down Expand Up @@ -408,8 +410,9 @@ public void trackExposureEvent(String featureName, String identifier, Object val
/**
* Send buffered events now.
*
* @return a future completing once every event buffered so far has been sent or dropped, already
* completed when events are not enabled
* @return a future completing, never exceptionally, once every event buffered so far has been
* sent, dropped or kept for the next flush, retries included; already completed when events
* are not enabled
*/
public CompletableFuture<Void> flushEvents() {
if (eventProcessor == null) {
Expand All @@ -421,15 +424,32 @@ public CompletableFuture<Void> flushEvents() {

/**
* Should be called when terminating the client to clean up any resources that
* need cleaning up.
* need cleaning up. Sends the buffered events first, waiting for at most one batch's worst case
* under the events API's timeouts and retries.
**/
public void close() {
close(EventProcessor::close);
}

/**
* Should be called when terminating the client to clean up any resources that need cleaning
* up. Sends the buffered events first, retries included, waiting for them for at most
* {@code timeout}; events still unsent then are dropped. Never throws.
*
* @param timeout how long to wait for the buffered events to be sent
* @param unit unit of {@code timeout}
*/
public void close(long timeout, TimeUnit unit) {
close((processor) -> processor.close(unit.toMillis(timeout)));
}

private void close(Consumer<EventProcessor> closeEvents) {
if (pollingManager != null) {
pollingManager.stopPolling();
}

if (eventProcessor != null) {
eventProcessor.close();
closeEvents.accept(eventProcessor);
}

flagsmithSdk.close();
Expand Down
Loading
Loading