litmus proxy batch experiment/variants api

This commit is contained in:
chandresh pancholi
2022-05-06 15:40:44 +05:30
parent e28eb85a38
commit 0528d665d8
23 changed files with 225 additions and 43 deletions

View File

@@ -1,5 +1,5 @@
FROM 193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/maven:3.8.3-openjdk-17-slim as builder
ARG ARTIFACT_VERSION=2.0.2-SNAPSHOT
ARG ARTIFACT_VERSION=2.0.3-SNAPSHOT
RUN mkdir -p /build
WORKDIR /build
COPY . /build
@@ -7,7 +7,7 @@ RUN mvn clean install -DskipTests
RUN mvn clean verify -DskipTests -Dartifact.version=${ARTIFACT_VERSION}
FROM 193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/openjdk:17-slim-bullseye
ARG ARTIFACT_VERSION=2.0.2-SNAPSHOT
ARG ARTIFACT_VERSION=2.0.3-SNAPSHOT
RUN mkdir -p /usr/local
RUN apt-get update -y && apt-get -y install fontconfig libpng-dev
WORKDIR /usr/local/

View File

@@ -1,5 +1,5 @@
FROM 193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/maven:3.8.3-openjdk-17-slim as builder
ARG ARTIFACT_VERSION=2.0.2-SNAPSHOT
ARG ARTIFACT_VERSION=2.0.3-SNAPSHOT
RUN mkdir -p /build
WORKDIR /build
COPY . /build
@@ -7,7 +7,7 @@ RUN mvn clean install -DskipTests
RUN mvn clean verify -DskipTests -Dartifact.version=${ARTIFACT_VERSION}
FROM 193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/openjdk:17-slim-bullseye
ARG ARTIFACT_VERSION=2.0.2-SNAPSHOT
ARG ARTIFACT_VERSION=2.0.3-SNAPSHOT
RUN mkdir -p /usr/local
RUN apt-get update -y && apt-get -y install fontconfig libpng-dev
WORKDIR /usr/local/

View File

@@ -4,11 +4,11 @@
<parent>
<artifactId>litmus</artifactId>
<groupId>com.navi.medici</groupId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</parent>
<artifactId>litmus-cache</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<packaging>jar</packaging>
<name>litmus-cache</name>

View File

@@ -5,11 +5,11 @@
<parent>
<artifactId>litmus</artifactId>
<groupId>com.navi.medici</groupId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</parent>
<artifactId>litmus-client</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<packaging>jar</packaging>
<name>litmus-client</name>
@@ -43,7 +43,7 @@
<dependency>
<groupId>com.navi.medici</groupId>
<artifactId>litmus-model</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</dependency>
<dependency>

View File

@@ -5,6 +5,7 @@ import com.navi.medici.clickstream.ClickStreamPayload;
import com.navi.medici.config.LitmusConfig;
import com.navi.medici.response.LitmusExperimentResponse;
import com.navi.medici.util.JacksonUtils;
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import lombok.extern.log4j.Log4j2;
@@ -32,6 +33,7 @@ public class ClickStreamClient {
this.meterRegistry = meterRegistry;
}
@Timed(value = "litmus_client_click_stream_publish_latency", percentiles = {0.90, 0.95, 0.99})
public <T> void publish(String experimentName, ClickStreamPayload<T> payload) {
String requestBody = JacksonUtils.objectToString(payload);
Request request = new Request.Builder()
@@ -56,15 +58,14 @@ public class ClickStreamClient {
log.error("clickstream ingestion received non-2xx. status: {}", response.code());
}
} catch (Exception e) {
Counter.builder("litmus_client_click_stream_event_ingestion")
log.error("clickstream event ingestion failed. ", e);
Counter.builder("litmus_client_click_stream_event_ingestion_failed")
.tag("vertical", vertical)
.tag("experiment_name", experimentName)
.tag("app_name", appName)
.tag("exception", e.getMessage())
.register(meterRegistry)
.increment();
log.error("clickstream event ingestion failed. ", e);
}
}
}

View File

