Skip to content

Commit

Permalink
code refactoring and minor changes wrt the validations
Browse files Browse the repository at this point in the history
Signed-off-by: Saad Khan <[email protected]>
  • Loading branch information
khansaad committed Dec 19, 2023
1 parent a87da4a commit f5a6558
Show file tree
Hide file tree
Showing 8 changed files with 394 additions and 208 deletions.
383 changes: 259 additions & 124 deletions src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public void setSloInfo(SloInfo sloInfo) {
}

public SelectorInfo getSelectorInfo() {
return new SelectorInfo(selectorInfo);
return selectorInfo;
}

public void setSelectorInfo(SelectorInfo selectorInfo) {
Expand Down
104 changes: 48 additions & 56 deletions src/main/java/com/autotune/analyzer/serviceObjects/Converters.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.autotune.analyzer.serviceObjects;

import com.autotune.analyzer.exceptions.InvalidValueException;
import com.autotune.analyzer.experiment.ExperimentValidation;
import com.autotune.analyzer.kruizeObject.ExperimentUseCaseType;
import com.autotune.analyzer.kruizeObject.KruizeObject;
import com.autotune.analyzer.kruizeObject.ObjectiveFunction;
Expand All @@ -26,11 +25,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class Converters {
Expand All @@ -52,62 +49,57 @@ public static CreateExperimentAPIObject convertKruizeObjectToCreateExperimentSO(

public static KruizeObject convertCreateExperimentAPIObjToKruizeObject(CreateExperimentAPIObject createExperimentAPIObject) {
KruizeObject kruizeObject = new KruizeObject();
// check for mandatory fields first
ValidationOutputData validationOutputData = new ExperimentValidation().validateMandatoryFields(createExperimentAPIObject);
kruizeObject.setValidation_data(validationOutputData);
if (!validationOutputData.isSuccess()) {
LOGGER.error(validationOutputData.getMessage());
try {
List<K8sObject> k8sObjectList = getK8sObjects(createExperimentAPIObject);
kruizeObject.setKubernetes_objects(k8sObjectList);
kruizeObject.setExperimentName(createExperimentAPIObject.getExperimentName());
kruizeObject.setApiVersion(createExperimentAPIObject.getApiVersion());
kruizeObject.setTarget_cluster(createExperimentAPIObject.getTarget_cluster());
Optional<String> clusterNameOptional = Optional.ofNullable(createExperimentAPIObject.getClusterName());
clusterNameOptional.ifPresent(kruizeObject::setClusterName);
kruizeObject.setMode(createExperimentAPIObject.getMode());
kruizeObject.setPerformanceProfile(createExperimentAPIObject.getPerformanceProfile());
kruizeObject.setSloInfo(createExperimentAPIObject.getSloInfo());
kruizeObject.setTrial_settings(createExperimentAPIObject.getTrial_settings());
kruizeObject.setRecommendation_settings(createExperimentAPIObject.getRecommendation_settings());
kruizeObject.setExperiment_id(createExperimentAPIObject.getExperiment_id());
kruizeObject.setStatus(createExperimentAPIObject.getStatus());
kruizeObject.setExperiment_usecase_type(new ExperimentUseCaseType(kruizeObject));
} catch (Exception e) {
LOGGER.error("Failed to convert CreateExperimentAPIObj To KruizeObject due to {} ", e.getMessage());
LOGGER.debug(createExperimentAPIObject.toString());
kruizeObject.setValidation_data(new ValidationOutputData(false,
"failed to convert CreateExperimentAPIObj To KruizeObject due to: "+e.getMessage(),
HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
return kruizeObject;
} else {
checkForNullOrEmpty(createExperimentAPIObject);
if (!createExperimentAPIObject.getValidationData().isSuccess()){
LOGGER.error(createExperimentAPIObject.getValidationData().getMessage());
kruizeObject.setValidation_data(createExperimentAPIObject.getValidationData());
return kruizeObject;
} else {
try {
List<K8sObject> k8sObjectList = new ArrayList<>();
List<KubernetesAPIObject> kubernetesAPIObjectsList = createExperimentAPIObject.getKubernetes_objects();
for (KubernetesAPIObject kubernetesAPIObject : kubernetesAPIObjectsList) {
K8sObject k8sObject = new K8sObject(kubernetesAPIObject.getName(), kubernetesAPIObject.getType(),
kubernetesAPIObject.getNamespace());
List<ContainerAPIObject> containerAPIObjects = kubernetesAPIObject.getContainerAPIObjects();
HashMap<String, ContainerData> containerDataHashMap = new HashMap<>();
for (ContainerAPIObject containerAPIObject : containerAPIObjects) {
ContainerData containerData = new ContainerData(containerAPIObject.getContainer_name(),
containerAPIObject.getContainer_image_name(), new ContainerRecommendations(), null);
containerDataHashMap.put(containerData.getContainer_name(), containerData);
}
k8sObject.setContainerDataMap(containerDataHashMap);
k8sObjectList.add(k8sObject);
}
kruizeObject.setKubernetes_objects(k8sObjectList);
kruizeObject.setExperimentName(createExperimentAPIObject.getExperimentName());
kruizeObject.setApiVersion(createExperimentAPIObject.getApiVersion());
kruizeObject.setTarget_cluster(createExperimentAPIObject.getTarget_cluster());
Optional<String> clusterNameOptional = Optional.ofNullable(createExperimentAPIObject.getClusterName());
clusterNameOptional.ifPresent(kruizeObject::setClusterName);
kruizeObject.setMode(createExperimentAPIObject.getMode());
kruizeObject.setPerformanceProfile(createExperimentAPIObject.getPerformanceProfile());
kruizeObject.setSloInfo(createExperimentAPIObject.getSloInfo());
kruizeObject.setTrial_settings(createExperimentAPIObject.getTrial_settings());
kruizeObject.setRecommendation_settings(createExperimentAPIObject.getRecommendation_settings());
kruizeObject.setExperiment_id(createExperimentAPIObject.getExperiment_id());
kruizeObject.setStatus(createExperimentAPIObject.getStatus());
kruizeObject.setExperiment_usecase_type(new ExperimentUseCaseType(kruizeObject));
} catch (Exception e) {
LOGGER.error("Failed to convert CreateExperimentAPIObj To KruizeObject due to {} ", e.getMessage());
LOGGER.debug(createExperimentAPIObject.toString());
kruizeObject.setValidation_data(new ValidationOutputData(false,
"failed to convert CreateExperimentAPIObj To KruizeObject due to: "+e.getMessage(),
HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
return kruizeObject;
}
}
}
return kruizeObject;
}

private static List<K8sObject> getK8sObjects(CreateExperimentAPIObject createExperimentAPIObject) {
List<K8sObject> k8sObjectList = new ArrayList<>();
List<KubernetesAPIObject> kubernetesAPIObjectsList = createExperimentAPIObject.getKubernetes_objects();
for (KubernetesAPIObject kubernetesAPIObject : kubernetesAPIObjectsList) {
K8sObject k8sObject = new K8sObject(kubernetesAPIObject.getName(), kubernetesAPIObject.getType(),
kubernetesAPIObject.getNamespace());
HashMap<String, ContainerData> containerDataHashMap = getContainerData(kubernetesAPIObject);
k8sObject.setContainerDataMap(containerDataHashMap);
k8sObjectList.add(k8sObject);
}
return k8sObjectList;
}

private static HashMap<String, ContainerData> getContainerData(KubernetesAPIObject kubernetesAPIObject) {
List<ContainerAPIObject> containerAPIObjects = kubernetesAPIObject.getContainerAPIObjects();
HashMap<String, ContainerData> containerDataHashMap = new HashMap<>();
for (ContainerAPIObject containerAPIObject : containerAPIObjects) {
ContainerData containerData = new ContainerData(containerAPIObject.getContainer_name(),
containerAPIObject.getContainer_image_name(), new ContainerRecommendations(), null);
containerDataHashMap.put(containerData.getContainer_name(), containerData);
}
return containerDataHashMap;
}

public static ListRecommendationsAPIObject convertKruizeObjectToListRecommendationSO(
KruizeObject kruizeObject,
boolean getLatest,
Expand Down
69 changes: 45 additions & 24 deletions src/main/java/com/autotune/analyzer/services/CreateExperiment.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.autotune.analyzer.exceptions.KruizeResponse;
import com.autotune.analyzer.experiment.ExperimentInitiator;
import com.autotune.analyzer.experiment.ExperimentValidation;
import com.autotune.analyzer.kruizeObject.KruizeObject;
import com.autotune.analyzer.serviceObjects.Converters;
import com.autotune.analyzer.serviceObjects.CreateExperimentAPIObject;
Expand Down Expand Up @@ -88,42 +89,62 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
// Set the character encoding of the request to UTF-8
request.setCharacterEncoding(CHARACTER_ENCODING);
inputData = request.getReader().lines().collect(Collectors.joining());
List<CreateExperimentAPIObject> createExperimentAPIObjects = Arrays.asList(new Gson().fromJson(inputData, CreateExperimentAPIObject[].class));
List<CreateExperimentAPIObject> createExperimentAPIObjects;
KruizeObject kruizeObject;
try {
createExperimentAPIObjects = Arrays.asList(new Gson().fromJson(inputData, CreateExperimentAPIObject[].class));
} catch (com.google.gson.JsonParseException e) {
LOGGER.error("{} : {}", AnalyzerErrorConstants.AutotuneObjectErrors.JSON_PARSING_ERROR, e.getMessage());
sendErrorResponse(inputData, response, null, HttpServletResponse.SC_BAD_REQUEST, AnalyzerErrorConstants.AutotuneObjectErrors.JSON_PARSING_ERROR);
return;
}
// check for bulk entries and respond accordingly
if (createExperimentAPIObjects.size() > 1) {
LOGGER.error(AnalyzerErrorConstants.AutotuneObjectErrors.UNSUPPORTED_EXPERIMENT);
sendErrorResponse(inputData, response, null, HttpServletResponse.SC_BAD_REQUEST, AnalyzerErrorConstants.AutotuneObjectErrors.UNSUPPORTED_EXPERIMENT);
} else {
List<KruizeObject> kruizeExpList = new ArrayList<>();
boolean validationFlag = true;
for (CreateExperimentAPIObject createExperimentAPIObject : createExperimentAPIObjects) {
createExperimentAPIObject.setExperiment_id(Utils.generateID(createExperimentAPIObject.toString()));
createExperimentAPIObject.setStatus(AnalyzerConstants.ExperimentStatus.IN_PROGRESS);
KruizeObject kruizeObject = Converters.KruizeObjectConverters.convertCreateExperimentAPIObjToKruizeObject(createExperimentAPIObject);
if (null != kruizeObject)
kruizeExpList.add(kruizeObject);
}
new ExperimentInitiator().validateAndAddNewExperiments(mKruizeExperimentMap, kruizeExpList);
//TODO: UX needs to be modified - Handle response for the multiple objects
KruizeObject invalidKruizeObject = kruizeExpList.stream().filter((ko) -> (!ko.getValidation_data().isSuccess())).findAny().orElse(null);
if (null == invalidKruizeObject) {
ValidationOutputData addedToDB = null; // TODO savetoDB should move to queue and bulk upload not considered here
for (KruizeObject ko : kruizeExpList) {
CreateExperimentAPIObject validAPIObj = createExperimentAPIObjects.stream()
.filter(createObj -> ko.getExperimentName().equals(createObj.getExperimentName()))
.findAny()
.orElse(null);
validAPIObj.setValidationData(ko.getValidation_data());
ExperimentDAO experimentDAO = new ExperimentDAOImpl();
addedToDB = new ExperimentDBService().addExperimentToDB(validAPIObj);
// validate the object
new ExperimentValidation().validateCreateExpAPIObject(createExperimentAPIObject);
if (createExperimentAPIObject.getValidationData().isSuccess()) {
kruizeObject = Converters.KruizeObjectConverters.convertCreateExperimentAPIObjToKruizeObject(createExperimentAPIObject);
if (kruizeObject.getValidation_data().isSuccess())
kruizeExpList.add(kruizeObject);
} else {
sendErrorResponse(inputData, response, null, createExperimentAPIObject.getValidationData().getErrorCode(),
createExperimentAPIObject.getValidationData().getMessage());
validationFlag = false;
break;
}
if (addedToDB.isSuccess()) {
sendSuccessResponse(response, "Experiment registered successfully with Kruize.");
statusValue = "success";
}
if (validationFlag) {
new ExperimentInitiator().validateAndAddNewExperiments(mKruizeExperimentMap, kruizeExpList);
//TODO: UX needs to be modified - Handle response for the multiple objects
KruizeObject invalidKruizeObject = kruizeExpList.stream().filter((ko) -> (!ko.getValidation_data().isSuccess())).findAny().orElse(null);
if (null == invalidKruizeObject) {
ValidationOutputData addedToDB = null; // TODO savetoDB should move to queue and bulk upload not considered here
for (KruizeObject ko : kruizeExpList) {
CreateExperimentAPIObject validAPIObj = createExperimentAPIObjects.stream()
.filter(createObj -> ko.getExperimentName().equals(createObj.getExperimentName()))
.findAny()
.orElse(null);
validAPIObj.setValidationData(ko.getValidation_data());
ExperimentDAO experimentDAO = new ExperimentDAOImpl();
addedToDB = new ExperimentDBService().addExperimentToDB(validAPIObj);
}
if (addedToDB.isSuccess()) {
sendSuccessResponse(response, "Experiment registered successfully with Kruize.");
statusValue = "success";
} else {
sendErrorResponse(inputData, response, null, HttpServletResponse.SC_BAD_REQUEST, addedToDB.getMessage());
}
} else {
sendErrorResponse(inputData, response, null, HttpServletResponse.SC_BAD_REQUEST, addedToDB.getMessage());
sendErrorResponse(inputData, response, null, invalidKruizeObject.getValidation_data().getErrorCode(), invalidKruizeObject.getValidation_data().getMessage());
}
} else {
sendErrorResponse(inputData, response, null, invalidKruizeObject.getValidation_data().getErrorCode(), invalidKruizeObject.getValidation_data().getMessage());
}
}
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,12 @@ public static final class AutotuneObjectErrors {
public static final String BLANK_AGGREGATION_INFO_VALUE = " cannot be negative or blank for the metric variable: ";
public static final String UNSUPPORTED_FORMAT = " Format value should be among these values: ".concat(KruizeSupportedTypes.SUPPORTED_FORMATS.toString());
public static final String UNSUPPORTED_METRIC = "Metric variable name should be among these values: ".concat(Arrays.toString(AnalyzerConstants.MetricName.values()));
public static final String MISSING_MANDATORY_PARAMETERS = "Following mandatory parameters are either missing or have null or empty values: ";
public static final String MISSING_MANDATORY_PARAMETERS = "Following mandatory parameters are either missing or have null values: ";
public static final String AGGREGATION_INFO_INVALID_VALUE = "Need to update";
public static final String JSON_PARSING_ERROR = "Failed to parse the JSON. Please check the input payload ";
public static final String NOT_EMPTY_OR_NULL = " cannot be empty or null";
public static final String NON_NUMERIC_THRESHOLD = "Threshold should be a numeral only";
public static final String WRONG_DURATION_FORMAT = "Measurement duration should be in the format '15min'";


private AutotuneObjectErrors() {
Expand Down
Loading

0 comments on commit f5a6558

Please sign in to comment.