From 8ff4f587f164adda95b2ea6881f7689226a1c106 Mon Sep 17 00:00:00 2001 From: chungchantal Date: Fri, 9 Sep 2022 15:59:19 -0700 Subject: [PATCH 1/3] implement EventQueueManager and track --- build.gradle | 4 + .../sdk/server/common/api/IDVCApi.java | 12 ++ .../server/local/api/DVCLocalApiClient.java | 12 ++ .../sdk/server/local/api/DVCLocalClient.java | 51 ++++--- .../local/api/DVCLocalEventsApiClient.java | 64 +++++++++ .../local/bucketing/LocalBucketing.java | 6 +- .../managers/EnvironmentConfigManager.java | 2 - .../local/managers/EventQueueManager.java | 136 +++++++++++++++++- .../server/local/model/DVCLocalOptions.java | 6 + .../sdk/server/local/model/EventPayload.java | 12 +- .../sdk/server/local/model/EventsBatch.java | 9 ++ .../sdk/server/local/model/FlushPayload.java | 34 +++++ .../sdk/server/local/model/RequestEvent.java | 12 +- src/main/resources/bucketing-lib.release.wasm | Bin 130777 -> 132336 bytes .../sdk/server/common/api/DVCApiMock.java | 7 + .../sdk/server/local/DVCLocalClientTest.java | 17 ++- 16 files changed, 330 insertions(+), 54 deletions(-) create mode 100644 src/main/java/com/devcycle/sdk/server/local/api/DVCLocalEventsApiClient.java create mode 100644 src/main/java/com/devcycle/sdk/server/local/model/EventsBatch.java create mode 100644 src/main/java/com/devcycle/sdk/server/local/model/FlushPayload.java diff --git a/build.gradle b/build.gradle index a88c2143..be102e41 100755 --- a/build.gradle +++ b/build.gradle @@ -129,6 +129,10 @@ dependencies { implementation ("io.github.kawamuray.wasmtime:wasmtime-java:$wasmtime_version") + implementation("com.squareup.okhttp3:logging-interceptor:$okhttp_version") { + exclude group: "com.squareup.okhttp3", module: "okhttp" + } + compileOnly("org.projectlombok:lombok:$lombok_version") testAnnotationProcessor("org.projectlombok:lombok:$lombok_version") diff --git a/src/main/java/com/devcycle/sdk/server/common/api/IDVCApi.java b/src/main/java/com/devcycle/sdk/server/common/api/IDVCApi.java index dc00c45d..ca4f619e 100755 --- a/src/main/java/com/devcycle/sdk/server/common/api/IDVCApi.java +++ b/src/main/java/com/devcycle/sdk/server/common/api/IDVCApi.java @@ -1,6 +1,7 @@ package com.devcycle.sdk.server.common.api; import com.devcycle.sdk.server.common.model.*; +import com.devcycle.sdk.server.local.model.EventsBatch; import retrofit2.Call; import retrofit2.http.*; @@ -62,4 +63,15 @@ public interface IDVCApi { @Headers({"Content-Type:application/json"}) @GET("config/v1/server/{sdkToken}.json") Call getConfig(@Path("sdkToken") String sdkToken, @Header("If-None-Match") String etag); + + /** + * Post events to DevCycle for user + * + * @param eventsBatch (required) + * @return Call<DVCResponse> + */ + @Headers({"Content-Type:application/json"}) + @POST("v1/events/batch") + Call publishEvents(@Body EventsBatch eventsBatch); } + diff --git a/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalApiClient.java b/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalApiClient.java index a7af88ba..c16cba8f 100755 --- a/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalApiClient.java +++ b/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalApiClient.java @@ -2,6 +2,7 @@ import com.devcycle.sdk.server.common.api.IDVCApi; import com.devcycle.sdk.server.local.model.DVCLocalOptions; +import com.devcycle.sdk.server.local.model.FlushPayload; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.annotation.JsonInclude; @@ -16,6 +17,7 @@ public final class DVCLocalApiClient { private final OkHttpClient.Builder okBuilder; private final Retrofit.Builder adapterBuilder; + private final Retrofit.Builder eventsBuilder; private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); @@ -44,6 +46,10 @@ private DVCLocalApiClient(DVCLocalOptions options) { adapterBuilder = new Retrofit.Builder() .baseUrl(url) .addConverterFactory(JacksonConverterFactory.create()); + + eventsBuilder = new Retrofit.Builder() + .baseUrl("https://events.devcycle.com") + .addConverterFactory(JacksonConverterFactory.create()); } public DVCLocalApiClient(String apiKey, DVCLocalOptions options) { @@ -60,4 +66,10 @@ public IDVCApi initialize() { private Boolean checkIfStringNullOrEmpty(String stringToCheck) { return Objects.isNull(stringToCheck) || Objects.equals(stringToCheck, ""); } + + public void publishEvents(String environmentKey, FlushPayload.Record[] eventsBatch) throws Exception { + if (environmentKey == null || environmentKey.equals("")) { + throw new Exception("DevCycle is not yet initialized to publish events."); + } + } } diff --git a/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalClient.java b/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalClient.java index e8770283..e9b1d4f9 100755 --- a/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalClient.java +++ b/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalClient.java @@ -6,6 +6,7 @@ import com.devcycle.sdk.server.common.model.*; import com.devcycle.sdk.server.local.bucketing.LocalBucketing; import com.devcycle.sdk.server.local.managers.EnvironmentConfigManager; +import com.devcycle.sdk.server.local.managers.EventQueueManager; import com.devcycle.sdk.server.local.model.BucketedUserConfig; import com.devcycle.sdk.server.local.model.DVCLocalOptions; import com.fasterxml.jackson.annotation.JsonInclude; @@ -22,6 +23,8 @@ public final class DVCLocalClient { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private EventQueueManager eventQueueManager; + public DVCLocalClient(String serverKey) { this(serverKey, DVCLocalOptions.builder().build()); } @@ -30,6 +33,7 @@ public DVCLocalClient(String serverKey, DVCLocalOptions dvcOptions) { configManager = new EnvironmentConfigManager(serverKey, localBucketing, dvcOptions); this.serverKey = serverKey; OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); + eventQueueManager = new EventQueueManager(localBucketing, serverKey, dvcOptions); } /** @@ -71,6 +75,13 @@ public Variable variable(User user, String key, T defaultValue) { System.out.println("Variable called before DVCClient has initialized, returning default value"); } + Variable defaultVariable = (Variable) Variable.builder() + .key(key) + .value(defaultValue) + .isDefaulted(true) + .reasonUsingDefaultValue("Variable not found") + .build(); + try { String userString = OBJECT_MAPPER.writeValueAsString(user); @@ -78,29 +89,22 @@ public Variable variable(User user, String key, T defaultValue) { if (bucketedUserConfig.variables.containsKey(key)) { Variable variable = bucketedUserConfig.variables.get(key); variable.setIsDefaulted(false); + eventQueueManager.queueAggregateEvent(Event.builder().type("aggVariableEvaluated").target(key).build(), bucketedUserConfig); return variable; + } else { + eventQueueManager.queueAggregateEvent(Event.builder().type("aggVariableDefaulted").target(key).build(), bucketedUserConfig); + return defaultVariable; } } catch (JsonProcessingException e) { System.out.printf("Unable to parse JSON for Variable %s due to error: %s", key, e.toString()); } - Variable variable; - - variable = (Variable) Variable.builder() - .key(key) - .value(defaultValue) - .isDefaulted(true) - .reasonUsingDefaultValue("Variable not found") - .build(); - - // TODO queue events - // eventQueue.queueAggregateEvent( - // user, - // new Event(type: EventTypes.variableDefaulted, target: key), - // null - // ); - - return variable; + try { + eventQueueManager.queueAggregateEvent(Event.builder().type("aggVariableDefaulted").target(key).build(), null); + } catch (JsonProcessingException e) { + System.out.printf("Unable to parse aggVariableDefaulted event for Variable %s due to error: %s", key, e.toString()); + } + return defaultVariable; } /** @@ -123,19 +127,12 @@ public Map allVariables(User user) throws JsonProcessingExcept * @param user (required) * @param event (required) */ - // TODO: Original return type should match the line below, uncomment once - // implemented and delete the void return - // public DVCResponse track(User user, Event event) throws DVCException { - public void track(User user, Event event) { + public void track(User user, Event event) throws Exception { validateUser(user); localBucketing.setPlatformData(user.getPlatformData().toString()); - UserAndEvents userAndEvents = UserAndEvents.builder() - .user(user) - .events(Collections.singletonList(event)) - .build(); - - // Call track method to append custom event to queue + eventQueueManager.queueEvent(user, event); + eventQueueManager.flushEvents(); } private void validateUser(User user) { diff --git a/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalEventsApiClient.java b/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalEventsApiClient.java new file mode 100644 index 00000000..84859555 --- /dev/null +++ b/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalEventsApiClient.java @@ -0,0 +1,64 @@ +package com.devcycle.sdk.server.local.api; + +import com.devcycle.sdk.server.common.api.IDVCApi; +import com.devcycle.sdk.server.common.interceptor.AuthorizationHeaderInterceptor; +import com.devcycle.sdk.server.local.model.DVCLocalOptions; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.annotation.JsonInclude; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import okhttp3.logging.HttpLoggingInterceptor.Level; +import retrofit2.Retrofit; +import retrofit2.converter.jackson.JacksonConverterFactory; + +import java.util.Objects; + +public final class DVCLocalEventsApiClient { + + private final OkHttpClient.Builder okBuilder; + private final Retrofit.Builder adapterBuilder; + private HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + private static final String EVENTS_API_URL = "https://events.devcycle.com/"; + + private String eventsApiUrl; + + private DVCLocalEventsApiClient(DVCLocalOptions options) { + String url; + + OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); + okBuilder = new OkHttpClient.Builder(); + + String eventsApiUrlFromOptions = options.getEventsApiBaseUrl(); + + eventsApiUrl = checkIfStringNullOrEmpty(eventsApiUrlFromOptions) ? EVENTS_API_URL : eventsApiUrlFromOptions; + + url = this.eventsApiUrl; + + adapterBuilder = new Retrofit.Builder() + .baseUrl(url) + .addConverterFactory(JacksonConverterFactory.create()); + } + + public DVCLocalEventsApiClient(String apiKey, DVCLocalOptions options) { + this(options); + okBuilder.addInterceptor(new AuthorizationHeaderInterceptor(apiKey)); + logging.setLevel(Level.BODY); + + okBuilder.addInterceptor(logging); + } + + public IDVCApi initialize() { + return adapterBuilder + .client(okBuilder.build()) + .build() + .create(IDVCApi.class); + } + + private Boolean checkIfStringNullOrEmpty(String stringToCheck) { + return Objects.isNull(stringToCheck) || Objects.equals(stringToCheck, ""); + } +} diff --git a/src/main/java/com/devcycle/sdk/server/local/bucketing/LocalBucketing.java b/src/main/java/com/devcycle/sdk/server/local/bucketing/LocalBucketing.java index dc5f5ef0..f4f6cb99 100644 --- a/src/main/java/com/devcycle/sdk/server/local/bucketing/LocalBucketing.java +++ b/src/main/java/com/devcycle/sdk/server/local/bucketing/LocalBucketing.java @@ -12,7 +12,7 @@ import java.util.concurrent.atomic.AtomicReference; import com.devcycle.sdk.server.local.model.BucketedUserConfig; -import com.devcycle.sdk.server.local.model.EventPayload; +import com.devcycle.sdk.server.local.model.FlushPayload; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -180,7 +180,7 @@ public void queueAggregateEvent(String token, String event, String variableVaria fn.accept(tokenAddress, eventAddress, variableVariationMapAddress); } - public EventPayload[] flushEventQueue(String token) throws JsonProcessingException { + public FlushPayload[] flushEventQueue(String token) throws JsonProcessingException { int tokenAddress = newWasmString(token); Func flushEventQueuePtr = linker.get(store, "", "flushEventQueue").get().func(); @@ -197,7 +197,7 @@ public EventPayload[] flushEventQueue(String token) throws JsonProcessingExcepti df.setTimeZone(TimeZone.getTimeZone("UTC")); objectMapper.setDateFormat(df); - EventPayload[] payloads = objectMapper.readValue(flushPayloadsStr, EventPayload[].class); + FlushPayload[] payloads = objectMapper.readValue(flushPayloadsStr, FlushPayload[].class); return payloads; } diff --git a/src/main/java/com/devcycle/sdk/server/local/managers/EnvironmentConfigManager.java b/src/main/java/com/devcycle/sdk/server/local/managers/EnvironmentConfigManager.java index c1732038..e484c469 100644 --- a/src/main/java/com/devcycle/sdk/server/local/managers/EnvironmentConfigManager.java +++ b/src/main/java/com/devcycle/sdk/server/local/managers/EnvironmentConfigManager.java @@ -43,8 +43,6 @@ public EnvironmentConfigManager(String environmentKey, LocalBucketing localBucke int configPollingIntervalMs = options.getConfigPollingIntervalMs(); pollingIntervalMS = configPollingIntervalMs >= MIN_INTERVALS_MS ? configPollingIntervalMs : DEFAULT_POLL_INTERVAL_MS; - - this.localBucketing = localBucketing; setupScheduler(); } diff --git a/src/main/java/com/devcycle/sdk/server/local/managers/EventQueueManager.java b/src/main/java/com/devcycle/sdk/server/local/managers/EventQueueManager.java index d39de71e..280e250c 100644 --- a/src/main/java/com/devcycle/sdk/server/local/managers/EventQueueManager.java +++ b/src/main/java/com/devcycle/sdk/server/local/managers/EventQueueManager.java @@ -1,21 +1,145 @@ package com.devcycle.sdk.server.local.managers; +import com.devcycle.sdk.server.common.api.IDVCApi; +import com.devcycle.sdk.server.common.model.*; +import com.devcycle.sdk.server.local.api.DVCLocalEventsApiClient; import com.devcycle.sdk.server.local.bucketing.LocalBucketing; +import com.devcycle.sdk.server.local.model.*; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import retrofit2.Call; +import retrofit2.Response; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; public class EventQueueManager { - private final LocalBucketing localBucketing; + private LocalBucketing localBucketing; + private final String environmentKey; + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private IDVCApi eventsApiClient; + private int flushEventsMs; + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + private boolean isFlushingEvents = false; - public EventQueueManager(LocalBucketing localBucketing) { + public EventQueueManager(LocalBucketing localBucketing, String environmentKey, DVCLocalOptions options) { this.localBucketing = localBucketing; + this.environmentKey = environmentKey; + flushEventsMs = options.getFlushEventsMs(); + + this.localBucketing.initEventQueue(environmentKey, "{}"); + + this.localBucketing.setPlatformData(User.builder().userId("java-server-sdk").build().getPlatformData().toString()); + eventsApiClient = new DVCLocalEventsApiClient(environmentKey, options).initialize(); + + OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); + + setupScheduler(); } - // TODO copy https://github.com/DevCycleHQ/js-sdks/blob/629b1f0a0d2cbed36bfe364d69f1929f645046db/sdk/nodejs/src/eventQueueAS.ts#L53 - // to fill in these functions, then call from DVCLocalClient + private void setupScheduler() { + Runnable getConfigRunnable = new Runnable() { + public void run() { + try { + flushEvents(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }; + scheduler.scheduleAtFixedRate(getConfigRunnable, 0, this.flushEventsMs, TimeUnit.MILLISECONDS); + } + + /** + * Flush events in queue to DevCycle Events API. Requeue events if flush fails + */ //flushEvents + public void flushEvents() throws Exception { + if (isFlushingEvents) return; + + if (environmentKey == null || environmentKey.equals("")) { + throw new Exception("DevCycle is not yet initialized to publish events."); + } + + FlushPayload[] flushPayloads = new FlushPayload[0]; + try { + flushPayloads = this.localBucketing.flushEventQueue(this.environmentKey); + } catch (Exception e) { + System.out.printf("DVC Error Flushing Events: %s%n", e.getMessage()); + } + + if (flushPayloads.length == 0) return; + System.out.printf("AS Flush Payloads: %s%n", Arrays.toString(flushPayloads)); + + int eventCount = 0; + isFlushingEvents = true; + for (FlushPayload payload: flushPayloads) { + eventCount += payload.eventCount; + publishEvents(this.environmentKey, payload); + } + isFlushingEvents = false; + System.out.printf("DVC Flush %d AS Events, for %d Users%n", eventCount, flushPayloads.length); + } + + /** + * Queue DVCAPIEvent for publishing to DevCycle Events API. + */ + public void queueEvent(User user, Event event) throws JsonProcessingException { + this.localBucketing.queueEvent(this.environmentKey, OBJECT_MAPPER.writeValueAsString(user), OBJECT_MAPPER.writeValueAsString(event)); + } + + /** + * Queue DVCEvent that can be aggregated together, where multiple calls are aggregated + * by incrementing the 'value' field. + */ + public void queueAggregateEvent(Event event, BucketedUserConfig bucketedConfig) throws JsonProcessingException { + if (bucketedConfig != null) { + this.localBucketing.queueAggregateEvent(this.environmentKey, OBJECT_MAPPER.writeValueAsString(event), OBJECT_MAPPER.writeValueAsString(bucketedConfig.variableVariationMap)); + } else { + this.localBucketing.queueAggregateEvent(this.environmentKey, OBJECT_MAPPER.writeValueAsString(event), "{}"); + } + } + + private void publishEvents(String environmentKey, FlushPayload flushPayload) throws InterruptedException { + Thread publishEventsThread = new Thread(new Runnable() { + @Override + public void run() { + Call response = eventsApiClient.publishEvents(EventsBatch.builder().batch(flushPayload.records).build()); + int responseCode = getResponse(response); - //queueEvent + if (responseCode == 201) { + localBucketing.onPayloadSuccess(environmentKey, flushPayload.payloadId); + } else { + System.out.printf("DVC Error Publishing Events: %d%n", responseCode); + localBucketing.onPayloadFailure(environmentKey, flushPayload.payloadId, responseCode >= 500); + } + } + }); - //queueAggregateEvent + publishEventsThread.start(); + publishEventsThread.join(); + } + + private int getResponse(Call call) { + Response response = null; + + try { + response = call.execute(); + } catch (IOException e) { + System.out.printf("DVC Events error: %s%n", e.getMessage()); + } + + if (response == null) { + return 500; + } else { + return response.code(); + } + } } diff --git a/src/main/java/com/devcycle/sdk/server/local/model/DVCLocalOptions.java b/src/main/java/com/devcycle/sdk/server/local/model/DVCLocalOptions.java index 2aea090c..74f26d48 100644 --- a/src/main/java/com/devcycle/sdk/server/local/model/DVCLocalOptions.java +++ b/src/main/java/com/devcycle/sdk/server/local/model/DVCLocalOptions.java @@ -17,5 +17,11 @@ public class DVCLocalOptions { @Builder.Default private String configCdnBaseUrl = "https://config-cdn.devcycle.com/"; + @Builder.Default + private String eventsApiBaseUrl = "https://events.devcycle.com/"; + + @Builder.Default + private int flushEventsMs = 10000; + public static class DVCLocalOptionsBuilder implements IDVCOptions { } } diff --git a/src/main/java/com/devcycle/sdk/server/local/model/EventPayload.java b/src/main/java/com/devcycle/sdk/server/local/model/EventPayload.java index cd352004..1dc01d01 100644 --- a/src/main/java/com/devcycle/sdk/server/local/model/EventPayload.java +++ b/src/main/java/com/devcycle/sdk/server/local/model/EventPayload.java @@ -1,15 +1,9 @@ package com.devcycle.sdk.server.local.model; +import com.devcycle.sdk.server.common.model.Event; import com.devcycle.sdk.server.common.model.User; public class EventPayload { - public Record[] records; - public String payloadId; - public int eventCount; - - public static class Record { - public User user; - public RequestEvent[] events; - } + private User user; + private Event[] events; } - diff --git a/src/main/java/com/devcycle/sdk/server/local/model/EventsBatch.java b/src/main/java/com/devcycle/sdk/server/local/model/EventsBatch.java new file mode 100644 index 00000000..df0c3ead --- /dev/null +++ b/src/main/java/com/devcycle/sdk/server/local/model/EventsBatch.java @@ -0,0 +1,9 @@ +package com.devcycle.sdk.server.local.model; + +import lombok.Builder; + +@Builder +public class EventsBatch { + public FlushPayload.Record[] batch; +} + diff --git a/src/main/java/com/devcycle/sdk/server/local/model/FlushPayload.java b/src/main/java/com/devcycle/sdk/server/local/model/FlushPayload.java new file mode 100644 index 00000000..14e3a791 --- /dev/null +++ b/src/main/java/com/devcycle/sdk/server/local/model/FlushPayload.java @@ -0,0 +1,34 @@ +package com.devcycle.sdk.server.local.model; + +import com.devcycle.sdk.server.common.model.User; + +import java.util.Arrays; + +public class FlushPayload { + public Record[] records; + public String payloadId; + public int eventCount; + + @Override + public String toString() { + return "EventPayload{" + + "records=" + Arrays.toString(records) + + ", payloadId='" + payloadId + '\'' + + ", eventCount=" + eventCount + + '}'; + } + + public static class Record { + @Override + public String toString() { + return "Record{" + + "user=" + user + + ", events=" + Arrays.toString(events) + + '}'; + } + + public User user; + public RequestEvent[] events; + } +} + diff --git a/src/main/java/com/devcycle/sdk/server/local/model/RequestEvent.java b/src/main/java/com/devcycle/sdk/server/local/model/RequestEvent.java index 5e06cb75..840fe173 100644 --- a/src/main/java/com/devcycle/sdk/server/local/model/RequestEvent.java +++ b/src/main/java/com/devcycle/sdk/server/local/model/RequestEvent.java @@ -1,8 +1,7 @@ package com.devcycle.sdk.server.local.model; -import com.devcycle.sdk.server.local.utils.LongTimestampDeserializer; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -10,6 +9,7 @@ import lombok.NoArgsConstructor; import java.math.BigDecimal; +import java.util.Date; import java.util.Map; @Data @@ -32,12 +32,12 @@ public class RequestEvent { private String target; @Schema(description = "Unix epoch time the event occurred according to client") - @JsonDeserialize(using = LongTimestampDeserializer.class) - private Long date; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'hh:mm:ss.SSS'Z'") + private String date; @Schema(description = "Unix epoch time the event occurred according to client") - @JsonDeserialize(using = LongTimestampDeserializer.class) - private Long clientDate; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'hh:mm:ss.SSS'Z'") + private Date clientDate; @Schema(description = "Value for numerical events. Contextual to event type") private BigDecimal value; diff --git a/src/main/resources/bucketing-lib.release.wasm b/src/main/resources/bucketing-lib.release.wasm index 1fb3f44d96361641ac5b61e8edbc3dc5f15b989d..c966e54c5cc2f112fb5baf6a3a6764caf0fe69ed 100644 GIT binary patch literal 132336 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 literal 130777 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%0D!Jd?Fv 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 getConfig(String sdkToken, String etag) { // TODO Auto-generated method stub return null; } + + @Override + public Call publishEvents(EventsBatch eventsBatch) { + // TODO Auto-generated method stub + return null; + } } diff --git a/src/test/java/com/devcycle/sdk/server/local/DVCLocalClientTest.java b/src/test/java/com/devcycle/sdk/server/local/DVCLocalClientTest.java index b64ce499..4af84ea3 100644 --- a/src/test/java/com/devcycle/sdk/server/local/DVCLocalClientTest.java +++ b/src/test/java/com/devcycle/sdk/server/local/DVCLocalClientTest.java @@ -3,6 +3,11 @@ import java.util.Map; import java.util.UUID; +import com.devcycle.sdk.server.common.api.IDVCApi; +import com.devcycle.sdk.server.common.model.Event; +import com.devcycle.sdk.server.local.api.DVCLocalEventsApiClient; +import com.devcycle.sdk.server.local.managers.EventQueueManager; +import com.devcycle.sdk.server.local.model.DVCLocalOptions; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -23,13 +28,17 @@ public class DVCLocalClientTest { private DVCLocalClient client; final String testConfigString = "{\"project\":{\"_id\":\"61f97628ff4afcb6d057dbf0\",\"key\":\"emma-project\",\"a0_organization\":\"org_tPyJN5dvNNirKar7\",\"settings\":{\"edgeDB\":{\"enabled\":false},\"optIn\":{\"enabled\":true,\"title\":\"EarlyAccess\",\"description\":\"Getearlyaccesstobetafeaturesbelow!\",\"imageURL\":\"\",\"colors\":{\"primary\":\"#531cd9\",\"secondary\":\"#16dec0\"}}}},\"environment\":{\"_id\":\"61f97628ff4afcb6d057dbf2\",\"key\":\"development\"},\"features\":[{\"_id\":\"62fbf6566f1ba302829f9e32\",\"key\":\"a-cool-new-feature\",\"type\":\"release\",\"variations\":[{\"key\":\"variation-on\",\"name\":\"VariationOn\",\"variables\":[{\"_var\":\"62fbf6566f1ba302829f9e34\",\"value\":true},{\"_var\":\"63125320a4719939fd57cb2b\",\"value\":\"variationOff\"}],\"_id\":\"62fbf6566f1ba302829f9e38\"},{\"key\":\"variation-off\",\"name\":\"VariationOff\",\"variables\":[{\"_var\":\"62fbf6566f1ba302829f9e34\",\"value\":false},{\"_var\":\"63125320a4719939fd57cb2b\",\"value\":\"variationOn\"}],\"_id\":\"62fbf6566f1ba302829f9e39\"}],\"configuration\":{\"_id\":\"62fbf6576f1ba302829f9e4d\",\"targets\":[{\"_audience\":{\"_id\":\"63125321d31c601f992288b6\",\"filters\":{\"filters\":[{\"type\":\"user\",\"subType\":\"email\",\"comparator\":\"=\",\"values\":[\"giveMeVariationOff@email.com\"],\"filters\":[]}],\"operator\":\"and\"}},\"distribution\":[{\"_variation\":\"62fbf6566f1ba302829f9e38\",\"percentage\":1}],\"_id\":\"63125321d31c601f992288bb\"},{\"_audience\":{\"_id\":\"63125321d31c601f992288b7\",\"filters\":{\"filters\":[{\"type\":\"all\",\"values\":[],\"filters\":[]}],\"operator\":\"and\"}},\"distribution\":[{\"_variation\":\"62fbf6566f1ba302829f9e39\",\"percentage\":1}],\"_id\":\"63125321d31c601f992288bc\"}],\"forcedUsers\":{}}}],\"variables\":[{\"_id\":\"62fbf6566f1ba302829f9e34\",\"key\":\"a-cool-new-feature\",\"type\":\"Boolean\"},{\"_id\":\"63125320a4719939fd57cb2b\",\"key\":\"string-var\",\"type\":\"String\"}],\"variableHashes\":{\"a-cool-new-feature\":1868656757,\"string-var\":2413071944}}"; final String apiKey = String.format("server-%s", UUID.randomUUID()); + private LocalBucketing localBucketing; + private EventQueueManager eventQueueManager; @Before public void setup() { client = new DVCLocalClient(apiKey); - LocalBucketing localBucketing = new LocalBucketing(); + localBucketing = new LocalBucketing(); localBucketing.storeConfig(apiKey, testConfigString); + eventQueueManager = new EventQueueManager(localBucketing, apiKey, DVCLocalOptions.builder().build()); WhiteBox.setInternalState(client, "localBucketing", localBucketing); + WhiteBox.setInternalState(client, "eventQueueManager", eventQueueManager); } @Test public void variableTest() { @@ -59,6 +68,12 @@ public void allVariablesTest() throws JsonProcessingException { Assert.assertEquals(variables.get("a-cool-new-feature").getId(), "62fbf6566f1ba302829f9e34"); Assert.assertEquals(variables.size(), 2); } + @Test + public void trackTest() throws Exception { + // TODO: remove test + User user = getUser(); + client.track(user, Event.builder().type("test").build()); + } private User getUser() { return User.builder() From 3aabe9d4c1bdd19a72dcc67f392976f4307627e6 Mon Sep 17 00:00:00 2001 From: Chantal Chung Date: Tue, 13 Sep 2022 11:01:07 -0700 Subject: [PATCH 2/3] remove test --- .../com/devcycle/sdk/server/local/DVCLocalClientTest.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/test/java/com/devcycle/sdk/server/local/DVCLocalClientTest.java b/src/test/java/com/devcycle/sdk/server/local/DVCLocalClientTest.java index 4af84ea3..c4a3a6a5 100644 --- a/src/test/java/com/devcycle/sdk/server/local/DVCLocalClientTest.java +++ b/src/test/java/com/devcycle/sdk/server/local/DVCLocalClientTest.java @@ -68,12 +68,6 @@ public void allVariablesTest() throws JsonProcessingException { Assert.assertEquals(variables.get("a-cool-new-feature").getId(), "62fbf6566f1ba302829f9e34"); Assert.assertEquals(variables.size(), 2); } - @Test - public void trackTest() throws Exception { - // TODO: remove test - User user = getUser(); - client.track(user, Event.builder().type("test").build()); - } private User getUser() { return User.builder() From 173731db03c07e27748b0fe1c0c346f7a504a3f9 Mon Sep 17 00:00:00 2001 From: Chantal Chung Date: Tue, 13 Sep 2022 11:14:30 -0700 Subject: [PATCH 3/3] rename to serverKey and cleanup --- .../server/local/api/DVCLocalApiClient.java | 8 +---- .../sdk/server/local/api/DVCLocalClient.java | 3 +- .../local/api/DVCLocalEventsApiClient.java | 4 +-- .../managers/EnvironmentConfigManager.java | 12 +++---- .../local/managers/EventQueueManager.java | 35 +++++++++---------- .../server/local/model/DVCLocalOptions.java | 2 +- .../sdk/server/local/DVCLocalClientTest.java | 2 +- 7 files changed, 29 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalApiClient.java b/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalApiClient.java index c16cba8f..12858bb2 100755 --- a/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalApiClient.java +++ b/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalApiClient.java @@ -52,7 +52,7 @@ private DVCLocalApiClient(DVCLocalOptions options) { .addConverterFactory(JacksonConverterFactory.create()); } - public DVCLocalApiClient(String apiKey, DVCLocalOptions options) { + public DVCLocalApiClient(String serverKey, DVCLocalOptions options) { this(options); } @@ -66,10 +66,4 @@ public IDVCApi initialize() { private Boolean checkIfStringNullOrEmpty(String stringToCheck) { return Objects.isNull(stringToCheck) || Objects.equals(stringToCheck, ""); } - - public void publishEvents(String environmentKey, FlushPayload.Record[] eventsBatch) throws Exception { - if (environmentKey == null || environmentKey.equals("")) { - throw new Exception("DevCycle is not yet initialized to publish events."); - } - } } diff --git a/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalClient.java b/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalClient.java index e9b1d4f9..e9e6ef43 100755 --- a/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalClient.java +++ b/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalClient.java @@ -33,7 +33,7 @@ public DVCLocalClient(String serverKey, DVCLocalOptions dvcOptions) { configManager = new EnvironmentConfigManager(serverKey, localBucketing, dvcOptions); this.serverKey = serverKey; OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); - eventQueueManager = new EventQueueManager(localBucketing, serverKey, dvcOptions); + eventQueueManager = new EventQueueManager(serverKey, localBucketing, dvcOptions); } /** @@ -132,7 +132,6 @@ public void track(User user, Event event) throws Exception { localBucketing.setPlatformData(user.getPlatformData().toString()); eventQueueManager.queueEvent(user, event); - eventQueueManager.flushEvents(); } private void validateUser(User user) { diff --git a/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalEventsApiClient.java b/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalEventsApiClient.java index 84859555..4208cb63 100644 --- a/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalEventsApiClient.java +++ b/src/main/java/com/devcycle/sdk/server/local/api/DVCLocalEventsApiClient.java @@ -43,9 +43,9 @@ private DVCLocalEventsApiClient(DVCLocalOptions options) { .addConverterFactory(JacksonConverterFactory.create()); } - public DVCLocalEventsApiClient(String apiKey, DVCLocalOptions options) { + public DVCLocalEventsApiClient(String serverKey, DVCLocalOptions options) { this(options); - okBuilder.addInterceptor(new AuthorizationHeaderInterceptor(apiKey)); + okBuilder.addInterceptor(new AuthorizationHeaderInterceptor(serverKey)); logging.setLevel(Level.BODY); okBuilder.addInterceptor(logging); diff --git a/src/main/java/com/devcycle/sdk/server/local/managers/EnvironmentConfigManager.java b/src/main/java/com/devcycle/sdk/server/local/managers/EnvironmentConfigManager.java index e484c469..84b583a8 100644 --- a/src/main/java/com/devcycle/sdk/server/local/managers/EnvironmentConfigManager.java +++ b/src/main/java/com/devcycle/sdk/server/local/managers/EnvironmentConfigManager.java @@ -31,14 +31,14 @@ public final class EnvironmentConfigManager { private ProjectConfig config; private String configETag = ""; - private String environmentKey; + private String serverKey; private int pollingIntervalMS; - public EnvironmentConfigManager(String environmentKey, LocalBucketing localBucketing, DVCLocalOptions options) { - this.environmentKey = environmentKey; + public EnvironmentConfigManager(String serverKey, LocalBucketing localBucketing, DVCLocalOptions options) { + this.serverKey = serverKey; this.localBucketing = localBucketing; - configApiClient = new DVCLocalApiClient(environmentKey, options).initialize(); + configApiClient = new DVCLocalApiClient(serverKey, options).initialize(); int configPollingIntervalMs = options.getConfigPollingIntervalMs(); pollingIntervalMS = configPollingIntervalMs >= MIN_INTERVALS_MS ? configPollingIntervalMs @@ -66,7 +66,7 @@ public boolean isConfigInitialized() { } private ProjectConfig getConfig() throws DVCException, JsonProcessingException { - Call config = this.configApiClient.getConfig(this.environmentKey, this.configETag); + Call config = this.configApiClient.getConfig(this.serverKey, this.configETag); this.config = getConfigResponse(config); return this.config; @@ -91,7 +91,7 @@ private ProjectConfig getConfigResponse(Call call) throws DVCExce ProjectConfig config = response.body(); try { ObjectMapper mapper = new ObjectMapper(); - localBucketing.storeConfig(environmentKey, mapper.writeValueAsString(config)); + localBucketing.storeConfig(serverKey, mapper.writeValueAsString(config)); } catch (JsonProcessingException e) { if (this.config != null) { System.out.printf("Unable to parse config with etag: %s. Using cache, etag %s%n", currentETag, this.configETag); diff --git a/src/main/java/com/devcycle/sdk/server/local/managers/EventQueueManager.java b/src/main/java/com/devcycle/sdk/server/local/managers/EventQueueManager.java index 280e250c..afef8af8 100644 --- a/src/main/java/com/devcycle/sdk/server/local/managers/EventQueueManager.java +++ b/src/main/java/com/devcycle/sdk/server/local/managers/EventQueueManager.java @@ -13,7 +13,6 @@ import java.io.IOException; import java.util.Arrays; -import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -21,22 +20,22 @@ public class EventQueueManager { private LocalBucketing localBucketing; - private final String environmentKey; + private final String serverKey; private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private IDVCApi eventsApiClient; - private int flushEventsMs; + private int eventFlushIntervalMS; private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); private boolean isFlushingEvents = false; - public EventQueueManager(LocalBucketing localBucketing, String environmentKey, DVCLocalOptions options) { + public EventQueueManager(String serverKey, LocalBucketing localBucketing, DVCLocalOptions options) { this.localBucketing = localBucketing; - this.environmentKey = environmentKey; - flushEventsMs = options.getFlushEventsMs(); + this.serverKey = serverKey; + eventFlushIntervalMS = options.getEventFlushIntervalMS(); - this.localBucketing.initEventQueue(environmentKey, "{}"); + this.localBucketing.initEventQueue(serverKey, "{}"); this.localBucketing.setPlatformData(User.builder().userId("java-server-sdk").build().getPlatformData().toString()); - eventsApiClient = new DVCLocalEventsApiClient(environmentKey, options).initialize(); + eventsApiClient = new DVCLocalEventsApiClient(serverKey, options).initialize(); OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); @@ -54,7 +53,7 @@ public void run() { } }; - scheduler.scheduleAtFixedRate(getConfigRunnable, 0, this.flushEventsMs, TimeUnit.MILLISECONDS); + scheduler.scheduleAtFixedRate(getConfigRunnable, 0, this.eventFlushIntervalMS, TimeUnit.MILLISECONDS); } /** @@ -64,13 +63,13 @@ public void run() { public void flushEvents() throws Exception { if (isFlushingEvents) return; - if (environmentKey == null || environmentKey.equals("")) { + if (serverKey == null || serverKey.equals("")) { throw new Exception("DevCycle is not yet initialized to publish events."); } FlushPayload[] flushPayloads = new FlushPayload[0]; try { - flushPayloads = this.localBucketing.flushEventQueue(this.environmentKey); + flushPayloads = this.localBucketing.flushEventQueue(this.serverKey); } catch (Exception e) { System.out.printf("DVC Error Flushing Events: %s%n", e.getMessage()); } @@ -82,7 +81,7 @@ public void flushEvents() throws Exception { isFlushingEvents = true; for (FlushPayload payload: flushPayloads) { eventCount += payload.eventCount; - publishEvents(this.environmentKey, payload); + publishEvents(this.serverKey, payload); } isFlushingEvents = false; System.out.printf("DVC Flush %d AS Events, for %d Users%n", eventCount, flushPayloads.length); @@ -92,7 +91,7 @@ public void flushEvents() throws Exception { * Queue DVCAPIEvent for publishing to DevCycle Events API. */ public void queueEvent(User user, Event event) throws JsonProcessingException { - this.localBucketing.queueEvent(this.environmentKey, OBJECT_MAPPER.writeValueAsString(user), OBJECT_MAPPER.writeValueAsString(event)); + this.localBucketing.queueEvent(this.serverKey, OBJECT_MAPPER.writeValueAsString(user), OBJECT_MAPPER.writeValueAsString(event)); } /** @@ -101,13 +100,13 @@ public void queueEvent(User user, Event event) throws JsonProcessingException { */ public void queueAggregateEvent(Event event, BucketedUserConfig bucketedConfig) throws JsonProcessingException { if (bucketedConfig != null) { - this.localBucketing.queueAggregateEvent(this.environmentKey, OBJECT_MAPPER.writeValueAsString(event), OBJECT_MAPPER.writeValueAsString(bucketedConfig.variableVariationMap)); + this.localBucketing.queueAggregateEvent(this.serverKey, OBJECT_MAPPER.writeValueAsString(event), OBJECT_MAPPER.writeValueAsString(bucketedConfig.variableVariationMap)); } else { - this.localBucketing.queueAggregateEvent(this.environmentKey, OBJECT_MAPPER.writeValueAsString(event), "{}"); + this.localBucketing.queueAggregateEvent(this.serverKey, OBJECT_MAPPER.writeValueAsString(event), "{}"); } } - private void publishEvents(String environmentKey, FlushPayload flushPayload) throws InterruptedException { + private void publishEvents(String serverKey, FlushPayload flushPayload) throws InterruptedException { Thread publishEventsThread = new Thread(new Runnable() { @Override public void run() { @@ -115,10 +114,10 @@ public void run() { int responseCode = getResponse(response); if (responseCode == 201) { - localBucketing.onPayloadSuccess(environmentKey, flushPayload.payloadId); + localBucketing.onPayloadSuccess(serverKey, flushPayload.payloadId); } else { System.out.printf("DVC Error Publishing Events: %d%n", responseCode); - localBucketing.onPayloadFailure(environmentKey, flushPayload.payloadId, responseCode >= 500); + localBucketing.onPayloadFailure(serverKey, flushPayload.payloadId, responseCode >= 500); } } }); diff --git a/src/main/java/com/devcycle/sdk/server/local/model/DVCLocalOptions.java b/src/main/java/com/devcycle/sdk/server/local/model/DVCLocalOptions.java index 74f26d48..99fb3316 100644 --- a/src/main/java/com/devcycle/sdk/server/local/model/DVCLocalOptions.java +++ b/src/main/java/com/devcycle/sdk/server/local/model/DVCLocalOptions.java @@ -21,7 +21,7 @@ public class DVCLocalOptions { private String eventsApiBaseUrl = "https://events.devcycle.com/"; @Builder.Default - private int flushEventsMs = 10000; + private int eventFlushIntervalMS = 10000; public static class DVCLocalOptionsBuilder implements IDVCOptions { } } diff --git a/src/test/java/com/devcycle/sdk/server/local/DVCLocalClientTest.java b/src/test/java/com/devcycle/sdk/server/local/DVCLocalClientTest.java index c4a3a6a5..c04af5e0 100644 --- a/src/test/java/com/devcycle/sdk/server/local/DVCLocalClientTest.java +++ b/src/test/java/com/devcycle/sdk/server/local/DVCLocalClientTest.java @@ -36,7 +36,7 @@ public void setup() { client = new DVCLocalClient(apiKey); localBucketing = new LocalBucketing(); localBucketing.storeConfig(apiKey, testConfigString); - eventQueueManager = new EventQueueManager(localBucketing, apiKey, DVCLocalOptions.builder().build()); + eventQueueManager = new EventQueueManager(apiKey, localBucketing, DVCLocalOptions.builder().build()); WhiteBox.setInternalState(client, "localBucketing", localBucketing); WhiteBox.setInternalState(client, "eventQueueManager", eventQueueManager); }