diff --git a/litmus-client/pom.xml b/litmus-client/pom.xml
index a8b779e..8b79263 100644
--- a/litmus-client/pom.xml
+++ b/litmus-client/pom.xml
@@ -40,12 +40,6 @@
-
-
-
-
-
-
com.navi.medici
litmus-model
@@ -76,6 +70,13 @@
2.13.0
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+ 2.13.0
+
+
+
diff --git a/litmus-client/src/main/java/com/navi/medici/client/ExperimentBackupHandlerFile.java b/litmus-client/src/main/java/com/navi/medici/client/ExperimentBackupHandlerFile.java
index 0b0fbcc..7266408 100644
--- a/litmus-client/src/main/java/com/navi/medici/client/ExperimentBackupHandlerFile.java
+++ b/litmus-client/src/main/java/com/navi/medici/client/ExperimentBackupHandlerFile.java
@@ -13,6 +13,7 @@ import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.core.util.IOUtils;
@Log4j2
@@ -28,7 +29,14 @@ public class ExperimentBackupHandlerFile implements ExperimentBackupHandler {
public LitmusExperimentCollection read() {
log.info("Litmus will try to load experiments states from temporary backup");
try (FileReader reader = new FileReader(backupFile)) {
- return JacksonUtils.stringToObject(IOUtils.toString(reader), LitmusExperimentCollection.class);
+ var data = IOUtils.toString(reader);
+ if (StringUtils.isBlank(data)) {
+ List emptyList = Collections.emptyList();
+ return LitmusExperimentCollection.builder()
+ .litmusExperiments(emptyList)
+ .build();
+ }
+ return JacksonUtils.stringToObject(data, LitmusExperimentCollection.class);
} catch (FileNotFoundException e) {
log.info(
" Litmus could not find the backup-file '"
diff --git a/litmus-client/src/main/java/com/navi/medici/util/JacksonUtils.java b/litmus-client/src/main/java/com/navi/medici/util/JacksonUtils.java
index 1f4c75d..f8f4cfb 100644
--- a/litmus-client/src/main/java/com/navi/medici/util/JacksonUtils.java
+++ b/litmus-client/src/main/java/com/navi/medici/util/JacksonUtils.java
@@ -11,7 +11,9 @@ import lombok.extern.log4j.Log4j2;
public class JacksonUtils {
public static String objectToString(Object o) {
try {
- return new ObjectMapper().writeValueAsString(o);
+ var objectMapper = new ObjectMapper();
+ objectMapper.findAndRegisterModules();
+ return objectMapper.writeValueAsString(o);
} catch (JsonProcessingException e) {
throw new RuntimeException("object to string conversion failed", e);
}
@@ -19,7 +21,9 @@ public class JacksonUtils {
public static T stringToObject(String s, Class klazz) {
try {
- return new ObjectMapper().readValue(s, klazz);
+ var objectMapper = new ObjectMapper();
+ objectMapper.findAndRegisterModules();
+ return objectMapper.readValue(s, klazz);
} catch (JsonProcessingException e) {
throw new RuntimeException("string to object conversion failed", e);
}
@@ -27,9 +31,12 @@ public class JacksonUtils {
public static List stringToListObject(String s, Class klazz) {
try {
- CollectionType listType = new ObjectMapper().getTypeFactory().constructCollectionType(ArrayList.class, klazz);
+ var objectMapper = new ObjectMapper();
+ objectMapper.findAndRegisterModules();
- return new ObjectMapper().readValue(s, listType);
+ CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, klazz);
+
+ return objectMapper.readValue(s, listType);
} catch (JsonProcessingException e) {
throw new RuntimeException("string to list object conversion failed", e);
}
diff --git a/litmus-client/src/main/java/com/navi/medici/util/VariantUtil.java b/litmus-client/src/main/java/com/navi/medici/util/VariantUtil.java
index d2068db..7c0b099 100644
--- a/litmus-client/src/main/java/com/navi/medici/util/VariantUtil.java
+++ b/litmus-client/src/main/java/com/navi/medici/util/VariantUtil.java
@@ -9,6 +9,7 @@ import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.function.Predicate;
+import org.apache.commons.lang3.StringUtils;
public final class VariantUtil {
private VariantUtil() {}
@@ -80,7 +81,7 @@ public final class VariantUtil {
}
public static Variant selectVariant(LitmusExperiment litmusExperiment, LitmusContext context, Variant defaultVariant) {
- if (litmusExperiment == null) {
+ if (litmusExperiment == null || StringUtils.isBlank(litmusExperiment.getVariants())) {
return defaultVariant;
}
List variants = JacksonUtils.stringToListObject(litmusExperiment.getVariants(), VariantDefinition.class);
diff --git a/litmus-core/pom.xml b/litmus-core/pom.xml
index 136d430..f8ace9c 100644
--- a/litmus-core/pom.xml
+++ b/litmus-core/pom.xml
@@ -85,6 +85,12 @@
opencsv
5.5.2
+
+
+ io.springfox
+ springfox-boot-starter
+ 3.0.0
+
diff --git a/litmus-core/src/main/java/com/navi/medici/config/SwaggerConfig.java b/litmus-core/src/main/java/com/navi/medici/config/SwaggerConfig.java
new file mode 100644
index 0000000..490a705
--- /dev/null
+++ b/litmus-core/src/main/java/com/navi/medici/config/SwaggerConfig.java
@@ -0,0 +1,24 @@
+package com.navi.medici.config;
+
+import static springfox.documentation.builders.PathSelectors.regex;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@EnableSwagger2
+@Configuration
+public class SwaggerConfig {
+
+ @Bean
+ public Docket configureSwagger() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .select()
+ .apis(RequestHandlerSelectors.any())
+ .paths(regex("/litmus-core/v1/.*"))
+ .build();
+ }
+}
diff --git a/litmus-core/src/main/java/com/navi/medici/controller/v1/ExperimentController.java b/litmus-core/src/main/java/com/navi/medici/controller/v1/ExperimentController.java
index b32433b..118d43c 100644
--- a/litmus-core/src/main/java/com/navi/medici/controller/v1/ExperimentController.java
+++ b/litmus-core/src/main/java/com/navi/medici/controller/v1/ExperimentController.java
@@ -42,7 +42,7 @@ public class ExperimentController {
@PutMapping(value = "/attach/variants/{experiment_id}", consumes = MediaType.APPLICATION_JSON_VALUE)
public void attachVariants(@PathVariable("experiment_id") String experimentId,
@RequestBody List variantDefinitions) {
-
+ experimentService.attachVariants(experimentId, variantDefinitions);
}
}
diff --git a/litmus-core/src/main/java/com/navi/medici/service/experiment/ExperimentServiceImpl.java b/litmus-core/src/main/java/com/navi/medici/service/experiment/ExperimentServiceImpl.java
index 5c2e649..237ac0e 100644
--- a/litmus-core/src/main/java/com/navi/medici/service/experiment/ExperimentServiceImpl.java
+++ b/litmus-core/src/main/java/com/navi/medici/service/experiment/ExperimentServiceImpl.java
@@ -74,6 +74,7 @@ public class ExperimentServiceImpl implements ExperimentService {
.enabled(experimentEntity.getEnabled())
.archived(experimentEntity.getArchived())
.strategies(jacksonUtils.stringToListObject(experimentEntity.getStrategies(), ActivationStrategy.class))
+ .variants(experimentEntity.getVariants())
.type(experimentEntity.getType())
.startTime(experimentEntity.getStartTime())
.endTime(experimentEntity.getEndTime())
diff --git a/litmus-mock/src/main/java/com/navi/medici/container/CustomLitmusContextProvider.java b/litmus-mock/src/main/java/com/navi/medici/container/CustomLitmusContextProvider.java
index d17b56c..c82b9da 100644
--- a/litmus-mock/src/main/java/com/navi/medici/container/CustomLitmusContextProvider.java
+++ b/litmus-mock/src/main/java/com/navi/medici/container/CustomLitmusContextProvider.java
@@ -2,6 +2,7 @@ package com.navi.medici.container;
import com.navi.medici.context.LitmusContext;
import com.navi.medici.provider.LitmusContextProvider;
+import java.util.Random;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.RequestScope;
@@ -15,8 +16,7 @@ public class CustomLitmusContextProvider implements LitmusContextProvider {
public LitmusContext getContext() {
return LitmusContext.builder()
.clickStreamPayload(null)
- .userId("test123")
-
+ .userId(new Random().nextInt() + "")
.build();
}
}
\ No newline at end of file
diff --git a/litmus-mock/src/main/java/com/navi/medici/container/MockContainer.java b/litmus-mock/src/main/java/com/navi/medici/container/MockContainer.java
index f5e5512..286c420 100644
--- a/litmus-mock/src/main/java/com/navi/medici/container/MockContainer.java
+++ b/litmus-mock/src/main/java/com/navi/medici/container/MockContainer.java
@@ -12,7 +12,7 @@ public class MockContainer {
@Bean
public Litmus litmus() {
var litmusConfig = LitmusConfig.builder()
- .litmusAPI("http://localhost:12000/v1")
+ .litmusAPI("http://localhost:12000/litmus-core/v1")
.appName("litmus-mock")
.instanceId("test-instance")
.litmusContextProvider(new CustomLitmusContextProvider())
diff --git a/litmus-mock/src/main/java/com/navi/medici/controller/MockController.java b/litmus-mock/src/main/java/com/navi/medici/controller/MockController.java
index ca5d639..da57290 100644
--- a/litmus-mock/src/main/java/com/navi/medici/controller/MockController.java
+++ b/litmus-mock/src/main/java/com/navi/medici/controller/MockController.java
@@ -2,6 +2,7 @@ package com.navi.medici.controller;
import com.navi.medici.context.LitmusContext;
import com.navi.medici.litmus.Litmus;
+import com.navi.medici.variants.Variant;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.web.bind.annotation.GetMapping;
@@ -23,4 +24,12 @@ public class MockController {
return "result ==> " + result;
}
+
+ @GetMapping("/variants/mock")
+ public Variant variants(@RequestParam("experiment") String experiment) {
+ var result = litmus.getVariant(experiment);
+
+ log.info("response ===> {}", result.toString());
+ return result;
+ }
}
diff --git a/litmus-model/src/main/java/com/navi/medici/variants/Payload.java b/litmus-model/src/main/java/com/navi/medici/variants/Payload.java
index 135f75f..9afbb4a 100644
--- a/litmus-model/src/main/java/com/navi/medici/variants/Payload.java
+++ b/litmus-model/src/main/java/com/navi/medici/variants/Payload.java
@@ -7,6 +7,7 @@ import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
+import lombok.ToString;
import lombok.experimental.FieldDefaults;
@AllArgsConstructor
@@ -16,6 +17,7 @@ import lombok.experimental.FieldDefaults;
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
@FieldDefaults(level = AccessLevel.PRIVATE)
+@ToString
public class Payload {
String type;
String value;
diff --git a/litmus-model/src/main/java/com/navi/medici/variants/Variant.java b/litmus-model/src/main/java/com/navi/medici/variants/Variant.java
index 02b60c1..1aa575c 100644
--- a/litmus-model/src/main/java/com/navi/medici/variants/Variant.java
+++ b/litmus-model/src/main/java/com/navi/medici/variants/Variant.java
@@ -7,6 +7,7 @@ import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
+import lombok.ToString;
import lombok.experimental.FieldDefaults;
@AllArgsConstructor
@@ -16,6 +17,7 @@ import lombok.experimental.FieldDefaults;
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
@FieldDefaults(level = AccessLevel.PRIVATE)
+@ToString
public class Variant {
String name;
Payload payload;
diff --git a/litmus-proxy/src/main/java/com/navi/medici/controller/HealthCheckController.java b/litmus-proxy/src/main/java/com/navi/medici/controller/HealthCheckController.java
new file mode 100644
index 0000000..c4d1ddf
--- /dev/null
+++ b/litmus-proxy/src/main/java/com/navi/medici/controller/HealthCheckController.java
@@ -0,0 +1,26 @@
+package com.navi.medici.controller;
+
+import com.navi.medici.util.JacksonUtils;
+import java.util.HashMap;
+import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+@RestController
+@RequestMapping("/health")
+@RequiredArgsConstructor
+public class HealthCheckController {
+
+ @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
+ public ResponseEntity> ping() {
+ Map map = new HashMap<>();
+ map.put("status", "Ok");
+
+ return ResponseEntity.ok(JacksonUtils.objectToString(map));
+ }
+}
\ No newline at end of file