add create metric api along with changes in ExperimentEntity

This commit is contained in:
akshat-sonic
2023-02-13 23:59:00 +05:30
parent 8fae68fa0e
commit 0dcad61872
15 changed files with 236 additions and 5 deletions

View File

@@ -45,6 +45,11 @@
<artifactId>litmus-cache</artifactId>
<version>2.0.8-RELEASE</version>
</dependency>
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-60</artifactId>
<version>2.21.1</version>
</dependency>
<dependency>
<groupId>com.navi.medici</groupId>

View File

@@ -1,8 +1,14 @@
package com.navi.medici.controller.v1;
import com.navi.medici.request.v1.CreateMetricRequest;
import com.navi.medici.response.MetricResponse;
import com.navi.medici.service.metric.MetricService;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -11,7 +17,11 @@ import org.springframework.web.bind.annotation.RestController;
@Log4j2
@RequiredArgsConstructor
public class MetricController {
private final MetricService metricService;
@PostMapping
public MetricResponse
public ResponseEntity<MetricResponse> createMetric(@RequestBody CreateMetricRequest createMetricRequest, @RequestHeader("x-session-token") String sessionToken){
log.info("create request received for creating metric : {}", createMetricRequest.getMetricName());
return ResponseEntity.ok(metricService.createMetric(createMetricRequest,sessionToken));
}
}

View File

@@ -0,0 +1,26 @@
package com.navi.medici.mapper;
import com.navi.medici.entity.MetricEntity;
import com.navi.medici.query.experiment.IExperimentQuery;
import com.navi.medici.repository.ExperimentRepository;
import com.navi.medici.response.MetricResponse;
import lombok.AllArgsConstructor;
import lombok.experimental.UtilityClass;
import org.springframework.stereotype.Component;
@Component
@AllArgsConstructor
public class MetricMapper {
private final ExperimentRepository experimentRepository;
public MetricResponse mapMetricEntityToMetricResponse(MetricEntity metricEntity){
long numberOfExperimentsForMetrics = experimentRepository.countByPrimaryMetric(metricEntity.getMetricName());
return MetricResponse.builder()
.metricId(metricEntity.getMetricId())
.metricOwner(metricEntity.getMetricOwner())
.metricName(metricEntity.getMetricName())
.metricType(metricEntity.getMetricType())
.updatedAt(metricEntity.getUpdatedAt())
.numberOfExperiments(numberOfExperimentsForMetrics)
.build();
}
}

View File

@@ -0,0 +1,8 @@
package com.navi.medici.service.metric;
import com.navi.medici.request.v1.CreateMetricRequest;
import com.navi.medici.response.MetricResponse;
public interface MetricService {
MetricResponse createMetric(CreateMetricRequest createMetricRequest, String sessionToken);
}

View File

@@ -0,0 +1,38 @@
package com.navi.medici.service.metric;
import com.navi.medici.entity.MetricEntity;
import com.navi.medici.mapper.MetricMapper;
import com.navi.medici.repository.MetricRepository;
import com.navi.medici.request.v1.CreateMetricRequest;
import com.navi.medici.request.v1.LitmusOwner;
import com.navi.medici.response.MetricResponse;
import com.navi.medici.validator.MetricRequestValidator;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.util.UUID;
@Service
@Getter
@Setter
@AllArgsConstructor
public class MetricServiceImpl implements MetricService {
private final MetricRepository metricRepository;
private final MetricMapper metricMapper;
@Override
@Transactional
public MetricResponse createMetric(CreateMetricRequest createMetricRequest, String sessionToken) {
MetricRequestValidator.validate(createMetricRequest);
MetricEntity metric = MetricEntity.builder()
.metricId(UUID.randomUUID().toString())
.metricName(createMetricRequest.getMetricName())
.metricType(createMetricRequest.getMetricType())
.metricOwner(LitmusOwner.builder().build())
.athenaQuery(createMetricRequest.getAthenaQuery())
.build();
return metricMapper.mapMetricEntityToMetricResponse(metricRepository.save(metric));
}
}

View File