@@ -7,6 +7,7 @@ import com.navi.medici.response.LitmusExperimentResponse;
import com.navi.medici.response.LitmusResponse;
import com.navi.medici.util.JacksonUtils;
import com.navi.medici.util.LitmusURLs;
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import java.net.URL;
@@ -40,6 +41,7 @@ public class HttpExperimentFetcher implements ExperimentFetcher {
}
@Override
@Timed(value = "litmus_client_fetch_experiments_latency", percentiles = {0.90, 0.95, 0.99})
public LitmusExperimentResponse fetchExperiments(String vertical, Long pollingTime) throws LitmusException {
URL experimentUrl = litmusURLs
.getLitmusExperimentsURL(projectName, projectNamePrefix);
@@ -100,6 +102,7 @@ public class HttpExperimentFetcher implements ExperimentFetcher {
}
}
@Timed(value = "litmus_client_segment_id_exists_latency", percentiles = {0.90, 0.95, 0.99})
public LitmusResponse<?> segmentIdExists(String segmentName, String id) {
URL segmentIdUrl = this.litmusURLs.getSegmentIdURL();
Request request = new Request.Builder()

View File

@@ -17,7 +17,7 @@ public class OkHttpClientContainer {
okHttpClient = new OkHttpClient.Builder()
.readTimeout(1, TimeUnit.SECONDS)
.callTimeout(1, TimeUnit.SECONDS)
.connectTimeout(1, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
.build();
}
}

View File

@@ -5,11 +5,11 @@
<parent>
<artifactId>litmus</artifactId>
<groupId>com.navi.medici</groupId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</parent>
<artifactId>litmus-core</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<packaging>jar</packaging>
<name>litmus-core</name>
@@ -31,25 +31,25 @@
<dependency>
<groupId>com.navi.medici</groupId>
<artifactId>litmus-model</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.navi.medici</groupId>
<artifactId>litmus-db</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.navi.medici</groupId>
<artifactId>litmus-cache</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.navi.medici</groupId>
<artifactId>litmus-util</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</dependency>
<dependency>

View File

@@ -4,11 +4,11 @@
<parent>
<artifactId>litmus</artifactId>
<groupId>com.navi.medici</groupId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</parent>
<artifactId>litmus-db</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<packaging>jar</packaging>
<name>litmus-db</name>
@@ -27,7 +27,7 @@
<dependency>
<groupId>com.navi.medici</groupId>
<artifactId>litmus-model</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@@ -4,11 +4,11 @@
<parent>
<artifactId>litmus</artifactId>
<groupId>com.navi.medici</groupId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</parent>
<artifactId>litmus-liquibase</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<packaging>jar</packaging>
<name>litmus-liquibase</name>

View File

@@ -4,11 +4,11 @@
<parent>
<artifactId>litmus</artifactId>
<groupId>com.navi.medici</groupId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</parent>
<artifactId>litmus-mock</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<packaging>jar</packaging>
<name>litmus-mock</name>
@@ -16,13 +16,13 @@
<dependency>
<groupId>com.navi.medici</groupId>
<artifactId>litmus-model</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.navi.medici</groupId>
<artifactId>litmus-client</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</dependency>
<dependency>

View File

@@ -5,11 +5,11 @@
<parent>
<artifactId>litmus</artifactId>
<groupId>com.navi.medici</groupId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</parent>
<artifactId>litmus-model</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<packaging>jar</packaging>
<name>litmus-model</name>

View File

@@ -4,11 +4,11 @@
<parent>
<artifactId>litmus</artifactId>
<groupId>com.navi.medici</groupId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</parent>
<artifactId>litmus-proxy</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<packaging>jar</packaging>
<name>litmus-proxy</name>
@@ -17,13 +17,13 @@
<dependency>
<groupId>com.navi.medici</groupId>
<artifactId>litmus-model</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.navi.medici</groupId>
<artifactId>litmus-client</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</dependency>
<dependency>
@@ -31,8 +31,6 @@
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
@@ -44,6 +42,12 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.8</version>
</dependency>
</dependencies>
<build>

View File

@@ -1,12 +1,16 @@
package com.navi.medici.controller;
import com.navi.medici.litmus.Litmus;
import com.navi.medici.model.request.v1.FetchBatchExperimentRequest;
import com.navi.medici.model.request.v1.FetchBatchVariantRequest;
import com.navi.medici.service.LitmusService;
import io.micrometer.core.annotation.Timed;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@@ -14,12 +18,12 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/v1/proxy")
@Log4j2
public record LitmusProxyController(Litmus litmus) {
public record LitmusProxyController(Litmus litmus, LitmusService litmusService) {
@GetMapping(value = "/experiment", produces = MediaType.APPLICATION_JSON_VALUE)
@Timed(value = "litmus.proxy.fetch.experiment", percentiles = {0.95, 0.99}, extraTags = {"mt", "fetch"} )
public ResponseEntity<?> fetch(@RequestParam("name") String experimentName) {
var result = litmus.isEnabled(experimentName);
var result = litmusService.fetchExperimentResponse(experimentName);
return ResponseEntity.ok(result);
}
@@ -27,9 +31,24 @@ public record LitmusProxyController(Litmus litmus) {
@GetMapping(value = "/variant", produces = MediaType.APPLICATION_JSON_VALUE)
@Timed(value = "litmus.proxy.fetch.experiment", percentiles = {0.95, 0.99}, extraTags = {"mt", "fetchVariants"})
public ResponseEntity<?> fetchVariants(@RequestParam("name") String variantName) {
var variant = litmus.getVariant(variantName);
var variant = litmusService.fetchVariant(variantName);
return ResponseEntity.ok(variant);
}
@PostMapping(value = "/batch/experiments", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> fetchBatchExperiment(@RequestBody FetchBatchExperimentRequest fetchBatchExperimentRequest) {
var response = litmusService.batchExperimentResponse(fetchBatchExperimentRequest);
return ResponseEntity.ok(response);
}
@PostMapping(value = "/batch/variants", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> fetchBatchVariantExperiment(@RequestBody FetchBatchVariantRequest fetchBatchVariantRequest) {
var response = litmusService.batchVariantResponse(fetchBatchVariantRequest);
return ResponseEntity.ok(response);
}
}

View File

@@ -0,0 +1,19 @@
package com.navi.medici.model.request.v1;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class ExperimentResponse {
String experimentName;
Boolean response;
}

View File

@@ -0,0 +1,17 @@
package com.navi.medici.model.request.v1;
import com.navi.medici.variants.Variant;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ExperimentVariantResponse {
String experimentName;
Variant variant;
}

View File

@@ -0,0 +1,20 @@
package com.navi.medici.model.request.v1;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
public class FetchBatchExperimentRequest {
@JsonProperty("experiment_names")
List<String> experimentNames;
}

View File

@@ -0,0 +1,20 @@
package com.navi.medici.model.request.v1;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
public class FetchBatchVariantRequest {
@JsonProperty("experiment_names")
List<String> experimentNames;
}

View File

@@ -0,0 +1,17 @@
package com.navi.medici.service;
import com.navi.medici.model.request.v1.ExperimentResponse;
import com.navi.medici.model.request.v1.ExperimentVariantResponse;
import com.navi.medici.model.request.v1.FetchBatchExperimentRequest;
import com.navi.medici.model.request.v1.FetchBatchVariantRequest;
import java.util.List;
public interface LitmusService {
List<ExperimentResponse> batchExperimentResponse(FetchBatchExperimentRequest fetchBatchExperimentRequest);
ExperimentResponse fetchExperimentResponse(String experimentName);
ExperimentVariantResponse fetchVariant(String experimentName);
List<ExperimentVariantResponse> batchVariantResponse(FetchBatchVariantRequest fetchBatchVariantRequest);
}

View File

@@ -0,0 +1,61 @@
package com.navi.medici.service;
import com.navi.medici.litmus.Litmus;
import com.navi.medici.model.request.v1.ExperimentResponse;
import com.navi.medici.model.request.v1.ExperimentVariantResponse;
import com.navi.medici.model.request.v1.FetchBatchExperimentRequest;
import com.navi.medici.model.request.v1.FetchBatchVariantRequest;
import java.util.List;
import java.util.stream.Collectors;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
@Service
@Log4j2
public record LitmusServiceImpl(Litmus litmus) implements LitmusService {
@Override
public List<ExperimentResponse> batchExperimentResponse(FetchBatchExperimentRequest fetchBatchExperimentRequest) {
return fetchBatchExperimentRequest.getExperimentNames().stream().map(experimentName -> {
var result = litmus.isEnabled(experimentName);
return ExperimentResponse.builder()
.response(result)
.experimentName(experimentName)
.build();
}).collect(Collectors.toList());
}
@Override
public ExperimentResponse fetchExperimentResponse(String experimentName) {
var result = litmus.isEnabled(experimentName);
return ExperimentResponse.builder()
.experimentName(experimentName)
.response(result)
.build();
}
@Override
public ExperimentVariantResponse fetchVariant(String experimentName) {
var result = litmus.getVariant(experimentName);
return ExperimentVariantResponse.builder()
.variant(result)
.experimentName(experimentName)
.build();
}
@Override
public List<ExperimentVariantResponse> batchVariantResponse(FetchBatchVariantRequest fetchBatchVariantRequest) {
return fetchBatchVariantRequest.getExperimentNames().stream().map(experimentName -> {
var result = litmus.getVariant(experimentName);
return ExperimentVariantResponse.builder()
.variant(result)
.experimentName(experimentName)
.build();
}).collect(Collectors.toList());
}
}

View File

@@ -11,3 +11,4 @@ management.metrics.kafka.producer.enabled=true
litmus.api.endpoint=${LITMUS_API_ENDPOINT:https://dev-litmus-core.np.navi-tech.in/litmus-core/v1}
clickstream.api.endpoint=${CLICK_STREAM_API_ENDPOINT:https://dev-janus.np.navi-tech.in/events/json}
springdoc.swagger-ui.path=/swagger-ui.html

View File

@@ -4,11 +4,11 @@
<parent>
<artifactId>litmus</artifactId>
<groupId>com.navi.medici</groupId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
</parent>
<artifactId>litmus-util</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<name>litmus-util</name>

View File

@@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.navi.medici</groupId>
<artifactId>litmus</artifactId>
<version>2.0.2-SNAPSHOT</version>
<version>2.0.3-SNAPSHOT</version>
<packaging>pom</packaging>
<name>litmus</name>