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
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.featureprobe</groupId>
<artifactId>server-sdk-java</artifactId>
<version>1.4.1-SNAPSHOT</version>
<version>2.0.1</version>
<name>server-sdk-java</name>
<url>https://github.com/FeatureProbe/server-sdk-java</url>
<description>FeatureProbe Server Side SDK for Java</description>
Expand Down
25 changes: 24 additions & 1 deletion src/main/java/com/featureprobe/sdk/example/FeatureProbeDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.featureprobe.sdk.server.FPUser;
import com.featureprobe.sdk.server.FeatureProbe;
import java.io.IOException;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import com.featureprobe.sdk.server.Loggers;
Expand All @@ -23,7 +24,7 @@ public class FeatureProbeDemo {
// Server Side SDK Key for your project and environment
public static final String FEATURE_PROBE_SERVER_SDK_KEY = "server-8ed48815ef044428826787e9a238b9c6a479f98c";

public static void main(String[] args) throws IOException {
public static void main(String[] args) throws IOException, InterruptedException {

Logger root = (Logger)LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
root.setLevel(Level.WARN);
Expand Down Expand Up @@ -55,6 +56,28 @@ public static void main(String[] args) throws IOException {
System.out.println("detail:" + isOpenDetail.getReason());
System.out.println("rule index:" + isOpenDetail.getRuleIndex());


// Simulate conversion rate of 1000 users for a new feature
final String YOUR_CUSTOM_EVENT_NAME = "new_feature_conversion";
for (int i = 0; i < 1000; i++) {
FPUser eventUser = new FPUser().stableRollout(String.valueOf(System.nanoTime()));
boolean newFeature = fpClient.boolValue(YOUR_TOGGLE_KEY, eventUser, false);
Random random = new Random();
int randomRang = random.nextInt(100);
if (newFeature) {
if (randomRang <= 55) {
System.out.println("New feature conversion.");
fpClient.track(YOUR_CUSTOM_EVENT_NAME, eventUser);
}
} else {
if (randomRang > 55) {
System.out.println("Old feature conversion.");
fpClient.track(YOUR_CUSTOM_EVENT_NAME, eventUser);
}
}
Thread.sleep(200);
}

fpClient.close();

}
Expand Down
45 changes: 35 additions & 10 deletions src/main/java/com/featureprobe/sdk/server/AccessEvent.java
Original file line number Diff line number Diff line change
@@ -1,36 +1,61 @@
package com.featureprobe.sdk.server;

import com.fasterxml.jackson.annotation.JsonIgnore;

public class AccessEvent extends Event {

private final String key;

private final String value;
private final Object value;

private final Long version;

private final Integer index;
private final Integer variationIndex;

public AccessEvent(long timestamp, FPUser user, String key, String value, Long version, Integer index) {
super(timestamp, user);
this.key = key;
private final Integer ruleIndex;

private final String reason;

@JsonIgnore
private boolean trackAccessEvents;

public AccessEvent(String user, String key, Object value, Long version, Integer variationIndex,
Integer ruleIndex, String reason, boolean trackAccessEvents) {
super("access", System.currentTimeMillis(), user);
this.value = value;
this.version = version;
this.index = index;
this.variationIndex = variationIndex;
this.key = key;
this.ruleIndex = ruleIndex;
this.reason = reason;
this.trackAccessEvents = trackAccessEvents;
}


public String getKey() {
return key;
}

public String getValue() {
public Object getValue() {
return value;
}

public Long getVersion() {
return version;
}

public Integer getIndex() {
return index;
public Integer getVariationIndex() {
return variationIndex;
}

public Integer getRuleIndex() {
return ruleIndex;
}

public String getReason() {
return reason;
}

public boolean isTrackAccessEvents() {
return trackAccessEvents;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,35 @@
import java.util.List;
import java.util.Map;

public class AccessRecorder {
public class AccessSummaryRecorder {

Map<String, List<Counter>> counters;

long startTime;

long endTime;

AccessRecorder() {
AccessSummaryRecorder() {
counters = new HashMap<>();
}

private AccessRecorder(AccessRecorder accessRecorder) {
counters = new HashMap<>(accessRecorder.counters);
startTime = accessRecorder.startTime;
private AccessSummaryRecorder(AccessSummaryRecorder accessSummaryRecorder) {
counters = new HashMap<>(accessSummaryRecorder.counters);
startTime = accessSummaryRecorder.startTime;
endTime = System.currentTimeMillis();
}

static final class Counter {

long count;

final String value;
final Object value;

final Long version;

final Integer index;

public Counter(String value, Long version, Integer index) {
public Counter(Object value, Long version, Integer index) {
this.value = value;
this.version = version;
this.index = index;
Expand All @@ -44,15 +44,15 @@ public void increment() {
++count;
}

public boolean isGroup(String value, Long version, Integer index) {
return this.value.equals(value) && this.version.equals(version) && this.index.equals(index);
public boolean isGroup(Long version, Integer index) {
return this.version.equals(version) && this.index.equals(index);
}

public long getCount() {
return count;
}

public String getValue() {
public Object getValue() {
return value;
}

Expand All @@ -73,15 +73,15 @@ public void add(Event event) {
if (counters.containsKey(accessEvent.getKey())) {
List<Counter> counters = this.counters.get(accessEvent.getKey());
for (Counter counter : counters) {
if (counter.isGroup(accessEvent.getValue(), accessEvent.getVersion(), accessEvent.getIndex())) {
if (counter.isGroup(accessEvent.getVersion(), accessEvent.getVariationIndex())) {
counter.increment();
return;
}
}
counters.add(new Counter(accessEvent.getValue(), accessEvent.getVersion(), accessEvent.getIndex()));
counters.add(new Counter(accessEvent.getValue(), accessEvent.getVersion(), accessEvent.getVariationIndex()));
} else {
List<Counter> groups = new ArrayList<>(1);
groups.add(new Counter(accessEvent.getValue(), accessEvent.getVersion(), accessEvent.getIndex()));
groups.add(new Counter(accessEvent.getValue(), accessEvent.getVersion(), accessEvent.getVariationIndex()));
counters.put(accessEvent.getKey(), groups);
}
}
Expand All @@ -90,8 +90,8 @@ public void clear() {
counters = new HashMap<>();
}

public AccessRecorder snapshot() {
return new AccessRecorder(this);
public AccessSummaryRecorder snapshot() {
return new AccessSummaryRecorder(this);
}

public Map<String, List<Counter>> getCounters() {
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/com/featureprobe/sdk/server/CustomEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.featureprobe.sdk.server;

public class CustomEvent extends Event {

private final String name;

private final Double value;

public CustomEvent(String name, String user, Double value) {
super("custom", System.currentTimeMillis(), user);
this.name = name;
this.value = value;
}

public String getName() {
return name;
}

public Double getValue() {
return value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -212,14 +212,14 @@ private static final class EventRepository {

List<Event> events = new ArrayList<>();

AccessRecorder access = new AccessRecorder();
AccessSummaryRecorder access = new AccessSummaryRecorder();

public EventRepository() {
}

private EventRepository(EventRepository eventRepository) {
this.events = eventRepository.events;
this.access = eventRepository.access.snapshot();
private EventRepository(EventRepository repository) {
this.events = new ArrayList<>(repository.events);
this.access = repository.access.snapshot();
}

boolean isEmpty() {
Expand All @@ -229,6 +229,12 @@ boolean isEmpty() {
void add(Event event) {
if (event instanceof AccessEvent) {
access.add(event);
// if (((AccessEvent) event).isTrackAccessEvents()) {
if (true) {
events.add(event);
}
} else if (event instanceof CustomEvent) {
events.add(event);
}
}

Expand All @@ -245,7 +251,7 @@ public List<Event> getEvents() {
return events;
}

public AccessRecorder getAccess() {
public AccessSummaryRecorder getAccess() {
return access;
}
}
Expand Down
21 changes: 14 additions & 7 deletions src/main/java/com/featureprobe/sdk/server/Event.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,27 @@

public class Event {

private final long createdTime;
private final String kind;

private final FPUser user;
private final long time;

public Event(long createdTime, FPUser user) {
this.createdTime = createdTime;
private final String user;

public Event(String kind, long time, String user) {
this.kind = kind;
this.time = time;
this.user = user;
}

public long getCreatedTime() {
return createdTime;
public String getKind() {
return kind;
}

public long getTime() {
return time;
}

public FPUser getUser() {
public String getUser() {
return user;
}
}
Loading