@@ -0,0 +1,21 @@
package com.navi.medici.validator;
import com.navi.medici.exceptions.BadRequestException;
import com.navi.medici.request.v1.CreateMetricRequest;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.StringUtils;
import java.util.Objects;
@UtilityClass
public class MetricRequestValidator {
public void validate(CreateMetricRequest createMetricRequest){
if (Objects.isNull(createMetricRequest)) {
throw new BadRequestException("request for creating metric is null");
} else if (StringUtils.isBlank(createMetricRequest.getMetricName())) {
throw new BadRequestException("Metric Name cannot be empty");
} else if (StringUtils.isBlank(createMetricRequest.getAthenaQuery())) {
throw new BadRequestException("Athena Query cannot be empty");
}
}
}

View File

@@ -33,6 +33,12 @@
<artifactId>litmus-model</artifactId>
<version>2.0.8-RELEASE</version>
</dependency>
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>2.16.2</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@@ -11,6 +11,9 @@ import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;
import com.navi.medici.request.v1.LitmusOwner;
import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
@@ -19,6 +22,8 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.FieldDefaults;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.UpdateTimestamp;
@Entity
@@ -29,6 +34,7 @@ import org.hibernate.annotations.UpdateTimestamp;
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
public class ExperimentEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@@ -82,6 +88,22 @@ public class ExperimentEntity {
@Column(name = "owner")
String experimentOwner;
String primaryMetric;
String secondaryMetric;
@Type(type = "jsonb")
@Column(columnDefinition = "jsonb")
LitmusOwner experiment_owner;
long sampleSizeRequired;
double baselineConversion;
double minimumDetectableEffect;
double confidenceInterval;
long testUsers;
}

View File

@@ -1,6 +1,8 @@
package com.navi.medici.entity;
import com.navi.medici.enums.MetricType;
import com.navi.medici.request.v1.LitmusOwner;
import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
@@ -8,7 +10,10 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.FieldDefaults;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
@@ -22,15 +27,19 @@ import javax.persistence.Table;
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
public class MetricEntity extends BaseEntity{
String metricName;
String metricId;
String metricName;
@Enumerated(EnumType.STRING)
MetricType metricType;
String metricOwner;
@Type(type = "jsonb")
@Column(columnDefinition = "jsonb")
LitmusOwner metricOwner;
String athenaQuery;
}

View File

@@ -27,4 +27,6 @@ public interface ExperimentRepository extends CrudRepository<ExperimentEntity, L
@Param("currentTime") LocalDateTime currentTime);
List<ExperimentEntity> findByVertical(String vertical);
long countByPrimaryMetric(String name);
}

View File

@@ -6,7 +6,7 @@ CREATE TABLE metrics (
metric_id varchar(36) NOT NULL,
metric_name varchar(100) NOT NULL,
metric_type varchar(100) NOT NULL,
metric_owner varchar(100) NOT NULL,
metric_owner jsonb,
athena_query text NOT NULL,
version BIGINT,
created_at timestamp,

View File

@@ -0,0 +1,12 @@
--liquibase formatted sql
--changeset author:akshatsonic id:202302132341
ALTER TABLE experiments
ADD primary_metric VARCHAR,
ADD secondary_metric VARCHAR,
ADD sample_size_required BIGINT,
ADD baseline_conversion FLOAT(2),
ADD minimum_detectable_effect FLOAT(2),
ADD confidence_interval FLOAT(2),
ADD test_users BIGINT;

View File

@@ -0,0 +1,20 @@
package com.navi.medici.request.v1;
import com.navi.medici.enums.MetricType;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.FieldDefaults;
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public class CreateMetricRequest {
String metricName;
String athenaQuery;
MetricType metricType;
}

View File

@@ -0,0 +1,22 @@
package com.navi.medici.request.v1;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.FieldDefaults;
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
@FieldDefaults(level = AccessLevel.PRIVATE)
public class LitmusOwner {
String emailId;
String name;
}

View File

@@ -0,0 +1,30 @@
package com.navi.medici.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.navi.medici.enums.MetricType;
import com.navi.medici.request.v1.LitmusOwner;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.FieldDefaults;
import java.time.LocalDateTime;
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
@FieldDefaults(level = AccessLevel.PRIVATE)
public class MetricResponse {
String metricId;
String metricName;
MetricType metricType;
LitmusOwner metricOwner;
LocalDateTime updatedAt;
Long numberOfExperiments;
}