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
10 changes: 10 additions & 0 deletions examples/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,13 @@ tasks.register('GettingStarted', JavaExec) {
classpath = sourceSets.main.runtimeClasspath
mainClass = "io.harness.ff.examples.GettingStarted"
}

tasks.register('EventExample', JavaExec) {
classpath = sourceSets.main.runtimeClasspath
mainClass = "io.harness.ff.examples.EventExample"
}

tasks.register('EventExampleWithFeatureSnapshot', JavaExec) {
classpath = sourceSets.main.runtimeClasspath
mainClass = "io.harness.ff.examples.EventExampleWithFeatureSnapshot"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package io.harness.ff.examples;

import io.harness.cf.client.api.BaseConfig;
import io.harness.cf.client.api.CfClient;
import io.harness.cf.client.api.Event;
import io.harness.cf.client.api.XmlFileMapStore;
import io.harness.cf.client.connector.HarnessConfig;
import io.harness.cf.client.connector.HarnessConnector;
import io.harness.cf.client.dto.Target;
import io.harness.cf.model.FeatureSnapshot;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
public class EventExamplePoC {
private static final String SDK_KEY = "";
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

private static CfClient client;

public static void main(String... args) {

Runtime.getRuntime().addShutdownHook(new Thread(() -> {
scheduler.shutdown();
client.close();
}));

final XmlFileMapStore fileStore = new XmlFileMapStore("Non-Freemium");
// this is one way of initialising config.
final HarnessConnector hc = new HarnessConnector(SDK_KEY, HarnessConfig.builder().build());

BaseConfig bc = BaseConfig.builder().
enableFeatureSnapshot(true).build();

// initialise the client.
client = new CfClient(hc, bc);

client.on(Event.READY, result -> log.info("READY"));

// example: specified prefix we can filter on.
final String FLAG_PREFIX = "FFM_";
// example: given flag change event - get both previous and current feature if prefix is matched.
client.on(Event.CHANGED, identifier -> {
if (identifier.startsWith(FLAG_PREFIX)) {
getSnapshot(identifier);
} else {
log.info("We had an event change but flag did not have required prefix");
}
});

// example : given flag change event - get all snapshots.
client.on(Event.CHANGED, identifier -> {
getAllSnapshots();
});

// example : given flag change event - get all snapshots with given prefix.
client.on(Event.CHANGED, identifier -> {
getAllSnapshotsWithPrefix();
});

final Target target = Target.builder().identifier("target1").attribute("testKey", "TestValue").name("target1").build();

scheduler.scheduleAtFixedRate(() -> {
log.info("ticking...");
}, 0, 10, TimeUnit.SECONDS);

}


// example method to extract a single snapshot.
private static void getSnapshot(String identifier) {
log.info("We had a chang event and prefix matched, lets inspect the diff");
// fetch current and previous version of the feature
FeatureSnapshot snapshot = client.getFeatureSnapshot(identifier);
log.info("Previous flag config: {}, {}", identifier, snapshot.getPrevious());
log.info("Current flag config: {}, {}", identifier, snapshot.getCurrent());
}


// example method to extract and print all the snapshots.
private static void getAllSnapshots() {
// get all snapshots
List<FeatureSnapshot> snapshots = client.getAllFeatureSnapshots();
int counter = 0;
for (FeatureSnapshot snapshot : snapshots) {
log.info("snapshots {} {}", ++counter, snapshot);
}
}

// example method to extract and print all the snapshots.
private static void getAllSnapshotsWithPrefix() {
// get all snapshots
String prefix = "FFM_";
List<FeatureSnapshot> snapshots = client.getAllFeatureSnapshots(prefix);
int counter = 0;
for (FeatureSnapshot snapshot : snapshots) {
log.info("snapshots {} {}", ++counter, snapshot);
}
}
}


3 changes: 3 additions & 0 deletions src/main/java/io/harness/cf/client/api/BaseConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ public class BaseConfig {
/** If metrics service POST call is taking > this time, we need to know about it */
@Builder.Default private final long metricsServiceAcceptableDuration = 10000;

/** store previous and current version of the FeatureConfig */
@Builder.Default private final boolean enableFeatureSnapshot = false;

/** Get metrics post frequency in seconds */
public int getFrequency() {
return Math.max(frequency, Config.MIN_FREQUENCY);
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/io/harness/cf/client/api/CfClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import io.harness.cf.client.dto.Message;
import io.harness.cf.client.dto.Target;
import io.harness.cf.client.logger.LogUtil;
import io.harness.cf.model.FeatureSnapshot;
import java.util.List;
import java.util.function.Consumer;
import lombok.NonNull;

Expand Down Expand Up @@ -83,6 +85,18 @@ public void on(@NonNull final Event event, @NonNull final Consumer<String> consu
client.on(event, consumer);
}

public List<FeatureSnapshot> getAllFeatureSnapshots(String prefix) {
return client.getFeatureSnapshots(prefix);
}

public List<FeatureSnapshot> getAllFeatureSnapshots() {
return client.getFeatureSnapshots();
}

public FeatureSnapshot getFeatureSnapshot(@NonNull String identifier) {
return client.getFeatureSnapshot(identifier);
}

public void off() {
client.off();
}
Expand Down
13 changes: 9 additions & 4 deletions src/main/java/io/harness/cf/client/api/InnerClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ protected void setUp(@NonNull final Connector connector, @NonNull final BaseConf
this.connector.setOnUnauthorized(this::onUnauthorized);

// initialization
repository = new StorageRepository(options.getCache(), options.getStore(), this, false);
repository =
new StorageRepository(
options.getCache(), options.getStore(), this, options.isEnableFeatureSnapshot());
evaluator = new Evaluator(repository, options);
authService = new AuthService(this.connector, options.getPollIntervalInSeconds(), this);
pollProcessor =
Expand Down Expand Up @@ -313,12 +315,13 @@ public synchronized void waitForInitialization()
}

public List<FeatureSnapshot> getFeatureSnapshots() {
// TODO return null/empty list if snapshot is not enabled in config.
return getFeatureSnapshots("");
}

public List<FeatureSnapshot> getFeatureSnapshots(String prefix) {
// TODO return null/empty list if snapshot is not enabled in config.
if (!options.isEnableFeatureSnapshot()){
log.debug("FeatureSnapshot disabled, snapshot will contain only current version.");
}
List<String> identifiers = repository.getAllFeatureIdentifiers(prefix);
List<FeatureSnapshot> snapshots = new LinkedList<>();

Expand All @@ -331,7 +334,9 @@ public List<FeatureSnapshot> getFeatureSnapshots(String prefix) {
}

public FeatureSnapshot getFeatureSnapshot(@NonNull String identifier) {
// TODO return null/empty list if snapshot is not enabled in config.
if (!options.isEnableFeatureSnapshot()){
log.debug("FeatureSnapshot disabled, snapshot will contain only current version.");
}
Optional<FeatureConfig[]> ofc = repository.getCurrentAndPreviousFeatureConfig(identifier);
FeatureSnapshot result = new FeatureSnapshot();
if (ofc.isPresent()) {
Expand Down