Skip to content

Implementing Resilience #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
*.log
build/
out/
/absmarly.db
5 changes: 4 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ plugins {


ext {
VERSION = "1.5.3"
VERSION = "1.6.0"
GROUP_ID = "com.absmartly.sdk"

slf4jVersion = "1.7.30"

jacksonVersion = "2.13.4.2"
jacksonDataTypeVersion = "2.13.4"

sqliteVersion = "3.40.1.0"

junitVersion = "5.7.0"
mockitoVersion = "3.6.28"
}
Expand Down Expand Up @@ -63,6 +65,7 @@ configure(subprojects.findAll {
from javadoc.destinationDir
}

//Config for local maven publish
afterEvaluate {
publishing {
publications {
Expand Down
11 changes: 11 additions & 0 deletions core-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ description = """ABSmartly Java SDK"""

def httpClientVersion = "5.1.3"

jar {
from {
configurations.runtimeClasspath.collect {
it.getName().contains("simpleCircuitBreaker") ? zipTree(it) : null
}
}
}

dependencies {
implementation group: "org.slf4j", name: "slf4j-api", version: slf4jVersion

Expand All @@ -21,6 +29,9 @@ dependencies {

implementation group: "com.fasterxml.jackson.core", name: "jackson-databind", version: jacksonVersion
implementation group: "com.fasterxml.jackson.datatype", name: "jackson-datatype-jsr310", version: jacksonDataTypeVersion
implementation group: 'org.xerial', name: 'sqlite-jdbc', version: sqliteVersion

implementation files('../libs/simpleCircuitBreaker-2.0.5.jar')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we going to distribute this in our repository?
Can we find something on maven-central or any other repository?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, the developer has not released it to any Maven Repo :(

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The developer didn't answer that. Let keep this way until I get a response from them.


testImplementation group: "org.junit.jupiter", name: "junit-jupiter-api", version: junitVersion
testImplementation group: "org.junit.jupiter", name: "junit-jupiter-params", version: junitVersion
Expand Down
21 changes: 19 additions & 2 deletions core-api/src/main/java/com/absmartly/sdk/ABSmartly.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,35 @@ private ABSmartly(@Nonnull ABSmartlyConfig config) {
audienceDeserializer_ = config.getAudienceDeserializer();
scheduler_ = config.getScheduler();

if (config.getResilienceConfig() != null
&& config.getResilienceConfig().getLocalCache() == null) {
throw new IllegalArgumentException("Missing LocalCache instance");
}

if ((contextDataProvider_ == null) || (contextEventHandler_ == null)) {
client_ = config.getClient();
if (client_ == null) {
throw new IllegalArgumentException("Missing Client instance");
}

if (contextDataProvider_ == null) {
contextDataProvider_ = new DefaultContextDataProvider(client_);
if (config.getResilienceConfig() != null) {
contextDataProvider_ = new ResilientContextDataProvider(client_,
config.getResilienceConfig().getLocalCache());
} else {
contextDataProvider_ = new DefaultContextDataProvider(client_);
}
}

if (contextEventHandler_ == null) {
contextEventHandler_ = new DefaultContextEventHandler(client_);
if (config.getResilienceConfig() != null) {
contextEventHandler_ = new ResilientContextEventHandler(
client_,
config.getResilienceConfig());
} else {
contextEventHandler_ = new DefaultContextEventHandler(client_);
}

}
}

Expand Down
10 changes: 10 additions & 0 deletions core-api/src/main/java/com/absmartly/sdk/ABSmartlyConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ public ABSmartlyConfig setVariableParser(@Nonnull final VariableParser variableP
return this;
}

public ResilienceConfig getResilienceConfig() {
return this.resilienceConfig;
}

public ABSmartlyConfig setResilienceConfig(@Nonnull final ResilienceConfig resilienceConfig) {
this.resilienceConfig = resilienceConfig;
return this;
}

public ScheduledExecutorService getScheduler() {
return scheduler_;
}
Expand Down Expand Up @@ -83,4 +92,5 @@ public ABSmartlyConfig setClient(Client client) {
private AudienceDeserializer audienceDeserializer_;
private ScheduledExecutorService scheduler_;
private Client client_;
private ResilienceConfig resilienceConfig;
}
4 changes: 2 additions & 2 deletions core-api/src/main/java/com/absmartly/sdk/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ static public Client create(@Nonnull final ClientConfig config, @Nonnull final H
executor_ = config.getExecutor();

if (deserializer_ == null) {
deserializer_ = new DefaultContextDataDeserializer();
deserializer_ = new DefaultContextDataSerializer();
}

if (serializer_ == null) {
Expand Down Expand Up @@ -154,6 +154,6 @@ public void close() throws IOException {
private final Map<String, String> headers_;
private final HTTPClient httpClient_;
private final Executor executor_;
private ContextDataDeserializer deserializer_;
private ContextDataSerializer deserializer_;
private ContextEventSerializer serializer_;
}
6 changes: 3 additions & 3 deletions core-api/src/main/java/com/absmartly/sdk/ClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ public ClientConfig setApplication(@Nonnull final String application) {
return this;
}

public ContextDataDeserializer getContextDataDeserializer() {
public ContextDataSerializer getContextDataDeserializer() {
return deserializer_;
}

public ClientConfig setContextDataDeserializer(@Nonnull final ContextDataDeserializer deserializer) {
public ClientConfig setContextDataDeserializer(@Nonnull final ContextDataSerializer deserializer) {
deserializer_ = deserializer;
return this;
}
Expand All @@ -91,7 +91,7 @@ public ClientConfig setExecutor(@Nonnull final Executor executor) {
private String apiKey_;
private String environment_;
private String application_;
private ContextDataDeserializer deserializer_;
private ContextDataSerializer deserializer_;
private ContextEventSerializer serializer_;
private Executor executor_;
}
11 changes: 9 additions & 2 deletions core-api/src/main/java/com/absmartly/sdk/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java8.util.concurrent.CompletableFuture;
import java8.util.concurrent.CompletionException;
import java8.util.function.BiConsumer;
import java8.util.function.Consumer;
import java8.util.function.Function;

Expand Down Expand Up @@ -71,6 +72,13 @@ private Context(Clock clock, ContextConfig config, ScheduledExecutorService sche
cassignments_ = (cassignments != null) ? new HashMap<String, Integer>(cassignments)
: new HashMap<String, Integer>();

dataFuture.whenComplete(new BiConsumer<ContextData, Throwable>() {
@Override
public void accept(ContextData unused, Throwable throwable) {
eventHandler_.onContextReady();
}
});

if (dataFuture.isDone()) {
dataFuture.thenAccept(new Consumer<ContextData>() {
@Override
Expand Down Expand Up @@ -602,7 +610,6 @@ public void run() {
@Override
public Void apply(Throwable throwable) {
Context.this.logError(throwable);

result.completeExceptionally(throwable);
return null;
}
Expand Down Expand Up @@ -920,7 +927,7 @@ private void setData(final ContextData data) {
new Comparator<ExperimentVariables>() {
@Override
public int compare(ExperimentVariables a, ExperimentVariables b) {
return Integer.valueOf(a.data.id).compareTo(b.data.id);
return Integer.compare(Integer.valueOf(a.data.id), b.data.id);
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

import com.absmartly.sdk.json.ContextData;

interface ContextDataDeserializer {
public interface ContextDataSerializer {

byte[] serialize(@Nonnull final ContextData contextData);

ContextData deserialize(@Nonnull final byte[] bytes, final int offset, final int length);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
import com.absmartly.sdk.json.PublishEvent;

public interface ContextEventHandler {
CompletableFuture<Void> publish(@Nonnull final Context context, @Nonnull final PublishEvent event);
CompletableFuture<Void> publish(final Context context, @Nonnull final PublishEvent event);
void onContextReady();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@

public interface ContextEventSerializer {
byte[] serialize(@Nonnull final PublishEvent publishEvent);

PublishEvent deserialize(@Nonnull final byte[] bytes, final int offset, final int length);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,40 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;

import com.absmartly.sdk.json.ContextData;

public class DefaultContextDataDeserializer implements ContextDataDeserializer {
private static final Logger log = LoggerFactory.getLogger(DefaultContextDataDeserializer.class);
public class DefaultContextDataSerializer implements ContextDataSerializer {
private static final Logger log = LoggerFactory.getLogger(DefaultContextDataSerializer.class);

public DefaultContextDataDeserializer() {
public DefaultContextDataSerializer() {
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(MapperFeature.USE_STATIC_TYPING);

this.writer_ = objectMapper.writerFor(ContextData.class);
this.reader_ = objectMapper.readerFor(ContextData.class);
}

public DefaultContextDataSerializer(final ObjectWriter writer, final ObjectReader reader) {
this.writer_ = writer;
this.reader_ = reader;
}

@Override
public byte[] serialize(@Nonnull ContextData contextData) {
try {
return writer_.writeValueAsBytes(contextData);
} catch (JsonProcessingException e) {
log.error("", e);
return null;
}
}

public ContextData deserialize(@Nonnull final byte[] bytes, final int offset, final int length) {
try {
return reader_.readValue(bytes, offset, length);
Expand All @@ -31,5 +50,6 @@ public ContextData deserialize(@Nonnull final byte[] bytes, final int offset, fi
}
}

final private ObjectWriter writer_;
private final ObjectReader reader_;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ public DefaultContextEventHandler(@Nonnull final Client client) {
}

@Override
public CompletableFuture<Void> publish(@Nonnull final Context context, @Nonnull final PublishEvent event) {
public CompletableFuture<Void> publish(final Context context, @Nonnull final PublishEvent event) {
return client_.publish(event);
}

private final Client client_;
@Override
public void onContextReady() {
}

final Client client_;
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package com.absmartly.sdk;

import java.io.IOException;

import javax.annotation.Nonnull;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;

import com.absmartly.sdk.json.PublishEvent;
Expand All @@ -17,10 +21,14 @@ public class DefaultContextEventSerializer implements ContextEventSerializer {
public DefaultContextEventSerializer() {
final ObjectMapper objectMapper = new ObjectMapper();
this.writer_ = objectMapper.writerFor(PublishEvent.class);

objectMapper.enable(MapperFeature.USE_STATIC_TYPING);
this.reader_ = objectMapper.readerFor(PublishEvent.class);
}

public DefaultContextEventSerializer(final ObjectWriter writer) {
public DefaultContextEventSerializer(final ObjectWriter writer, final ObjectReader reader) {
this.writer_ = writer;
this.reader_ = reader;
}

@Override
Expand All @@ -33,5 +41,17 @@ public byte[] serialize(@Nonnull final PublishEvent event) {
}
}

@Override
public PublishEvent deserialize(@Nonnull byte[] bytes, int offset, int length) {
try {
return reader_.readValue(bytes, offset, length);
} catch (IOException e) {
log.error("", e);
return null;
}
}

final private ObjectWriter writer_;

private final ObjectReader reader_;
}
Loading