Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.autotune.analyzer.adapters;

import com.autotune.analyzer.kruizeObject.KruizeObject;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

import java.lang.reflect.Type;

public class KruizeObjectAdapter implements JsonSerializer<KruizeObject> {
@Override
public JsonElement serialize(KruizeObject obj, Type typeOfSrc, JsonSerializationContext context) {
JsonObject jsonObject = context.serialize(obj).getAsJsonObject();

// Replace the experiment_type field
String typeStr = obj.getExperimentTypeString();
jsonObject.remove("experiment_type");
jsonObject.addProperty("experiment_type", typeStr);

return jsonObject;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.autotune.analyzer.recommendations.ContainerRecommendations;
import com.autotune.analyzer.utils.AnalyzerConstants;
import com.autotune.analyzer.utils.AnalyzerErrorConstants;
import com.autotune.analyzer.utils.ExperimentTypeUtil;
import com.autotune.common.data.ValidationOutputData;
import com.autotune.common.data.metrics.Metric;
import com.autotune.common.data.result.ContainerData;
Expand Down Expand Up @@ -373,7 +374,7 @@ public ValidationOutputData validateMandatoryFields(KruizeObject expObj) {
String depType = "";
if (expObj.getExperiment_usecase_type().isRemote_monitoring()) {
// In case of RM, kubernetes_obj is mandatory
if (expObj.getExperimentType().equals(AnalyzerConstants.ExperimentType.CONTAINER)) {
if (AnalyzerConstants.ExperimentBitMask.CONTAINER_BIT.isSet(expObj.getExperimentType())) {
mandatoryDeploymentSelector = Collections.singletonList(AnalyzerConstants.KUBERNETES_OBJECTS);
// check for valid k8stype
for (K8sObject k8sObject : expObj.getKubernetes_objects()) {
Expand All @@ -395,15 +396,27 @@ public ValidationOutputData validateMandatoryFields(KruizeObject expObj) {
}
}
// Namespace experiment validation for both remote and local monitoring
if (expObj.getExperimentType().equals(AnalyzerConstants.ExperimentType.NAMESPACE)){
if (AnalyzerConstants.ExperimentBitMask.NAMESPACE_BIT.isSet(expObj.getExperimentType())){
for (K8sObject k8sObject : expObj.getKubernetes_objects()) {
if (null == k8sObject.getNamespaceDataMap() || k8sObject.getNamespaceDataMap().isEmpty()) {
errorMsg = errorMsg.concat(String.format(AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.MISSING_NAMESPACE_DATA, expObj.getExperimentType().toString()));
errorMsg = errorMsg.concat(
String.format(
AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.MISSING_NAMESPACE_DATA,
ExperimentTypeUtil.getExperimentTypeFromBitMask(
expObj.getExperimentType()
).toString()
));
missingNamespaceData = true;
} else {
for (NamespaceData namespaceData : k8sObject.getNamespaceDataMap().values()) {
if (null == namespaceData.getNamespace_name()) {
errorMsg = errorMsg.concat(String.format(AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.MISSING_NAMESPACE, expObj.getExperimentType().toString()));
errorMsg = errorMsg.concat(
String.format(
AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.MISSING_NAMESPACE,
ExperimentTypeUtil.getExperimentTypeFromBitMask(
expObj.getExperimentType()
).toString()
));
missingNamespaceData = true;
break;
}
Expand Down
18 changes: 11 additions & 7 deletions src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
* <p>
* Refer to examples dir for a reference AutotuneObject yaml.
*/
public final class KruizeObject implements ExperimentTypeAware {
public final class KruizeObject {

@SerializedName("version")
private String apiVersion;
Expand All @@ -53,8 +53,7 @@ public final class KruizeObject implements ExperimentTypeAware {
@SerializedName("datasource")
private String datasource;
@SerializedName(KruizeConstants.JSONKeys.EXPERIMENT_TYPE) //TODO: to be used in future
@JsonAdapter(ExperimentTypeUtil.ExperimentTypeSerializer.class)
private AnalyzerConstants.ExperimentType experimentType;
private long experimentType;
@SerializedName("default_updater")
private String defaultUpdater;
private String namespace; // TODO: Currently adding it at this level with an assumption that there is only one entry in k8s object needs to be changed
Expand Down Expand Up @@ -370,11 +369,11 @@ public void setDataSource(String datasource) {
this.datasource = datasource;
}

public AnalyzerConstants.ExperimentType getExperimentType() {
public long getExperimentType() {
return experimentType;
}

public void setExperimentType(AnalyzerConstants.ExperimentType experimentType) {
public void setExperimentType(long experimentType) {
this.experimentType = experimentType;
}

Expand Down Expand Up @@ -425,12 +424,12 @@ public String toString() {
'}';
}

@Override

public boolean isNamespaceExperiment() {
return ExperimentTypeUtil.isNamespaceExperiment(experimentType);
}

@Override

public boolean isContainerExperiment() {
return ExperimentTypeUtil.isContainerExperiment(experimentType);
}
Expand All @@ -453,4 +452,9 @@ private static double getTermThresholdInDays(String term, Double measurement_dur
return ((double) measurement_duration * minDataPoints
/ (KruizeConstants.TimeConv.NO_OF_HOURS_PER_DAY * KruizeConstants.TimeConv.NO_OF_MINUTES_PER_HOUR));
}

public String getExperimentTypeString() {
AnalyzerConstants.ExperimentType type = ExperimentTypeUtil.getExperimentTypeFromBitMask(this.experimentType);
return type.toString().toLowerCase();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.autotune.analyzer.recommendations.utils.RecommendationUtils;
import com.autotune.analyzer.utils.AnalyzerConstants;
import com.autotune.analyzer.utils.AnalyzerErrorConstants;
import com.autotune.analyzer.utils.ExperimentTypeUtil;
import com.autotune.common.data.ValidationOutputData;
import com.autotune.common.data.metrics.*;
import com.autotune.common.data.result.ContainerData;
Expand Down Expand Up @@ -2044,8 +2045,11 @@ private void fetchNamespaceMetricsBasedOnDataSourceAndProfile(KruizeObject kruiz

}

List<Metric> namespaceMetricList = filterMetricsBasedOnExpTypeAndK8sObject(metricProfile,
AnalyzerConstants.MetricName.namespaceMaxDate.name(), kruizeObject.getExperimentType());
List<Metric> namespaceMetricList = filterMetricsBasedOnExpTypeAndK8sObject(
metricProfile,
AnalyzerConstants.MetricName.namespaceMaxDate.name(),
ExperimentTypeUtil.getExperimentTypeFromBitMask(kruizeObject.getExperimentType())
);

// Iterate over metrics and aggregation functions
for (Metric metricEntry : namespaceMetricList) {
Expand Down Expand Up @@ -2276,8 +2280,11 @@ private void fetchContainerMetricsBasedOnDataSourceAndProfile(KruizeObject kruiz
MetricResults metricResults = null;
MetricAggregationInfoResults metricAggregationInfoResults = null;

List<Metric> metricList = filterMetricsBasedOnExpTypeAndK8sObject(metricProfile,
AnalyzerConstants.MetricName.maxDate.name(), kruizeObject.getExperimentType());
List<Metric> metricList = filterMetricsBasedOnExpTypeAndK8sObject(
metricProfile,
AnalyzerConstants.MetricName.maxDate.name(),
ExperimentTypeUtil.getExperimentTypeFromBitMask(kruizeObject.getExperimentType())
);

List<String> acceleratorFunctions = Arrays.asList(
AnalyzerConstants.MetricName.acceleratorCoreUsage.toString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.autotune.analyzer.recommendations.objects.MappedRecommendationForTimestamp;
import com.autotune.analyzer.recommendations.utils.RecommendationUtils;
import com.autotune.analyzer.utils.AnalyzerConstants;
import com.autotune.analyzer.utils.ExperimentTypeUtil;
import com.autotune.common.data.ValidationOutputData;
import com.autotune.common.data.metrics.*;
import com.autotune.common.data.result.ContainerData;
Expand Down Expand Up @@ -79,7 +80,7 @@ public static KruizeObject convertCreateExperimentAPIObjToKruizeObject(CreateExp
kruizeObject.setMode(createExperimentAPIObject.getMode());
kruizeObject.setPerformanceProfile(createExperimentAPIObject.getPerformanceProfile());
kruizeObject.setDataSource(createExperimentAPIObject.getDatasource());
kruizeObject.setExperimentType(createExperimentAPIObject.getExperimentType());
kruizeObject.setExperimentType(ExperimentTypeUtil.getExperimentType(createExperimentAPIObject.getExperimentType()));
kruizeObject.setSloInfo(createExperimentAPIObject.getSloInfo());
kruizeObject.setTrial_settings(createExperimentAPIObject.getTrialSettings());
RecommendationSettings recommendationSettings = new RecommendationSettings();
Expand Down Expand Up @@ -158,7 +159,9 @@ public static ListRecommendationsAPIObject convertKruizeObjectToListRecommendati
listRecommendationsAPIObject.setApiVersion(AnalyzerConstants.VersionConstants.APIVersionConstants.CURRENT_LIST_RECOMMENDATIONS_VERSION);
listRecommendationsAPIObject.setExperimentName(kruizeObject.getExperimentName());
listRecommendationsAPIObject.setClusterName(kruizeObject.getClusterName());
listRecommendationsAPIObject.setExperimentType(kruizeObject.getExperimentType());
listRecommendationsAPIObject.setExperimentType(
ExperimentTypeUtil.getExperimentTypeFromBitMask(kruizeObject.getExperimentType())
);
List<KubernetesAPIObject> kubernetesAPIObjects = new ArrayList<>();
KubernetesAPIObject kubernetesAPIObject;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public boolean isValid(UpdateResultsAPIObject updateResultsAPIObject, Constraint
String kubeObjNameSpaceInKruizeObject = kruizeObject.getKubernetes_objects().get(0).getNamespace();
String kubeObjNameSpaceInResultsData = resultData.getKubernetes_objects().get(0).getNamespace();

if (kruizeObject.getExperimentType().equals(AnalyzerConstants.ExperimentType.CONTAINER)) {
if (AnalyzerConstants.ExperimentBitMask.CONTAINER_BIT.isSet(kruizeObject.getExperimentType())) {
if (kubeObjNameSpaceInKruizeObject != null && !kubeObjNameSpaceInKruizeObject.equals(kubeObjNameSpaceInResultsData)) {
kubeObjsMisMatch = true;
errorMsg = errorMsg.concat(
Expand Down
35 changes: 33 additions & 2 deletions src/main/java/com/autotune/analyzer/services/ListExperiments.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.autotune.analyzer.services;

import com.autotune.analyzer.adapters.DeviceDetailsAdapter;
import com.autotune.analyzer.adapters.KruizeObjectAdapter;
import com.autotune.analyzer.adapters.RecommendationItemAdapter;
import com.autotune.analyzer.experiment.KruizeExperiment;
import com.autotune.analyzer.kruizeObject.KruizeObject;
Expand Down Expand Up @@ -196,7 +197,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
}
if (!error) {
// create Gson Object
Gson gsonObj = createGsonObject();
Gson gsonObj = createGsonObject(rmTable);

// Modify the JSON response here based on query params.
gsonStr = buildResponseBasedOnQuery(mKruizeExperimentMap, gsonObj, results, recommendations, latest, experimentName, rmTable);
Expand Down Expand Up @@ -324,12 +325,41 @@ private void loadLMExperimentsFromDatabase(Map<String, KruizeObject> mKruizeExpe
}
}

private Gson createGsonObject() {
private Gson createGsonObject(boolean rmtable) {
if (!rmtable) {
return new GsonBuilder()
.disableHtmlEscaping()
.setPrettyPrinting()
.enableComplexMapKeySerialization()
.registerTypeAdapter(Date.class, new GsonUTCDateAdapter())
.registerTypeAdapter(AnalyzerConstants.RecommendationItem.class, new RecommendationItemAdapter())
.registerTypeAdapter(DeviceDetails.class, new DeviceDetailsAdapter())
.setExclusionStrategies(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getDeclaringClass() == Metric.class && (
f.getName().equals("trialSummaryResult")
|| f.getName().equals("cycleDataMap")
) ||
f.getDeclaringClass() == ContainerData.class && (
f.getName().equalsIgnoreCase("metrics")
);
}

@Override
public boolean shouldSkipClass(Class<?> aClass) {
return false;
}
})
.create();
}

return new GsonBuilder()
.disableHtmlEscaping()
.setPrettyPrinting()
.enableComplexMapKeySerialization()
.registerTypeAdapter(Date.class, new GsonUTCDateAdapter())
.registerTypeAdapter(KruizeObject.class, new KruizeObjectAdapter())
.registerTypeAdapter(AnalyzerConstants.RecommendationItem.class, new RecommendationItemAdapter())
.registerTypeAdapter(DeviceDetails.class, new DeviceDetailsAdapter())
.setExclusionStrategies(new ExclusionStrategy() {
Expand All @@ -350,6 +380,7 @@ public boolean shouldSkipClass(Class<?> aClass) {
}
})
.create();

}

private void checkPercentileInfo(Map<String, KruizeObject> mainKruizeExperimentMap) {
Expand Down
8 changes: 6 additions & 2 deletions src/main/java/com/autotune/database/helper/DBHelpers.java
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,9 @@ public static KruizeLMRecommendationEntry convertKruizeObjectTOLMRecommendation(
kruizeRecommendationEntry.setVersion(KruizeConstants.KRUIZE_RECOMMENDATION_API_VERSION.LATEST.getVersionNumber());
kruizeRecommendationEntry.setExperiment_name(listRecommendationsAPIObject.getExperimentName());
kruizeRecommendationEntry.setCluster_name(listRecommendationsAPIObject.getClusterName());
kruizeRecommendationEntry.setExperimentType(kruizeObject.getExperimentType().name());
kruizeRecommendationEntry.setExperimentType(
ExperimentTypeUtil.getExperimentTypeFromBitMask(kruizeObject.getExperimentType()).name()
);

Timestamp endInterval = null;
// todo : what happens if two k8 objects or Containers with different timestamp
Expand Down Expand Up @@ -756,7 +758,9 @@ public static ListRecommendationsAPIObject getListRecommendationAPIObjectForDB(K
listRecommendationsAPIObject.setClusterName(kruizeObject.getClusterName());
listRecommendationsAPIObject.setExperimentName(kruizeObject.getExperimentName());
listRecommendationsAPIObject.setKubernetesObjects(kubernetesAPIObjectList);
listRecommendationsAPIObject.setExperimentType(kruizeObject.getExperimentType());
listRecommendationsAPIObject.setExperimentType(
ExperimentTypeUtil.getExperimentTypeFromBitMask(kruizeObject.getExperimentType())
);
}
return listRecommendationsAPIObject;
}
Expand Down