From 068727dc29535d21f97530937fb565e23d7b6a7b Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Wed, 8 Jan 2025 14:42:33 +0530 Subject: [PATCH 01/18] adds Model and Term setting class --- .../analyzer/kruizeObject/ModelSettings.java | 24 ++++++++++++++ .../kruizeObject/RecommendationSettings.java | 20 ++++++++++++ .../analyzer/kruizeObject/TermSettings.java | 32 +++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 src/main/java/com/autotune/analyzer/kruizeObject/ModelSettings.java create mode 100644 src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/ModelSettings.java b/src/main/java/com/autotune/analyzer/kruizeObject/ModelSettings.java new file mode 100644 index 000000000..a2948ea71 --- /dev/null +++ b/src/main/java/com/autotune/analyzer/kruizeObject/ModelSettings.java @@ -0,0 +1,24 @@ +package com.autotune.analyzer.kruizeObject; + +import java.util.List; + +public class ModelSettings { + + private List models; + + public List getModels() { + return models; + } + + public void setModels(List models) { + this.models = models; + } + + @Override + public String toString() { + return "ModelSettings{" + + "models=" + models + + '}'; + } + +} diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/RecommendationSettings.java b/src/main/java/com/autotune/analyzer/kruizeObject/RecommendationSettings.java index 9ced5be3b..607f189d3 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/RecommendationSettings.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/RecommendationSettings.java @@ -17,6 +17,8 @@ public class RecommendationSettings { private Double threshold; + private ModelSettings modelSettings; + private TermSettings termSettings; public Double getThreshold() { return threshold; @@ -26,10 +28,28 @@ public void setThreshold(Double threshold) { this.threshold = threshold; } + public ModelSettings getModelSettings() { + return modelSettings; + } + + public void setModelSettings(ModelSettings modelSettings) { + this.modelSettings = modelSettings; + } + + public TermSettings getTermSettings() { + return termSettings; + } + + public void setTermSettings(TermSettings termSettings) { + this.termSettings = termSettings; + } + @Override public String toString() { return "RecommendationSettings{" + "threshold=" + threshold + + ", modelSettings=" + modelSettings + + ", termSettings=" + termSettings + '}'; } } diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java b/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java new file mode 100644 index 000000000..83fb7bd07 --- /dev/null +++ b/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java @@ -0,0 +1,32 @@ +package com.autotune.analyzer.kruizeObject; + +import java.util.List; + +public class TermSettings { + private List terms; + private String singleTerm; + + public List getTerms() { + return terms; + } + + public void setTerms(List terms) { + this.terms = terms; + } + + public String getSingleTerm() { + return singleTerm; + } + + public void setSingleTerm(String singleTerm) { + this.singleTerm = singleTerm; + } + + @Override + public String toString() { + return "TermSettings{" + + "terms=" + terms + + ", singleTerm='" + singleTerm + '\'' + + '}'; + } +} From 057e15738f638a7702d52aa2543765b0882d6b6b Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Thu, 6 Feb 2025 12:36:07 +0530 Subject: [PATCH 02/18] rebase & fix conflicts --- .../analyzer/kruizeObject/KruizeObject.java | 67 ++++++++++--------- .../analyzer/kruizeObject/TermSettings.java | 14 ++-- .../engine/RecommendationEngine.java | 48 ++++++++++--- .../analyzer/serviceObjects/Converters.java | 10 +-- 4 files changed, 89 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java index 990fb57d7..c10653d54 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java @@ -17,6 +17,7 @@ import com.autotune.analyzer.exceptions.InvalidValueException; import com.autotune.analyzer.recommendations.term.Terms; +import com.autotune.analyzer.serviceObjects.CreateExperimentAPIObject; import com.autotune.analyzer.utils.AnalyzerConstants; import com.autotune.analyzer.utils.ExperimentTypeAware; import com.autotune.analyzer.utils.ExperimentTypeUtil; @@ -26,10 +27,12 @@ import com.autotune.utils.KruizeConstants; import com.autotune.utils.KruizeSupportedTypes; import com.autotune.utils.Utils; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; import io.fabric8.kubernetes.api.model.ObjectReference; +import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -133,22 +136,45 @@ public KruizeObject() { @param terms A map to store the default terms with term name as the key and Terms object as the value. @param kruizeObject The KruizeObject for which the default terms are being set. */ + // take this from json and put value here step 2 public static void setDefaultTerms(Map terms, KruizeObject kruizeObject) { // TODO: define term names like daily, weekly, fortnightly etc // TODO: add CRD for terms - terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, - KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, - getTermThresholdInDays(KruizeConstants.JSONKeys.SHORT_TERM, kruizeObject.getTrial_settings().getMeasurement_durationMinutes_inDouble()), + // TODO : fixx this part from json objecttt figure out this + terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, KruizeConstants.RecommendationEngineConstants + .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, KruizeConstants.RecommendationEngineConstants + .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, 4, 0.25)); + // need to discuss how will these value change based on change in term + terms.put(KruizeConstants.JSONKeys.MEDIUM_TERM, new Terms(KruizeConstants.JSONKeys.MEDIUM_TERM, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS_THRESHOLD, 7, 1)); + terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS_THRESHOLD, 15, 1)); + + kruizeObject.setTerms(terms); + } + + + public static void setCustomTerms(Map terms, KruizeObject kruizeObject) { + // TODO: define term names like daily, weekly, fortnightly etc + // TODO: add CRD for terms + + // TODO : fixx this part from json objecttt figure out this +// for loop for multiple terms + + terms.put(kruizeObject.getRecommendation_settings().getTermSettings().getTerms().get(0), new Terms(kruizeObject.getRecommendation_settings().getTermSettings().getTerms().get(0) + , kruizeObject.getRecommendation_settings().getTermSettings().getTermDuration(), + KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, 4, 0.25)); - terms.put(KruizeConstants.JSONKeys.MEDIUM_TERM, new Terms(KruizeConstants.JSONKeys.MEDIUM_TERM, - KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS, - getTermThresholdInDays(KruizeConstants.JSONKeys.MEDIUM_TERM, kruizeObject.getTrial_settings().getMeasurement_durationMinutes_inDouble()), - 7, 1)); - terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, - KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS, - getTermThresholdInDays(KruizeConstants.JSONKeys.LONG_TERM, kruizeObject.getTrial_settings().getMeasurement_durationMinutes_inDouble()), - 15, 1)); + // need to discuss how will these value change based on change in term +// terms.put(KruizeConstants.JSONKeys.MEDIUM_TERM, new Terms(KruizeConstants.JSONKeys.MEDIUM_TERM, KruizeConstants +// .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS, KruizeConstants +// .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS_THRESHOLD, 7, 1)); +// terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, KruizeConstants +// .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS, KruizeConstants +// .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS_THRESHOLD, 15, 1)); kruizeObject.setTerms(terms); } @@ -363,23 +389,4 @@ public boolean isNamespaceExperiment() { public boolean isContainerExperiment() { return ExperimentTypeUtil.isContainerExperiment(experimentType); } - - private static double getTermThresholdInDays(String term, Double measurement_duration) { - double minDataPoints = 2; - - switch (term) { - case KruizeConstants.JSONKeys.SHORT_TERM: - minDataPoints = KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.SHORT_TERM_MIN_DATAPOINTS; - break; - case KruizeConstants.JSONKeys.MEDIUM_TERM: - minDataPoints = KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_MIN_DATAPOINTS; - break; - case KruizeConstants.JSONKeys.LONG_TERM: - minDataPoints = KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_MIN_DATAPOINTS; - break; - } - - return ((double) measurement_duration * minDataPoints - / (KruizeConstants.TimeConv.NO_OF_HOURS_PER_DAY * KruizeConstants.TimeConv.NO_OF_MINUTES_PER_HOUR)); - } } diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java b/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java index 83fb7bd07..361bd6dc8 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java @@ -4,7 +4,7 @@ public class TermSettings { private List terms; - private String singleTerm; + private String termDuration; public List getTerms() { return terms; @@ -14,19 +14,19 @@ public void setTerms(List terms) { this.terms = terms; } - public String getSingleTerm() { - return singleTerm; + public String getTermDuration() { + return termDuration; } - public void setSingleTerm(String singleTerm) { - this.singleTerm = singleTerm; + public void setTermDuration(String termDuration) { + this.termDuration = termDuration; } - + @Override public String toString() { return "TermSettings{" + "terms=" + terms + - ", singleTerm='" + singleTerm + '\'' + + ", singleTerm='" + termDuration + '\'' + '}'; } } diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index c662b20a4..79c988c7f 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -67,13 +67,16 @@ public class RecommendationEngine { private Map terms; private KruizeObject kruizeObject; private Timestamp interval_end_time; + private String modelName; +// private ModelName modelName = kruizeObject.getRecommendationSettings().getModelSettings().getModels(); public RecommendationEngine(String experimentName, String intervalEndTimeStr, String intervalStartTimeStr) { this.experimentName = experimentName; this.intervalEndTimeStr = intervalEndTimeStr; this.intervalStartTimeStr = intervalStartTimeStr; - this.init(); +// this.modelName = modelName; +// this.init(modelName); } private static int getNumPods(Map filteredResultsMap) { @@ -123,16 +126,27 @@ private static int getNumPodsForNamespace(Map filter return (int) Math.ceil(max_pods_cpu); } - private void init() { + private void LoadRecommendationModel(String modelName) { // Add new models recommendationModels = new ArrayList<>(); // Create Cost based model - CostBasedRecommendationModel costBasedRecommendationModel = new CostBasedRecommendationModel(); - // TODO: Create profile based model - registerModel(costBasedRecommendationModel); - // Create Performance based model - PerformanceBasedRecommendationModel performanceBasedRecommendationModel = new PerformanceBasedRecommendationModel(); - registerModel(performanceBasedRecommendationModel); + /// TODO: add if else pick models for the get func we created -- first change + if("cost".equalsIgnoreCase(modelName)) { + CostBasedRecommendationModel costBasedRecommendationModel = new CostBasedRecommendationModel(); + // TODO: Create profile based model + registerModel(costBasedRecommendationModel); + } else if ("performance".equalsIgnoreCase(modelName)) { + // Create Performance based model + PerformanceBasedRecommendationModel performanceBasedRecommendationModel = new PerformanceBasedRecommendationModel(); + registerModel(performanceBasedRecommendationModel); + } else { + CostBasedRecommendationModel costBasedRecommendationModel = new CostBasedRecommendationModel(); + // TODO: Create profile based model + registerModel(costBasedRecommendationModel); + // Create Performance based model + PerformanceBasedRecommendationModel performanceBasedRecommendationModel = new PerformanceBasedRecommendationModel(); + registerModel(performanceBasedRecommendationModel); + } // TODO: Add profile based once recommendation algos are available } @@ -168,10 +182,22 @@ public void setExperimentName(String experimentName) { this.experimentName = experimentName; } + public String getModelName() { + return modelName; + } + + public void setModelName(String modelName) { + this.modelName = modelName; + } + public Timestamp getInterval_end_time() { return interval_end_time; } + public String getIntervalEndTimeStr() { + return intervalEndTimeStr; + } + public void setInterval_end_time(Timestamp interval_end_time) { this.interval_end_time = interval_end_time; } @@ -291,9 +317,15 @@ public KruizeObject prepareRecommendations(int calCount, String target_cluster) KruizeObject.setDefaultTerms(terms, kruizeObject); // set the performance profile setPerformanceProfile(kruizeObject.getPerformanceProfile()); + // set custom terms + KruizeObject.setCustomTerms(terms, kruizeObject); // get the datasource // TODO: If no data source given use KruizeDeploymentInfo.monitoring_agent / default datasource String dataSource = kruizeObject.getDataSource(); + + setModelName(kruizeObject.getRecommendation_settings().getModelSettings().getModels().get(0)); + LoadRecommendationModel(modelName); + LOGGER.debug(String.format(KruizeConstants.APIMessages.EXPERIMENT_DATASOURCE, kruizeObject.getExperimentName(), dataSource)); int maxDay = Terms.getMaxDays(terms); diff --git a/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java b/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java index 0c62096b0..2a710a1d6 100644 --- a/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java +++ b/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java @@ -1,10 +1,7 @@ package com.autotune.analyzer.serviceObjects; import com.autotune.analyzer.exceptions.InvalidValueException; -import com.autotune.analyzer.kruizeObject.ExperimentUseCaseType; -import com.autotune.analyzer.kruizeObject.KruizeObject; -import com.autotune.analyzer.kruizeObject.ObjectiveFunction; -import com.autotune.analyzer.kruizeObject.SloInfo; +import com.autotune.analyzer.kruizeObject.*; import com.autotune.analyzer.metadataProfiles.MetadataProfile; import com.autotune.analyzer.performanceProfiles.PerformanceProfile; import com.autotune.analyzer.recommendations.ContainerRecommendations; @@ -84,7 +81,10 @@ public static KruizeObject convertCreateExperimentAPIObjToKruizeObject(CreateExp kruizeObject.setExperimentType(createExperimentAPIObject.getExperimentType()); kruizeObject.setSloInfo(createExperimentAPIObject.getSloInfo()); kruizeObject.setTrial_settings(createExperimentAPIObject.getTrialSettings()); - kruizeObject.setRecommendation_settings(createExperimentAPIObject.getRecommendationSettings()); + TermSettings termSettings = createExperimentAPIObject.getRecommendationSettings().getTermSettings(); + RecommendationSettings recommendationSettings = new RecommendationSettings(); + recommendationSettings.setTermSettings(termSettings); + kruizeObject.setRecommendation_settings(recommendationSettings); kruizeObject.setExperiment_id(createExperimentAPIObject.getExperiment_id()); kruizeObject.setStatus(createExperimentAPIObject.getStatus()); kruizeObject.setExperiment_usecase_type(new ExperimentUseCaseType(kruizeObject)); From 5adf0c76da5aede974cf7f9c8b8161f51e20ddce Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Tue, 21 Jan 2025 18:52:49 +0530 Subject: [PATCH 03/18] create and list exp api call works --- .../analyzer/kruizeObject/KruizeObject.java | 16 ++++++---------- .../analyzer/kruizeObject/ModelSettings.java | 2 ++ .../kruizeObject/RecommendationSettings.java | 7 +++++++ .../analyzer/kruizeObject/TermSettings.java | 18 ++++++++++++------ .../analyzer/serviceObjects/Converters.java | 2 ++ .../com/autotune/utils/KruizeConstants.java | 4 ++++ 6 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java index c10653d54..a7a30653b 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java @@ -17,6 +17,7 @@ import com.autotune.analyzer.exceptions.InvalidValueException; import com.autotune.analyzer.recommendations.term.Terms; +import com.autotune.analyzer.serviceObjects.Converters; import com.autotune.analyzer.serviceObjects.CreateExperimentAPIObject; import com.autotune.analyzer.utils.AnalyzerConstants; import com.autotune.analyzer.utils.ExperimentTypeAware; @@ -31,12 +32,15 @@ import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; import io.fabric8.kubernetes.api.model.ObjectReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; + /** * Container class for the Autotune kubernetes kind objects. *

@@ -160,21 +164,13 @@ public static void setDefaultTerms(Map terms, KruizeObject kruize public static void setCustomTerms(Map terms, KruizeObject kruizeObject) { // TODO: define term names like daily, weekly, fortnightly etc // TODO: add CRD for terms - // TODO : fixx this part from json objecttt figure out this -// for loop for multiple terms - terms.put(kruizeObject.getRecommendation_settings().getTermSettings().getTerms().get(0), new Terms(kruizeObject.getRecommendation_settings().getTermSettings().getTerms().get(0) - , kruizeObject.getRecommendation_settings().getTermSettings().getTermDuration(), + terms.put(kruizeObject.getRecommendation_settings().getTermSettings().getTerms().get(0) + "_term", new Terms(kruizeObject.getRecommendation_settings().getTermSettings().getTerms().get(0) + "_term" + , kruizeObject.getRecommendation_settings().getTermSettings().getTermDurations().get(kruizeObject.getRecommendation_settings().getTermSettings().getTerms().get(0)), KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, 4, 0.25)); // need to discuss how will these value change based on change in term -// terms.put(KruizeConstants.JSONKeys.MEDIUM_TERM, new Terms(KruizeConstants.JSONKeys.MEDIUM_TERM, KruizeConstants -// .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS, KruizeConstants -// .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS_THRESHOLD, 7, 1)); -// terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, KruizeConstants -// .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS, KruizeConstants -// .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS_THRESHOLD, 15, 1)); kruizeObject.setTerms(terms); } diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/ModelSettings.java b/src/main/java/com/autotune/analyzer/kruizeObject/ModelSettings.java index a2948ea71..96fdbc2c3 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/ModelSettings.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/ModelSettings.java @@ -6,6 +6,8 @@ public class ModelSettings { private List models; + public ModelSettings() {} + public List getModels() { return models; } diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/RecommendationSettings.java b/src/main/java/com/autotune/analyzer/kruizeObject/RecommendationSettings.java index 607f189d3..b96f5feaa 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/RecommendationSettings.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/RecommendationSettings.java @@ -15,11 +15,18 @@ *******************************************************************************/ package com.autotune.analyzer.kruizeObject; +import com.autotune.utils.KruizeConstants; +import com.google.gson.annotations.SerializedName; + public class RecommendationSettings { private Double threshold; + @SerializedName(KruizeConstants.JSONKeys.MODEL_SETTINGS) private ModelSettings modelSettings; + @SerializedName(KruizeConstants.JSONKeys.TERM_SETTINGS) private TermSettings termSettings; + public RecommendationSettings(){} + public Double getThreshold() { return threshold; } diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java b/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java index 361bd6dc8..9b813120c 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java @@ -1,10 +1,16 @@ package com.autotune.analyzer.kruizeObject; +import com.google.gson.annotations.SerializedName; + import java.util.List; +import java.util.Map; public class TermSettings { private List terms; - private String termDuration; + @SerializedName("term_duration_in_days") + private Map termDurations; + + public TermSettings() {} public List getTerms() { return terms; @@ -14,19 +20,19 @@ public void setTerms(List terms) { this.terms = terms; } - public String getTermDuration() { - return termDuration; + public Map getTermDurations() { + return termDurations; } - public void setTermDuration(String termDuration) { - this.termDuration = termDuration; + public void setTermDurations(Map termDurations) { + this.termDurations = termDurations; } @Override public String toString() { return "TermSettings{" + "terms=" + terms + - ", singleTerm='" + termDuration + '\'' + + ", termDurations=" + termDurations + '}'; } } diff --git a/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java b/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java index 2a710a1d6..277d403fa 100644 --- a/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java +++ b/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java @@ -84,6 +84,8 @@ public static KruizeObject convertCreateExperimentAPIObjToKruizeObject(CreateExp TermSettings termSettings = createExperimentAPIObject.getRecommendationSettings().getTermSettings(); RecommendationSettings recommendationSettings = new RecommendationSettings(); recommendationSettings.setTermSettings(termSettings); + ModelSettings modelSettings = createExperimentAPIObject.getRecommendationSettings().getModelSettings(); + recommendationSettings.setModelSettings(modelSettings); kruizeObject.setRecommendation_settings(recommendationSettings); kruizeObject.setExperiment_id(createExperimentAPIObject.getExperiment_id()); kruizeObject.setStatus(createExperimentAPIObject.getStatus()); diff --git a/src/main/java/com/autotune/utils/KruizeConstants.java b/src/main/java/com/autotune/utils/KruizeConstants.java index 26e365b5d..3287a99d4 100644 --- a/src/main/java/com/autotune/utils/KruizeConstants.java +++ b/src/main/java/com/autotune/utils/KruizeConstants.java @@ -272,6 +272,10 @@ public static final class JSONKeys { public static final String DEVICE = "device"; public static final String MODEL_NAME = "modelName"; + // Config changes JSON Keys + public static final String MODEL_SETTINGS = "model_settings"; + public static final String TERM_SETTINGS = "term_settings"; + private JSONKeys() { } } From 9ad4ed856734a449a896410c6bd9355f4444ceb9 Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Thu, 23 Jan 2025 17:02:26 +0530 Subject: [PATCH 04/18] adds single custom term settings, removes extra commented code --- .../analyzer/kruizeObject/KruizeObject.java | 57 ++++++++------- .../analyzer/kruizeObject/TermSettings.java | 14 ++-- .../engine/RecommendationEngine.java | 69 ++++++++++++------- 3 files changed, 82 insertions(+), 58 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java index a7a30653b..420f951c8 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java @@ -17,8 +17,6 @@ import com.autotune.analyzer.exceptions.InvalidValueException; import com.autotune.analyzer.recommendations.term.Terms; -import com.autotune.analyzer.serviceObjects.Converters; -import com.autotune.analyzer.serviceObjects.CreateExperimentAPIObject; import com.autotune.analyzer.utils.AnalyzerConstants; import com.autotune.analyzer.utils.ExperimentTypeAware; import com.autotune.analyzer.utils.ExperimentTypeUtil; @@ -28,14 +26,10 @@ import com.autotune.utils.KruizeConstants; import com.autotune.utils.KruizeSupportedTypes; import com.autotune.utils.Utils; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; import io.fabric8.kubernetes.api.model.ObjectReference; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -140,39 +134,50 @@ public KruizeObject() { @param terms A map to store the default terms with term name as the key and Terms object as the value. @param kruizeObject The KruizeObject for which the default terms are being set. */ - // take this from json and put value here step 2 + public static void setDefaultTerms(Map terms, KruizeObject kruizeObject) { // TODO: define term names like daily, weekly, fortnightly etc // TODO: add CRD for terms - // TODO : fixx this part from json objecttt figure out this - terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, KruizeConstants.RecommendationEngineConstants - .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, KruizeConstants.RecommendationEngineConstants - .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, 4, 0.25)); - // need to discuss how will these value change based on change in term - terms.put(KruizeConstants.JSONKeys.MEDIUM_TERM, new Terms(KruizeConstants.JSONKeys.MEDIUM_TERM, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS_THRESHOLD, 7, 1)); - terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS_THRESHOLD, 15, 1)); + if(kruizeObject.getTarget_cluster() == AnalyzerConstants.REMOTE) { + // for remote monitoring use case + terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, KruizeConstants.RecommendationEngineConstants + .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, KruizeConstants.RecommendationEngineConstants + .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, 4, 0.25)); + terms.put(KruizeConstants.JSONKeys.MEDIUM_TERM, new Terms(KruizeConstants.JSONKeys.MEDIUM_TERM, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS_THRESHOLD, 7, 1)); + terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS_THRESHOLD, 15, 1)); - kruizeObject.setTerms(terms); + } + else { + // for local monitoring use case + // Default is Short Term + terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, KruizeConstants.RecommendationEngineConstants + .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, KruizeConstants.RecommendationEngineConstants + .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, 4, 0.25)); + + kruizeObject.setTerms(terms); + } } public static void setCustomTerms(Map terms, KruizeObject kruizeObject) { // TODO: define term names like daily, weekly, fortnightly etc // TODO: add CRD for terms - // TODO : fixx this part from json objecttt figure out this - terms.put(kruizeObject.getRecommendation_settings().getTermSettings().getTerms().get(0) + "_term", new Terms(kruizeObject.getRecommendation_settings().getTermSettings().getTerms().get(0) + "_term" - , kruizeObject.getRecommendation_settings().getTermSettings().getTermDurations().get(kruizeObject.getRecommendation_settings().getTermSettings().getTerms().get(0)), - KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, - 4, 0.25)); - // need to discuss how will these value change based on change in term + if( kruizeObject.getRecommendation_settings().getTermSettings() != null ) { + String termKey = kruizeObject.getRecommendation_settings().getTermSettings().getTerms().get(0); + TermDetails termDetails = kruizeObject.getRecommendation_settings().getTermSettings().getTermDetails().get(termKey); - kruizeObject.setTerms(terms); + + terms.put(termKey + "_term", new Terms(termKey + "_term", termDetails.getDurationInDays(), termDetails.getDurationThreshold(), + termDetails.getPlotsDatapoint(), termDetails.getPlotsDatapointDeltaInDays())); + + kruizeObject.setTerms(terms); + } } public String getExperimentName() { diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java b/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java index 9b813120c..5d44a3d06 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java @@ -7,8 +7,8 @@ public class TermSettings { private List terms; - @SerializedName("term_duration_in_days") - private Map termDurations; + @SerializedName("term_details") + private Map termDetails; public TermSettings() {} @@ -20,19 +20,19 @@ public void setTerms(List terms) { this.terms = terms; } - public Map getTermDurations() { - return termDurations; + public Map getTermDetails() { + return termDetails; } - public void setTermDurations(Map termDurations) { - this.termDurations = termDurations; + public void setTermDetails(Map termDetails) { + this.termDetails = termDetails; } @Override public String toString() { return "TermSettings{" + "terms=" + terms + - ", termDurations=" + termDurations + + ", termDetails=" + termDetails + '}'; } } diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index 79c988c7f..f2949f40f 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -68,15 +68,13 @@ public class RecommendationEngine { private KruizeObject kruizeObject; private Timestamp interval_end_time; private String modelName; -// private ModelName modelName = kruizeObject.getRecommendationSettings().getModelSettings().getModels(); public RecommendationEngine(String experimentName, String intervalEndTimeStr, String intervalStartTimeStr) { this.experimentName = experimentName; this.intervalEndTimeStr = intervalEndTimeStr; this.intervalStartTimeStr = intervalStartTimeStr; -// this.modelName = modelName; -// this.init(modelName); + } private static int getNumPods(Map filteredResultsMap) { @@ -126,23 +124,28 @@ private static int getNumPodsForNamespace(Map filter return (int) Math.ceil(max_pods_cpu); } - private void LoadRecommendationModel(String modelName) { - // Add new models + private void LoadRecommendationModelForRemoteMonitoring() { recommendationModels = new ArrayList<>(); // Create Cost based model - /// TODO: add if else pick models for the get func we created -- first change + CostBasedRecommendationModel costBasedRecommendationModel = new CostBasedRecommendationModel(); + registerModel(costBasedRecommendationModel); + // Create Performance based model + PerformanceBasedRecommendationModel performanceBasedRecommendationModel = new PerformanceBasedRecommendationModel(); + registerModel(performanceBasedRecommendationModel); + } + + private void LoadRecommendationModelForLocalMonitoring(String modelName) { + // Add new models + recommendationModels = new ArrayList<>(); + if("cost".equalsIgnoreCase(modelName)) { + // Create Cost based model CostBasedRecommendationModel costBasedRecommendationModel = new CostBasedRecommendationModel(); - // TODO: Create profile based model - registerModel(costBasedRecommendationModel); - } else if ("performance".equalsIgnoreCase(modelName)) { - // Create Performance based model - PerformanceBasedRecommendationModel performanceBasedRecommendationModel = new PerformanceBasedRecommendationModel(); - registerModel(performanceBasedRecommendationModel); - } else { - CostBasedRecommendationModel costBasedRecommendationModel = new CostBasedRecommendationModel(); - // TODO: Create profile based model registerModel(costBasedRecommendationModel); + } + /// TODO: add an if else statement for handling custom model + else { + // Default condition : if nothing is specified by the user // Create Performance based model PerformanceBasedRecommendationModel performanceBasedRecommendationModel = new PerformanceBasedRecommendationModel(); registerModel(performanceBasedRecommendationModel); @@ -194,10 +197,6 @@ public Timestamp getInterval_end_time() { return interval_end_time; } - public String getIntervalEndTimeStr() { - return intervalEndTimeStr; - } - public void setInterval_end_time(Timestamp interval_end_time) { this.interval_end_time = interval_end_time; } @@ -313,18 +312,38 @@ public KruizeObject prepareRecommendations(int calCount, String target_cluster) // continue to generate recommendation when kruizeObject is successfully created try { // set the default terms if the terms aren't provided by the user - if (kruizeObject.getTerms() == null) - KruizeObject.setDefaultTerms(terms, kruizeObject); + if(kruizeObject.getTerms() == null) { + if (null == kruizeObject.getRecommendation_settings().getTermSettings()) { + KruizeObject.setDefaultTerms(terms, kruizeObject); + } else { + // set custom terms as provided by the user + KruizeObject.setCustomTerms(terms, kruizeObject); + } + } // set the performance profile setPerformanceProfile(kruizeObject.getPerformanceProfile()); - // set custom terms - KruizeObject.setCustomTerms(terms, kruizeObject); + // get the datasource // TODO: If no data source given use KruizeDeploymentInfo.monitoring_agent / default datasource String dataSource = kruizeObject.getDataSource(); - setModelName(kruizeObject.getRecommendation_settings().getModelSettings().getModels().get(0)); - LoadRecommendationModel(modelName); + // call different models for different use cases + if( kruizeObject.getTarget_cluster() == AnalyzerConstants.REMOTE){ + // remote monitoring use case + LoadRecommendationModelForRemoteMonitoring(); + } + else { + // local monitoring use case + if(kruizeObject.getRecommendation_settings().getModelSettings() != null) { + // if user has specified model, run that + setModelName(kruizeObject.getRecommendation_settings().getModelSettings().getModels().get(0)); + LoadRecommendationModelForLocalMonitoring(modelName); + } + else{ + // default local monitoring model is performance + LoadRecommendationModelForLocalMonitoring(KruizeConstants.JSONKeys.PERFORMANCE); + } + } LOGGER.debug(String.format(KruizeConstants.APIMessages.EXPERIMENT_DATASOURCE, kruizeObject.getExperimentName(), dataSource)); From 7dd5139d868d60c3aced988f82ce02d735753f58 Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Thu, 23 Jan 2025 17:34:59 +0530 Subject: [PATCH 05/18] adds term details file --- .../analyzer/kruizeObject/TermDetails.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/main/java/com/autotune/analyzer/kruizeObject/TermDetails.java diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/TermDetails.java b/src/main/java/com/autotune/analyzer/kruizeObject/TermDetails.java new file mode 100644 index 000000000..ec9128cbf --- /dev/null +++ b/src/main/java/com/autotune/analyzer/kruizeObject/TermDetails.java @@ -0,0 +1,59 @@ +package com.autotune.analyzer.kruizeObject; + +import com.google.gson.annotations.SerializedName; + +public class TermDetails { + @SerializedName("duration_in_days") + private Integer durationInDays; + @SerializedName("duration_threshold") + private Integer durationThreshold; + @SerializedName("plots_datapoint") + private Integer plotsDatapoint; + @SerializedName("plots_datapoint_delta_in_days") + private Double plotsDatapointDeltaInDays; + + public TermDetails() { + } + + public Integer getDurationInDays() { + return durationInDays; + } + + public void setDurationInDays(Integer durationInDays) { + this.durationInDays = durationInDays; + } + + public Integer getDurationThreshold() { + return durationThreshold; + } + + public void setDurationThreshold(Integer durationThreshold) { + this.durationThreshold = durationThreshold; + } + + public Integer getPlotsDatapoint() { + return plotsDatapoint; + } + + public void setPlotsDatapoint(Integer plotsDatapoint) { + this.plotsDatapoint = plotsDatapoint; + } + + public Double getPlotsDatapointDeltaInDays() { + return plotsDatapointDeltaInDays; + } + + public void setPlotsDatapointDeltaInDays(Double plotsDatapointDeltaInDays) { + this.plotsDatapointDeltaInDays = plotsDatapointDeltaInDays; + } + + @Override + public String toString() { + return "TermDetails{" + + "durationInDays=" + durationInDays + + ", durationThreshold=" + durationThreshold + + ", plotsDatapoint=" + plotsDatapoint + + ", plotsDatapointDeltaInDays=" + plotsDatapointDeltaInDays + + '}'; + } +} From e2885a6b529d53904c4a4416490d8ae3dceb7458 Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Thu, 6 Feb 2025 12:42:07 +0530 Subject: [PATCH 06/18] rebasing --- .../java/com/autotune/analyzer/serviceObjects/Converters.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java b/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java index 277d403fa..c99286abb 100644 --- a/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java +++ b/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java @@ -70,6 +70,8 @@ public static KruizeObject convertCreateExperimentAPIObjToKruizeObject(CreateExp LOGGER.debug("Experiment Type: {}", createExperimentAPIObject.getExperimentType()); k8sObjectList.add(k8sObject); } + // TODO : some modification to add custom terms and models automatically here + kruizeObject.setKubernetes_objects(k8sObjectList); kruizeObject.setExperimentName(createExperimentAPIObject.getExperimentName()); kruizeObject.setApiVersion(createExperimentAPIObject.getApiVersion()); @@ -86,6 +88,7 @@ public static KruizeObject convertCreateExperimentAPIObjToKruizeObject(CreateExp recommendationSettings.setTermSettings(termSettings); ModelSettings modelSettings = createExperimentAPIObject.getRecommendationSettings().getModelSettings(); recommendationSettings.setModelSettings(modelSettings); +// recommendationSettings.setThreshold(createExperimentAPIObject.getRecommendationSettings().getThreshold()); kruizeObject.setRecommendation_settings(recommendationSettings); kruizeObject.setExperiment_id(createExperimentAPIObject.getExperiment_id()); kruizeObject.setStatus(createExperimentAPIObject.getStatus()); From d26ad07fa332c0ffa5f09a67088308ee23a77f67 Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Fri, 24 Jan 2025 15:11:28 +0530 Subject: [PATCH 07/18] fixes rm flow --- .../com/autotune/analyzer/kruizeObject/KruizeObject.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java index 420f951c8..08bbd67bb 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java @@ -33,6 +33,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; /** @@ -139,7 +140,7 @@ public static void setDefaultTerms(Map terms, KruizeObject kruize // TODO: define term names like daily, weekly, fortnightly etc // TODO: add CRD for terms - if(kruizeObject.getTarget_cluster() == AnalyzerConstants.REMOTE) { + if(kruizeObject.getTarget_cluster().equalsIgnoreCase(AnalyzerConstants.REMOTE)) { // for remote monitoring use case terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, KruizeConstants.RecommendationEngineConstants .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, KruizeConstants.RecommendationEngineConstants @@ -150,7 +151,7 @@ public static void setDefaultTerms(Map terms, KruizeObject kruize terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, KruizeConstants .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS, KruizeConstants .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS_THRESHOLD, 15, 1)); - + kruizeObject.setTerms(terms); } else { // for local monitoring use case From 61261c1bb24da954229d1564bbb40a1833b87eda Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Fri, 24 Jan 2025 15:47:46 +0530 Subject: [PATCH 08/18] fix for remote monitoring --- .../analyzer/recommendations/engine/RecommendationEngine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index f2949f40f..b03afb323 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -328,7 +328,7 @@ public KruizeObject prepareRecommendations(int calCount, String target_cluster) String dataSource = kruizeObject.getDataSource(); // call different models for different use cases - if( kruizeObject.getTarget_cluster() == AnalyzerConstants.REMOTE){ + if( kruizeObject.getTarget_cluster().equalsIgnoreCase(AnalyzerConstants.REMOTE)){ // remote monitoring use case LoadRecommendationModelForRemoteMonitoring(); } From 255849423c46698dbc30643b8fe6a4c56c170d26 Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Fri, 24 Jan 2025 16:26:48 +0530 Subject: [PATCH 09/18] adds documentation --- design/KruizeLocalAPI.md | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/design/KruizeLocalAPI.md b/design/KruizeLocalAPI.md index 0ba5b7b69..8dbf0ef25 100644 --- a/design/KruizeLocalAPI.md +++ b/design/KruizeLocalAPI.md @@ -2570,6 +2570,73 @@ If no experiment type is specified, it will default to `container`. ``` +**Request with `model_settings` and `term_settings` field** + +Under `recommendation_settings`, the `model_settings` and `term_settings` field is optional +and allows you to specify custom model and term details. Currently, it supports configurations +for a single model and a single term. Model can be set to either cost or performance while +Term is user-customizable to suit specific needs. + +If no model or term settings are specified, then it will default to `performance` +and `short` term. + +

+ Example Request with custom model_settings and term_settings + +### EXAMPLE REQUEST +```json +[ + { + "version": "v2.0", + "experiment_name": "default|default|deployment|tfb-qrh-deployment", + "cluster_name": "default", + "performance_profile": "resource-optimization-openshift", + "mode": "monitor", + "target_cluster": "local", + "experiment_type": "container", + "kubernetes_objects": [ + { + "type": "deployment", + "name": "tfb-qrh-deployment", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0" + }, + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1" + } + ] + } + ], + "trial_settings": { + "measurement_duration": "15min" + }, + "recommendation_settings": { + "threshold": "0.1", + "model_settings": { + "models": ["cost"] + }, + "term_settings": { + "terms": ["short"], + "term_details": { + "short": { + "duration_in_days": 2 , + "duration_threshold": 1, + "plots_datapoint": 4, + "plots_datapoint_delta_in_days": 0.25 + } + } + } + }, + "datasource": "prometheus-1" + } +] +``` +
+ **Response**
From 5d31c12fee82cc319655d6e1d5292190b7e82a04 Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Wed, 29 Jan 2025 13:49:48 +0530 Subject: [PATCH 10/18] removes custom term changes --- .../exceptions/InvalidTermException.java | 23 ++++++++ .../analyzer/kruizeObject/KruizeObject.java | 40 ++++++++++--- .../analyzer/kruizeObject/TermDetails.java | 59 ------------------- .../analyzer/kruizeObject/TermSettings.java | 13 +--- .../engine/RecommendationEngine.java | 7 ++- 5 files changed, 62 insertions(+), 80 deletions(-) create mode 100644 src/main/java/com/autotune/analyzer/exceptions/InvalidTermException.java delete mode 100644 src/main/java/com/autotune/analyzer/kruizeObject/TermDetails.java diff --git a/src/main/java/com/autotune/analyzer/exceptions/InvalidTermException.java b/src/main/java/com/autotune/analyzer/exceptions/InvalidTermException.java new file mode 100644 index 000000000..13f30d09e --- /dev/null +++ b/src/main/java/com/autotune/analyzer/exceptions/InvalidTermException.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2020, 2021 Red Hat, IBM Corporation and others. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ +package com.autotune.analyzer.exceptions; + +public class InvalidTermException extends Throwable +{ + public InvalidTermException(String term) { + super(term); + } +} diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java index 08bbd67bb..edb5875cb 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java @@ -15,6 +15,7 @@ *******************************************************************************/ package com.autotune.analyzer.kruizeObject; +import com.autotune.analyzer.exceptions.InvalidTermException; import com.autotune.analyzer.exceptions.InvalidValueException; import com.autotune.analyzer.recommendations.term.Terms; import com.autotune.analyzer.utils.AnalyzerConstants; @@ -165,20 +166,43 @@ public static void setDefaultTerms(Map terms, KruizeObject kruize } - public static void setCustomTerms(Map terms, KruizeObject kruizeObject) { + public static void setCustomTerms(Map terms, KruizeObject kruizeObject) throws InvalidTermException { // TODO: define term names like daily, weekly, fortnightly etc // TODO: add CRD for terms - if( kruizeObject.getRecommendation_settings().getTermSettings() != null ) { - String termKey = kruizeObject.getRecommendation_settings().getTermSettings().getTerms().get(0); - TermDetails termDetails = kruizeObject.getRecommendation_settings().getTermSettings().getTermDetails().get(termKey); - - - terms.put(termKey + "_term", new Terms(termKey + "_term", termDetails.getDurationInDays(), termDetails.getDurationThreshold(), - termDetails.getPlotsDatapoint(), termDetails.getPlotsDatapointDeltaInDays())); + if( kruizeObject.getRecommendation_settings() != null && + kruizeObject.getRecommendation_settings().getTermSettings() != null ) + { + + String userInputTerm = String.valueOf(kruizeObject.getRecommendation_settings().getTermSettings().getTerms().get(0)); + + if( "short".equalsIgnoreCase(userInputTerm)){ + terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, KruizeConstants.RecommendationEngineConstants + .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, KruizeConstants.RecommendationEngineConstants + .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, 4, 0.25)); + } + else if ( "medium".equalsIgnoreCase(userInputTerm)) { + terms.put(KruizeConstants.JSONKeys.MEDIUM_TERM, new Terms(KruizeConstants.JSONKeys.MEDIUM_TERM, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS_THRESHOLD, 7, 1)); + } + else if ( "long".equalsIgnoreCase(userInputTerm)) { + terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS_THRESHOLD, 15, 1)); + + } + else{ + // Term name is invalid + throw new InvalidTermException(userInputTerm + " is not supported, use short, medium or long term"); + } kruizeObject.setTerms(terms); } + else { + // Handle the case where termSettings is null + throw new InvalidTermException("Term settings are not defined in the recommendation settings."); + } } public String getExperimentName() { diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/TermDetails.java b/src/main/java/com/autotune/analyzer/kruizeObject/TermDetails.java deleted file mode 100644 index ec9128cbf..000000000 --- a/src/main/java/com/autotune/analyzer/kruizeObject/TermDetails.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.autotune.analyzer.kruizeObject; - -import com.google.gson.annotations.SerializedName; - -public class TermDetails { - @SerializedName("duration_in_days") - private Integer durationInDays; - @SerializedName("duration_threshold") - private Integer durationThreshold; - @SerializedName("plots_datapoint") - private Integer plotsDatapoint; - @SerializedName("plots_datapoint_delta_in_days") - private Double plotsDatapointDeltaInDays; - - public TermDetails() { - } - - public Integer getDurationInDays() { - return durationInDays; - } - - public void setDurationInDays(Integer durationInDays) { - this.durationInDays = durationInDays; - } - - public Integer getDurationThreshold() { - return durationThreshold; - } - - public void setDurationThreshold(Integer durationThreshold) { - this.durationThreshold = durationThreshold; - } - - public Integer getPlotsDatapoint() { - return plotsDatapoint; - } - - public void setPlotsDatapoint(Integer plotsDatapoint) { - this.plotsDatapoint = plotsDatapoint; - } - - public Double getPlotsDatapointDeltaInDays() { - return plotsDatapointDeltaInDays; - } - - public void setPlotsDatapointDeltaInDays(Double plotsDatapointDeltaInDays) { - this.plotsDatapointDeltaInDays = plotsDatapointDeltaInDays; - } - - @Override - public String toString() { - return "TermDetails{" + - "durationInDays=" + durationInDays + - ", durationThreshold=" + durationThreshold + - ", plotsDatapoint=" + plotsDatapoint + - ", plotsDatapointDeltaInDays=" + plotsDatapointDeltaInDays + - '}'; - } -} diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java b/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java index 5d44a3d06..a9cf77b2f 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java @@ -7,8 +7,6 @@ public class TermSettings { private List terms; - @SerializedName("term_details") - private Map termDetails; public TermSettings() {} @@ -20,19 +18,10 @@ public void setTerms(List terms) { this.terms = terms; } - public Map getTermDetails() { - return termDetails; - } - - public void setTermDetails(Map termDetails) { - this.termDetails = termDetails; - } - @Override public String toString() { return "TermSettings{" + - "terms=" + terms + - ", termDetails=" + termDetails + + "terms=" + terms + '}'; } } diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index b03afb323..a02e68274 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -1,6 +1,7 @@ package com.autotune.analyzer.recommendations.engine; import com.autotune.analyzer.exceptions.FetchMetricsError; +import com.autotune.analyzer.exceptions.InvalidTermException; import com.autotune.analyzer.kruizeObject.KruizeObject; import com.autotune.analyzer.kruizeObject.RecommendationSettings; import com.autotune.analyzer.performanceProfiles.MetricProfileCollection; @@ -317,7 +318,11 @@ public KruizeObject prepareRecommendations(int calCount, String target_cluster) KruizeObject.setDefaultTerms(terms, kruizeObject); } else { // set custom terms as provided by the user - KruizeObject.setCustomTerms(terms, kruizeObject); + try { + KruizeObject.setCustomTerms(terms, kruizeObject); + } catch (InvalidTermException e) { + throw new RuntimeException(e); + } } } // set the performance profile From 39f77377d6442583d8161b4b89a17d401a97d52c Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Fri, 31 Jan 2025 23:22:53 +0530 Subject: [PATCH 11/18] fixes design and addresses review comments --- design/KruizeLocalAPI.md | 20 +- .../exceptions/InvalidModelException.java | 23 +++ .../analyzer/kruizeObject/KruizeObject.java | 82 ++++---- .../engine/RecommendationEngine.java | 177 ++++++++++++++---- .../analyzer/utils/AnalyzerConstants.java | 9 + .../utils/AnalyzerErrorConstants.java | 7 +- 6 files changed, 220 insertions(+), 98 deletions(-) create mode 100644 src/main/java/com/autotune/analyzer/exceptions/InvalidModelException.java diff --git a/design/KruizeLocalAPI.md b/design/KruizeLocalAPI.md index 8dbf0ef25..5ae03124c 100644 --- a/design/KruizeLocalAPI.md +++ b/design/KruizeLocalAPI.md @@ -2573,12 +2573,12 @@ If no experiment type is specified, it will default to `container`. **Request with `model_settings` and `term_settings` field** Under `recommendation_settings`, the `model_settings` and `term_settings` field is optional -and allows you to specify custom model and term details. Currently, it supports configurations -for a single model and a single term. Model can be set to either cost or performance while -Term is user-customizable to suit specific needs. +and allows you to specify model and term details. Currently, it supports configurations +for a single model and a single term. Model can be set to either cost or performance and +term can be set to short, medium or long term. -If no model or term settings are specified, then it will default to `performance` -and `short` term. +If mode is set to auto or recreate and the above settings are not mentioned then it will +default to `performance` and `short` term.
Example Request with custom model_settings and term_settings @@ -2620,15 +2620,7 @@ and `short` term. "models": ["cost"] }, "term_settings": { - "terms": ["short"], - "term_details": { - "short": { - "duration_in_days": 2 , - "duration_threshold": 1, - "plots_datapoint": 4, - "plots_datapoint_delta_in_days": 0.25 - } - } + "terms": ["short"] } }, "datasource": "prometheus-1" diff --git a/src/main/java/com/autotune/analyzer/exceptions/InvalidModelException.java b/src/main/java/com/autotune/analyzer/exceptions/InvalidModelException.java new file mode 100644 index 000000000..b04d27577 --- /dev/null +++ b/src/main/java/com/autotune/analyzer/exceptions/InvalidModelException.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2020, 2021 Red Hat, IBM Corporation and others. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ +package com.autotune.analyzer.exceptions; + +public class InvalidModelException extends Throwable +{ + public InvalidModelException(String model) { + super(model); + } +} diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java index edb5875cb..20b454324 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java @@ -19,6 +19,7 @@ import com.autotune.analyzer.exceptions.InvalidValueException; import com.autotune.analyzer.recommendations.term.Terms; import com.autotune.analyzer.utils.AnalyzerConstants; +import com.autotune.analyzer.utils.AnalyzerErrorConstants; import com.autotune.analyzer.utils.ExperimentTypeAware; import com.autotune.analyzer.utils.ExperimentTypeUtil; import com.autotune.common.data.ValidationOutputData; @@ -34,7 +35,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; /** @@ -141,67 +141,63 @@ public static void setDefaultTerms(Map terms, KruizeObject kruize // TODO: define term names like daily, weekly, fortnightly etc // TODO: add CRD for terms - if(kruizeObject.getTarget_cluster().equalsIgnoreCase(AnalyzerConstants.REMOTE)) { - // for remote monitoring use case - terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, KruizeConstants.RecommendationEngineConstants + // for monitoring use case + terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, KruizeConstants.RecommendationEngineConstants .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, KruizeConstants.RecommendationEngineConstants .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, 4, 0.25)); - terms.put(KruizeConstants.JSONKeys.MEDIUM_TERM, new Terms(KruizeConstants.JSONKeys.MEDIUM_TERM, KruizeConstants + terms.put(KruizeConstants.JSONKeys.MEDIUM_TERM, new Terms(KruizeConstants.JSONKeys.MEDIUM_TERM, KruizeConstants .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS, KruizeConstants .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS_THRESHOLD, 7, 1)); - terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, KruizeConstants + terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, KruizeConstants .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS, KruizeConstants .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS_THRESHOLD, 15, 1)); - kruizeObject.setTerms(terms); - } - else { - // for local monitoring use case - // Default is Short Term - terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, KruizeConstants.RecommendationEngineConstants - .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, KruizeConstants.RecommendationEngineConstants - .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, 4, 0.25)); + kruizeObject.setTerms(terms); + - kruizeObject.setTerms(terms); - } } + public static void setDefaultTermsForAutoAndRecreate(Map terms, KruizeObject kruizeObject){ + // for auto and recreate mode + // Default is Short Term + terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, KruizeConstants.RecommendationEngineConstants + .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, KruizeConstants.RecommendationEngineConstants + .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, 4, 0.25)); + + kruizeObject.setTerms(terms); + } public static void setCustomTerms(Map terms, KruizeObject kruizeObject) throws InvalidTermException { // TODO: define term names like daily, weekly, fortnightly etc // TODO: add CRD for terms - - if( kruizeObject.getRecommendation_settings() != null && - kruizeObject.getRecommendation_settings().getTermSettings() != null ) - { - - String userInputTerm = String.valueOf(kruizeObject.getRecommendation_settings().getTermSettings().getTerms().get(0)); - - if( "short".equalsIgnoreCase(userInputTerm)){ - terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, KruizeConstants.RecommendationEngineConstants - .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, KruizeConstants.RecommendationEngineConstants - .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, 4, 0.25)); - } - else if ( "medium".equalsIgnoreCase(userInputTerm)) { - terms.put(KruizeConstants.JSONKeys.MEDIUM_TERM, new Terms(KruizeConstants.JSONKeys.MEDIUM_TERM, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS_THRESHOLD, 7, 1)); - } - else if ( "long".equalsIgnoreCase(userInputTerm)) { - terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS_THRESHOLD, 15, 1)); - + if( kruizeObject.getRecommendation_settings() != null && kruizeObject.getRecommendation_settings().getTermSettings() != null ){ + + List termList = kruizeObject.getRecommendation_settings().getTermSettings().getTerms(); + + for (String userInputTerm : termList) { + if (AnalyzerConstants.RecommendationSettings.SHORT.equalsIgnoreCase(userInputTerm)) { + terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, KruizeConstants.RecommendationEngineConstants + .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, KruizeConstants.RecommendationEngineConstants + .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, 4, 0.25)); + } else if (AnalyzerConstants.RecommendationSettings.MEDIUM.equalsIgnoreCase(userInputTerm)) { + terms.put(KruizeConstants.JSONKeys.MEDIUM_TERM, new Terms(KruizeConstants.JSONKeys.MEDIUM_TERM, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS_THRESHOLD, 7, 1)); + } else if (AnalyzerConstants.RecommendationSettings.LONG.equalsIgnoreCase(userInputTerm)) { + terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS_THRESHOLD, 15, 1)); + + } else { + // Term name is invalid + throw new InvalidTermException(userInputTerm + AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.INVALID_TERM_NAME); + } } - else{ - // Term name is invalid - throw new InvalidTermException(userInputTerm + " is not supported, use short, medium or long term"); - } kruizeObject.setTerms(terms); } else { // Handle the case where termSettings is null - throw new InvalidTermException("Term settings are not defined in the recommendation settings."); + throw new InvalidTermException(AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.TERM_SETTINGS_UNDEFINED); } } diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index a02e68274..d6b80e826 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -1,6 +1,7 @@ package com.autotune.analyzer.recommendations.engine; import com.autotune.analyzer.exceptions.FetchMetricsError; +import com.autotune.analyzer.exceptions.InvalidModelException; import com.autotune.analyzer.exceptions.InvalidTermException; import com.autotune.analyzer.kruizeObject.KruizeObject; import com.autotune.analyzer.kruizeObject.RecommendationSettings; @@ -68,7 +69,7 @@ public class RecommendationEngine { private Map terms; private KruizeObject kruizeObject; private Timestamp interval_end_time; - private String modelName; + private List modelName; public RecommendationEngine(String experimentName, String intervalEndTimeStr, String intervalStartTimeStr) { @@ -125,7 +126,8 @@ private static int getNumPodsForNamespace(Map filter return (int) Math.ceil(max_pods_cpu); } - private void LoadRecommendationModelForRemoteMonitoring() { + private void DefaultLoadRecommendationModel() { + // create both cost and performance model by default recommendationModels = new ArrayList<>(); // Create Cost based model CostBasedRecommendationModel costBasedRecommendationModel = new CostBasedRecommendationModel(); @@ -135,23 +137,33 @@ private void LoadRecommendationModelForRemoteMonitoring() { registerModel(performanceBasedRecommendationModel); } - private void LoadRecommendationModelForLocalMonitoring(String modelName) { - // Add new models + private void DefaultLoadRecommendationModelForAutoAndRecreate() { + // create performance model by default recommendationModels = new ArrayList<>(); + // Create Performance based model + PerformanceBasedRecommendationModel performanceBasedRecommendationModel = new PerformanceBasedRecommendationModel(); + registerModel(performanceBasedRecommendationModel); + } - if("cost".equalsIgnoreCase(modelName)) { - // Create Cost based model - CostBasedRecommendationModel costBasedRecommendationModel = new CostBasedRecommendationModel(); - registerModel(costBasedRecommendationModel); - } - /// TODO: add an if else statement for handling custom model - else { - // Default condition : if nothing is specified by the user - // Create Performance based model - PerformanceBasedRecommendationModel performanceBasedRecommendationModel = new PerformanceBasedRecommendationModel(); - registerModel(performanceBasedRecommendationModel); + private void CustomLoadRecommendationModel(List modelName) throws InvalidModelException { + // Add new models + recommendationModels = new ArrayList<>(); + for(String model : modelName){ + if("cost".equalsIgnoreCase(model)) { + // Create Cost based model + CostBasedRecommendationModel costBasedRecommendationModel = new CostBasedRecommendationModel(); + registerModel(costBasedRecommendationModel); + } + else if("performance".equalsIgnoreCase(model)){ + // Create Performance based model + PerformanceBasedRecommendationModel performanceBasedRecommendationModel = new PerformanceBasedRecommendationModel(); + registerModel(performanceBasedRecommendationModel); + } + else { + // user input does not matches standard models + throw new InvalidModelException(modelName + AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.INVALID_MODEL_NAME); + } } - // TODO: Add profile based once recommendation algos are available } private void registerModel(RecommendationModel recommendationModel) { @@ -186,11 +198,11 @@ public void setExperimentName(String experimentName) { this.experimentName = experimentName; } - public String getModelName() { + public List getModelName() { return modelName; } - public void setModelName(String modelName) { + public void setModelName(List modelName) { this.modelName = modelName; } @@ -312,19 +324,56 @@ public KruizeObject prepareRecommendations(int calCount, String target_cluster) mainKruizeExperimentMAP.put(kruizeObject.getExperimentName(), kruizeObject); // continue to generate recommendation when kruizeObject is successfully created try { - // set the default terms if the terms aren't provided by the user - if(kruizeObject.getTerms() == null) { - if (null == kruizeObject.getRecommendation_settings().getTermSettings()) { - KruizeObject.setDefaultTerms(terms, kruizeObject); - } else { - // set custom terms as provided by the user - try { - KruizeObject.setCustomTerms(terms, kruizeObject); - } catch (InvalidTermException e) { - throw new RuntimeException(e); + // term settings for different use cases + if( kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.MONITOR)) { + // monitoring mode + if(kruizeObject.getRecommendation_settings() == null || + kruizeObject.getRecommendation_settings().getTermSettings() == null || + kruizeObject.getRecommendation_settings().getTermSettings().getTerms() == null){ + // default for monitoring + KruizeObject.setDefaultTerms(terms,kruizeObject); + } + else{ + // Process terms + KruizeObject.setCustomTerms(terms, kruizeObject); + } + + } + else if (kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.AUTO) || kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.RECREATE)) { + // auto or recreate mode + if(kruizeObject.getRecommendation_settings() == null || + kruizeObject.getRecommendation_settings().getTermSettings() == null || + kruizeObject.getRecommendation_settings().getTermSettings().getTerms() == null){ + + // default for monitoring + KruizeObject.setDefaultTermsForAutoAndRecreate(terms, kruizeObject); + } + else{ + // terms for auto recreate + // verify if single + if(kruizeObject.getRecommendation_settings().getTermSettings().getTerms().size() == 1) { + // call for that one term + KruizeObject.setCustomTerms(terms, kruizeObject); + } + else{ + // multiple terms throw error + throw new InvalidTermException(AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.MULTIPLE_TERMS_UNSUPPORTED); } } } + +// if(kruizeObject.getTerms() == null) { +// if (null == kruizeObject.getRecommendation_settings().getTermSettings()) { +// KruizeObject.setDefaultTerms(terms, kruizeObject); +// } else { +// // set custom terms as provided by the user +// +// KruizeObject.setCustomTerms(terms, kruizeObject); +// +// } +// } + + // set the performance profile setPerformanceProfile(kruizeObject.getPerformanceProfile()); @@ -333,20 +382,68 @@ public KruizeObject prepareRecommendations(int calCount, String target_cluster) String dataSource = kruizeObject.getDataSource(); // call different models for different use cases - if( kruizeObject.getTarget_cluster().equalsIgnoreCase(AnalyzerConstants.REMOTE)){ - // remote monitoring use case - LoadRecommendationModelForRemoteMonitoring(); + if( kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.MONITOR)){ + // can be local or remote monitoring use case + if(kruizeObject.getRecommendation_settings() == null){ + // recommendation setting are null -> use default values + // both cost and perf model to be called + DefaultLoadRecommendationModel(); + } + else{ + // recommendation setting are present --> check for model settings + if(kruizeObject.getRecommendation_settings().getModelSettings() == null){ + // model settings are not present + DefaultLoadRecommendationModel(); + } + else { + // model settings are present + // for what ever model settings are present do as directed. + List models = kruizeObject.getRecommendation_settings().getModelSettings().getModels(); + if(models == null ){ + // models are not there + DefaultLoadRecommendationModel(); + } + else{ + // models present + setModelName(models); + CustomLoadRecommendationModel(modelName); + } + + } + } + } - else { - // local monitoring use case - if(kruizeObject.getRecommendation_settings().getModelSettings() != null) { - // if user has specified model, run that - setModelName(kruizeObject.getRecommendation_settings().getModelSettings().getModels().get(0)); - LoadRecommendationModelForLocalMonitoring(modelName); + else if (kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.AUTO) || kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.RECREATE)){ + // auto or recreate mode + if(kruizeObject.getRecommendation_settings() == null){ + // recommendation setting are null -> use default values + // perf model to be called + DefaultLoadRecommendationModelForAutoAndRecreate(); } else{ - // default local monitoring model is performance - LoadRecommendationModelForLocalMonitoring(KruizeConstants.JSONKeys.PERFORMANCE); + // recommendation setting are present --> check for model settings + if(kruizeObject.getRecommendation_settings().getModelSettings() == null){ + // model settings are not present + DefaultLoadRecommendationModelForAutoAndRecreate(); + } + else { + // model settings are present + // for what ever model settings are present do as directed. + // check for single model + if(kruizeObject.getRecommendation_settings().getModelSettings().getModels() != null && + kruizeObject.getRecommendation_settings().getModelSettings().getModels().size() == 1) { + // call for that one model +// String model = kruizeObject.getRecommendation_settings().getModelSettings().getModels().get(0); + CustomLoadRecommendationModel(kruizeObject.getRecommendation_settings().getModelSettings().getModels()); + } + else{ + // multiple model throw error + throw new InvalidModelException(AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.MULTIPLE_MODELS_UNSUPPORTED); + } + + + } + } } @@ -389,7 +486,7 @@ public KruizeObject prepareRecommendations(int calCount, String target_cluster) experimentName, interval_start_time, interval_end_time)); kruizeObject.setValidation_data(new ValidationOutputData(false, e.getMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR)); } - } catch (Exception | FetchMetricsError e) { + } catch (Exception | FetchMetricsError | InvalidModelException | InvalidTermException e) { LOGGER.error(String.format(AnalyzerErrorConstants.APIErrors.UpdateRecommendationsAPI.RECOMMENDATION_EXCEPTION, experimentName, interval_end_time, e.getMessage())); LOGGER.error(String.format(AnalyzerErrorConstants.APIErrors.UpdateRecommendationsAPI.UPDATE_RECOMMENDATIONS_FAILED_COUNT, calCount)); diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java index 03f53239b..11fe2c57d 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java @@ -301,6 +301,15 @@ private ExperimentTypes() { } } + public static final class RecommendationSettings { + public static final String SHORT = "short"; + public static final String MEDIUM = "medium"; + public static final String LONG = "long"; + + private RecommendationSettings() { + } + } + /** * Used to parse the Autotune kind resource */ diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java index d59f715a9..d38f3b878 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java @@ -18,7 +18,6 @@ import com.autotune.operator.KruizeDeploymentInfo; import com.autotune.utils.KruizeConstants; import com.autotune.utils.KruizeSupportedTypes; -import software.amazon.awssdk.services.cloudwatchlogs.endpoints.internal.Value; import java.util.Arrays; @@ -182,6 +181,12 @@ public static final class CreateExperimentAPI { public static final String INVALID_MODE_FOR_NAMESPACE_EXP = "Auto or recreate mode is not supported for namespace experiment."; public static final String INVALID_OBJECT_TYPE_FOR_AUTO_EXP = "Kubernetes object type is not supported for auto or recreate mode."; public static final String AUTO_EXP_NOT_SUPPORTED_FOR_REMOTE = "Auto or recreate mode is not supported for remote monitoring use case."; + public static final String INVALID_TERM_NAME = " term name is not supported, use short, medium or long term."; + public static final String TERM_SETTINGS_UNDEFINED= "Term settings are not defined in the recommendation settings."; + public static final String MULTIPLE_TERMS_UNSUPPORTED = "Multiple terms are currently not supported"; + public static final String INVALID_MODEL_NAME = " model name is not supported, use cost or performance."; + public static final String MULTIPLE_MODELS_UNSUPPORTED = "Multiple models are currently not supported"; + private CreateExperimentAPI() { } From 57bb0fc08111e95ff4b2085e40bbb5131052e146 Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Thu, 6 Feb 2025 12:27:04 +0530 Subject: [PATCH 12/18] remove comments --- .../engine/RecommendationEngine.java | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index d6b80e826..d820808b7 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -362,18 +362,6 @@ else if (kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.AUTO) || krui } } -// if(kruizeObject.getTerms() == null) { -// if (null == kruizeObject.getRecommendation_settings().getTermSettings()) { -// KruizeObject.setDefaultTerms(terms, kruizeObject); -// } else { -// // set custom terms as provided by the user -// -// KruizeObject.setCustomTerms(terms, kruizeObject); -// -// } -// } - - // set the performance profile setPerformanceProfile(kruizeObject.getPerformanceProfile()); @@ -433,7 +421,7 @@ else if (kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.AUTO) || krui if(kruizeObject.getRecommendation_settings().getModelSettings().getModels() != null && kruizeObject.getRecommendation_settings().getModelSettings().getModels().size() == 1) { // call for that one model -// String model = kruizeObject.getRecommendation_settings().getModelSettings().getModels().get(0); + // String model = kruizeObject.getRecommendation_settings().getModelSettings().getModels().get(0); CustomLoadRecommendationModel(kruizeObject.getRecommendation_settings().getModelSettings().getModels()); } else{ From 20698763a545b43f2b2170f6ed1a43560102f830 Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Thu, 6 Feb 2025 15:40:20 +0530 Subject: [PATCH 13/18] accodomated review comments --- .../exceptions/InvalidModelException.java | 5 +- .../exceptions/InvalidTermException.java | 5 +- .../analyzer/kruizeObject/KruizeObject.java | 64 ++++----- .../analyzer/kruizeObject/TermSettings.java | 3 - .../engine/RecommendationEngine.java | 123 ++++++------------ .../analyzer/serviceObjects/Converters.java | 2 +- .../utils/AnalyzerErrorConstants.java | 4 +- 7 files changed, 82 insertions(+), 124 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/exceptions/InvalidModelException.java b/src/main/java/com/autotune/analyzer/exceptions/InvalidModelException.java index b04d27577..0f5688f57 100644 --- a/src/main/java/com/autotune/analyzer/exceptions/InvalidModelException.java +++ b/src/main/java/com/autotune/analyzer/exceptions/InvalidModelException.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020, 2021 Red Hat, IBM Corporation and others. + * Copyright (c) 2025 Red Hat, IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,7 @@ *******************************************************************************/ package com.autotune.analyzer.exceptions; -public class InvalidModelException extends Throwable -{ +public class InvalidModelException extends Throwable{ public InvalidModelException(String model) { super(model); } diff --git a/src/main/java/com/autotune/analyzer/exceptions/InvalidTermException.java b/src/main/java/com/autotune/analyzer/exceptions/InvalidTermException.java index 13f30d09e..5b63effb3 100644 --- a/src/main/java/com/autotune/analyzer/exceptions/InvalidTermException.java +++ b/src/main/java/com/autotune/analyzer/exceptions/InvalidTermException.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020, 2021 Red Hat, IBM Corporation and others. + * Copyright (c) 2025 Red Hat, IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,7 @@ *******************************************************************************/ package com.autotune.analyzer.exceptions; -public class InvalidTermException extends Throwable -{ +public class InvalidTermException extends Throwable{ public InvalidTermException(String term) { super(term); } diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java index 20b454324..a9c9f0855 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java @@ -140,28 +140,30 @@ public KruizeObject() { public static void setDefaultTerms(Map terms, KruizeObject kruizeObject) { // TODO: define term names like daily, weekly, fortnightly etc // TODO: add CRD for terms - - // for monitoring use case - terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, KruizeConstants.RecommendationEngineConstants - .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, KruizeConstants.RecommendationEngineConstants - .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, 4, 0.25)); - terms.put(KruizeConstants.JSONKeys.MEDIUM_TERM, new Terms(KruizeConstants.JSONKeys.MEDIUM_TERM, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS_THRESHOLD, 7, 1)); - terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS_THRESHOLD, 15, 1)); + // for monitoring use case + terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, + KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, + KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, + 4, 0.25)); + terms.put(KruizeConstants.JSONKeys.MEDIUM_TERM, new Terms(KruizeConstants.JSONKeys.MEDIUM_TERM, + KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS, + KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS_THRESHOLD, + 7, 1)); + terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, + KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS, + KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS_THRESHOLD, + 15, 1)); kruizeObject.setTerms(terms); - } - public static void setDefaultTermsForAutoAndRecreate(Map terms, KruizeObject kruizeObject){ + public static void setDefaultTermsForAutoAndRecreate(Map terms, KruizeObject kruizeObject) { // for auto and recreate mode // Default is Short Term - terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, KruizeConstants.RecommendationEngineConstants - .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, KruizeConstants.RecommendationEngineConstants - .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, 4, 0.25)); + terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, + KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, + KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, + 4, 0.25)); kruizeObject.setTerms(terms); } @@ -170,33 +172,33 @@ public static void setCustomTerms(Map terms, KruizeObject kruizeO // TODO: define term names like daily, weekly, fortnightly etc // TODO: add CRD for terms - if( kruizeObject.getRecommendation_settings() != null && kruizeObject.getRecommendation_settings().getTermSettings() != null ){ + if (kruizeObject.getRecommendation_settings() != null && kruizeObject.getRecommendation_settings().getTermSettings() != null) { List termList = kruizeObject.getRecommendation_settings().getTermSettings().getTerms(); for (String userInputTerm : termList) { if (AnalyzerConstants.RecommendationSettings.SHORT.equalsIgnoreCase(userInputTerm)) { - terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, KruizeConstants.RecommendationEngineConstants - .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, KruizeConstants.RecommendationEngineConstants - .DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, 4, 0.25)); + terms.put(KruizeConstants.JSONKeys.SHORT_TERM, new Terms(KruizeConstants.JSONKeys.SHORT_TERM, + KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS, + KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.SHORT_TERM_DURATION_DAYS_THRESHOLD, + 4, 0.25)); } else if (AnalyzerConstants.RecommendationSettings.MEDIUM.equalsIgnoreCase(userInputTerm)) { - terms.put(KruizeConstants.JSONKeys.MEDIUM_TERM, new Terms(KruizeConstants.JSONKeys.MEDIUM_TERM, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS_THRESHOLD, 7, 1)); + terms.put(KruizeConstants.JSONKeys.MEDIUM_TERM, new Terms(KruizeConstants.JSONKeys.MEDIUM_TERM, + KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS, + KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.MEDIUM_TERM_DURATION_DAYS_THRESHOLD, + 7, 1)); } else if (AnalyzerConstants.RecommendationSettings.LONG.equalsIgnoreCase(userInputTerm)) { - terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS_THRESHOLD, 15, 1)); - + terms.put(KruizeConstants.JSONKeys.LONG_TERM, new Terms(KruizeConstants.JSONKeys.LONG_TERM, + KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS, + KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS_THRESHOLD, + 15, 1)); } else { - // Term name is invalid throw new InvalidTermException(userInputTerm + AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.INVALID_TERM_NAME); } } kruizeObject.setTerms(terms); - } - else { - // Handle the case where termSettings is null + } else { + // Handles the case where termSettings is null throw new InvalidTermException(AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.TERM_SETTINGS_UNDEFINED); } } diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java b/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java index a9cf77b2f..f5df47af0 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java @@ -1,9 +1,6 @@ package com.autotune.analyzer.kruizeObject; -import com.google.gson.annotations.SerializedName; - import java.util.List; -import java.util.Map; public class TermSettings { private List terms; diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index d820808b7..c0f9ad986 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -69,7 +69,7 @@ public class RecommendationEngine { private Map terms; private KruizeObject kruizeObject; private Timestamp interval_end_time; - private List modelName; + private List modelNames; public RecommendationEngine(String experimentName, String intervalEndTimeStr, String intervalStartTimeStr) { @@ -126,7 +126,7 @@ private static int getNumPodsForNamespace(Map filter return (int) Math.ceil(max_pods_cpu); } - private void DefaultLoadRecommendationModel() { + private void loadDefaultRecommendationModels() { // create both cost and performance model by default recommendationModels = new ArrayList<>(); // Create Cost based model @@ -137,7 +137,7 @@ private void DefaultLoadRecommendationModel() { registerModel(performanceBasedRecommendationModel); } - private void DefaultLoadRecommendationModelForAutoAndRecreate() { + private void loadDefaultRecommendationModelForAutoAndRecreate() { // create performance model by default recommendationModels = new ArrayList<>(); // Create Performance based model @@ -145,21 +145,19 @@ private void DefaultLoadRecommendationModelForAutoAndRecreate() { registerModel(performanceBasedRecommendationModel); } - private void CustomLoadRecommendationModel(List modelName) throws InvalidModelException { + private void loadCustomRecommendationModels(List modelName) throws InvalidModelException { // Add new models recommendationModels = new ArrayList<>(); - for(String model : modelName){ - if("cost".equalsIgnoreCase(model)) { + for (String model : modelName) { + if ("cost".equalsIgnoreCase(model)) { // Create Cost based model CostBasedRecommendationModel costBasedRecommendationModel = new CostBasedRecommendationModel(); registerModel(costBasedRecommendationModel); - } - else if("performance".equalsIgnoreCase(model)){ + } else if ("performance".equalsIgnoreCase(model)) { // Create Performance based model PerformanceBasedRecommendationModel performanceBasedRecommendationModel = new PerformanceBasedRecommendationModel(); registerModel(performanceBasedRecommendationModel); - } - else { + } else { // user input does not matches standard models throw new InvalidModelException(modelName + AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.INVALID_MODEL_NAME); } @@ -198,12 +196,12 @@ public void setExperimentName(String experimentName) { this.experimentName = experimentName; } - public List getModelName() { - return modelName; + public List getModelNames() { + return modelNames; } - public void setModelName(List modelName) { - this.modelName = modelName; + public void setModelNames(List modelNames) { + this.modelNames = modelNames; } public Timestamp getInterval_end_time() { @@ -307,7 +305,7 @@ public String validate_local() { //TODO Instead of relying on the 'lo * @param calCount The count of incoming requests. * @return The KruizeObject containing the prepared recommendations. */ - public KruizeObject prepareRecommendations(int calCount, String target_cluster) throws FetchMetricsError { + public KruizeObject prepareRecommendations(int calCount, String target_cluster) throws FetchMetricsError, InvalidModelException { Map mainKruizeExperimentMAP = new ConcurrentHashMap<>(); Map terms = new HashMap<>(); ValidationOutputData validationOutputData; @@ -325,37 +323,31 @@ public KruizeObject prepareRecommendations(int calCount, String target_cluster) // continue to generate recommendation when kruizeObject is successfully created try { // term settings for different use cases - if( kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.MONITOR)) { + if (kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.MONITOR)) { // monitoring mode - if(kruizeObject.getRecommendation_settings() == null || - kruizeObject.getRecommendation_settings().getTermSettings() == null || - kruizeObject.getRecommendation_settings().getTermSettings().getTerms() == null){ + if (kruizeObject.getRecommendation_settings() == null || + kruizeObject.getRecommendation_settings().getTermSettings() == null || + kruizeObject.getRecommendation_settings().getTermSettings().getTerms() == null) { // default for monitoring KruizeObject.setDefaultTerms(terms,kruizeObject); - } - else{ + } else { // Process terms KruizeObject.setCustomTerms(terms, kruizeObject); } - } else if (kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.AUTO) || kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.RECREATE)) { // auto or recreate mode - if(kruizeObject.getRecommendation_settings() == null || + if (kruizeObject.getRecommendation_settings() == null || kruizeObject.getRecommendation_settings().getTermSettings() == null || - kruizeObject.getRecommendation_settings().getTermSettings().getTerms() == null){ - - // default for monitoring + kruizeObject.getRecommendation_settings().getTermSettings().getTerms() == null) { + // default KruizeObject.setDefaultTermsForAutoAndRecreate(terms, kruizeObject); - } - else{ + } else { // terms for auto recreate - // verify if single - if(kruizeObject.getRecommendation_settings().getTermSettings().getTerms().size() == 1) { - // call for that one term + if (kruizeObject.getRecommendation_settings().getTermSettings().getTerms().size() == 1) { + // single term KruizeObject.setCustomTerms(terms, kruizeObject); - } - else{ + } else { // multiple terms throw error throw new InvalidTermException(AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.MULTIPLE_TERMS_UNSUPPORTED); } @@ -370,68 +362,37 @@ else if (kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.AUTO) || krui String dataSource = kruizeObject.getDataSource(); // call different models for different use cases - if( kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.MONITOR)){ + if (kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.MONITOR)) { // can be local or remote monitoring use case - if(kruizeObject.getRecommendation_settings() == null){ + if (kruizeObject.getRecommendation_settings() == null || + kruizeObject.getRecommendation_settings().getModelSettings() == null || + kruizeObject.getRecommendation_settings().getModelSettings().getModels() == null) { // recommendation setting are null -> use default values // both cost and perf model to be called - DefaultLoadRecommendationModel(); - } - else{ - // recommendation setting are present --> check for model settings - if(kruizeObject.getRecommendation_settings().getModelSettings() == null){ - // model settings are not present - DefaultLoadRecommendationModel(); - } - else { - // model settings are present - // for what ever model settings are present do as directed. - List models = kruizeObject.getRecommendation_settings().getModelSettings().getModels(); - if(models == null ){ - // models are not there - DefaultLoadRecommendationModel(); - } - else{ - // models present - setModelName(models); - CustomLoadRecommendationModel(modelName); - } - - } + loadDefaultRecommendationModels(); + } else { + // models present + setModelNames(kruizeObject.getRecommendation_settings().getModelSettings().getModels()); + loadCustomRecommendationModels(modelNames); } - } else if (kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.AUTO) || kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.RECREATE)){ // auto or recreate mode - if(kruizeObject.getRecommendation_settings() == null){ + if (kruizeObject.getRecommendation_settings() == null || + kruizeObject.getRecommendation_settings().getModelSettings() == null || + kruizeObject.getRecommendation_settings().getModelSettings().getModels() != null) { // recommendation setting are null -> use default values - // perf model to be called - DefaultLoadRecommendationModelForAutoAndRecreate(); - } - else{ - // recommendation setting are present --> check for model settings - if(kruizeObject.getRecommendation_settings().getModelSettings() == null){ - // model settings are not present - DefaultLoadRecommendationModelForAutoAndRecreate(); - } - else { - // model settings are present + loadDefaultRecommendationModelForAutoAndRecreate(); + } else { // for what ever model settings are present do as directed. // check for single model - if(kruizeObject.getRecommendation_settings().getModelSettings().getModels() != null && - kruizeObject.getRecommendation_settings().getModelSettings().getModels().size() == 1) { + if (kruizeObject.getRecommendation_settings().getModelSettings().getModels().size() == 1) { // call for that one model - // String model = kruizeObject.getRecommendation_settings().getModelSettings().getModels().get(0); - CustomLoadRecommendationModel(kruizeObject.getRecommendation_settings().getModelSettings().getModels()); - } - else{ + loadCustomRecommendationModels(kruizeObject.getRecommendation_settings().getModelSettings().getModels()); + }else { // multiple model throw error throw new InvalidModelException(AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.MULTIPLE_MODELS_UNSUPPORTED); } - - - } - } } diff --git a/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java b/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java index c99286abb..fc139f081 100644 --- a/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java +++ b/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java @@ -88,7 +88,7 @@ public static KruizeObject convertCreateExperimentAPIObjToKruizeObject(CreateExp recommendationSettings.setTermSettings(termSettings); ModelSettings modelSettings = createExperimentAPIObject.getRecommendationSettings().getModelSettings(); recommendationSettings.setModelSettings(modelSettings); -// recommendationSettings.setThreshold(createExperimentAPIObject.getRecommendationSettings().getThreshold()); + recommendationSettings.setThreshold(createExperimentAPIObject.getRecommendationSettings().getThreshold()); kruizeObject.setRecommendation_settings(recommendationSettings); kruizeObject.setExperiment_id(createExperimentAPIObject.getExperiment_id()); kruizeObject.setStatus(createExperimentAPIObject.getStatus()); diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java index d38f3b878..5016be734 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java @@ -181,10 +181,10 @@ public static final class CreateExperimentAPI { public static final String INVALID_MODE_FOR_NAMESPACE_EXP = "Auto or recreate mode is not supported for namespace experiment."; public static final String INVALID_OBJECT_TYPE_FOR_AUTO_EXP = "Kubernetes object type is not supported for auto or recreate mode."; public static final String AUTO_EXP_NOT_SUPPORTED_FOR_REMOTE = "Auto or recreate mode is not supported for remote monitoring use case."; - public static final String INVALID_TERM_NAME = " term name is not supported, use short, medium or long term."; + public static final String INVALID_TERM_NAME = " Term name is not supported, use short, medium or long term."; public static final String TERM_SETTINGS_UNDEFINED= "Term settings are not defined in the recommendation settings."; public static final String MULTIPLE_TERMS_UNSUPPORTED = "Multiple terms are currently not supported"; - public static final String INVALID_MODEL_NAME = " model name is not supported, use cost or performance."; + public static final String INVALID_MODEL_NAME = " Model name is not supported, use cost or performance."; public static final String MULTIPLE_MODELS_UNSUPPORTED = "Multiple models are currently not supported"; private CreateExperimentAPI() { From 41076e221cc29605707e6b44aa1dad7872edef77 Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Thu, 6 Feb 2025 15:52:46 +0530 Subject: [PATCH 14/18] fix error message --- .../java/com/autotune/analyzer/kruizeObject/KruizeObject.java | 1 - .../analyzer/recommendations/engine/RecommendationEngine.java | 2 +- .../com/autotune/analyzer/utils/AnalyzerErrorConstants.java | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java index a9c9f0855..8e055a229 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java @@ -36,7 +36,6 @@ import java.util.List; import java.util.Map; - /** * Container class for the Autotune kubernetes kind objects. *

diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index c0f9ad986..fd3738373 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -305,7 +305,7 @@ public String validate_local() { //TODO Instead of relying on the 'lo * @param calCount The count of incoming requests. * @return The KruizeObject containing the prepared recommendations. */ - public KruizeObject prepareRecommendations(int calCount, String target_cluster) throws FetchMetricsError, InvalidModelException { + public KruizeObject prepareRecommendations(int calCount, String target_cluster) throws FetchMetricsError { Map mainKruizeExperimentMAP = new ConcurrentHashMap<>(); Map terms = new HashMap<>(); ValidationOutputData validationOutputData; diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java index 5016be734..2de4142af 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java @@ -181,10 +181,10 @@ public static final class CreateExperimentAPI { public static final String INVALID_MODE_FOR_NAMESPACE_EXP = "Auto or recreate mode is not supported for namespace experiment."; public static final String INVALID_OBJECT_TYPE_FOR_AUTO_EXP = "Kubernetes object type is not supported for auto or recreate mode."; public static final String AUTO_EXP_NOT_SUPPORTED_FOR_REMOTE = "Auto or recreate mode is not supported for remote monitoring use case."; - public static final String INVALID_TERM_NAME = " Term name is not supported, use short, medium or long term."; + public static final String INVALID_TERM_NAME = " term name is not supported. Use short, medium or long term."; public static final String TERM_SETTINGS_UNDEFINED= "Term settings are not defined in the recommendation settings."; public static final String MULTIPLE_TERMS_UNSUPPORTED = "Multiple terms are currently not supported"; - public static final String INVALID_MODEL_NAME = " Model name is not supported, use cost or performance."; + public static final String INVALID_MODEL_NAME = " model name is not supported. Use cost or performance."; public static final String MULTIPLE_MODELS_UNSUPPORTED = "Multiple models are currently not supported"; private CreateExperimentAPI() { From 2eb0b25cb5320ed9870a6f448ac29917dbe3a429 Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Thu, 6 Feb 2025 16:13:16 +0530 Subject: [PATCH 15/18] adds space --- .../autotune/analyzer/exceptions/InvalidModelException.java | 2 +- .../autotune/analyzer/exceptions/InvalidTermException.java | 2 +- .../autotune/analyzer/exceptions/InvalidValueException.java | 3 +-- .../analyzer/recommendations/engine/RecommendationEngine.java | 4 ++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/exceptions/InvalidModelException.java b/src/main/java/com/autotune/analyzer/exceptions/InvalidModelException.java index 0f5688f57..eb03635da 100644 --- a/src/main/java/com/autotune/analyzer/exceptions/InvalidModelException.java +++ b/src/main/java/com/autotune/analyzer/exceptions/InvalidModelException.java @@ -15,7 +15,7 @@ *******************************************************************************/ package com.autotune.analyzer.exceptions; -public class InvalidModelException extends Throwable{ +public class InvalidModelException extends Throwable { public InvalidModelException(String model) { super(model); } diff --git a/src/main/java/com/autotune/analyzer/exceptions/InvalidTermException.java b/src/main/java/com/autotune/analyzer/exceptions/InvalidTermException.java index 5b63effb3..2bde04761 100644 --- a/src/main/java/com/autotune/analyzer/exceptions/InvalidTermException.java +++ b/src/main/java/com/autotune/analyzer/exceptions/InvalidTermException.java @@ -15,7 +15,7 @@ *******************************************************************************/ package com.autotune.analyzer.exceptions; -public class InvalidTermException extends Throwable{ +public class InvalidTermException extends Throwable { public InvalidTermException(String term) { super(term); } diff --git a/src/main/java/com/autotune/analyzer/exceptions/InvalidValueException.java b/src/main/java/com/autotune/analyzer/exceptions/InvalidValueException.java index fbdd7d727..464fd5e7b 100644 --- a/src/main/java/com/autotune/analyzer/exceptions/InvalidValueException.java +++ b/src/main/java/com/autotune/analyzer/exceptions/InvalidValueException.java @@ -15,8 +15,7 @@ *******************************************************************************/ package com.autotune.analyzer.exceptions; -public class InvalidValueException extends Throwable -{ +public class InvalidValueException extends Throwable { public InvalidValueException(String namespace) { super(namespace); } diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index fd3738373..5f83580f8 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -376,7 +376,7 @@ else if (kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.AUTO) || krui loadCustomRecommendationModels(modelNames); } } - else if (kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.AUTO) || kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.RECREATE)){ + else if (kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.AUTO) || kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.RECREATE)) { // auto or recreate mode if (kruizeObject.getRecommendation_settings() == null || kruizeObject.getRecommendation_settings().getModelSettings() == null || @@ -389,7 +389,7 @@ else if (kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.AUTO) || krui if (kruizeObject.getRecommendation_settings().getModelSettings().getModels().size() == 1) { // call for that one model loadCustomRecommendationModels(kruizeObject.getRecommendation_settings().getModelSettings().getModels()); - }else { + } else { // multiple model throw error throw new InvalidModelException(AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.MULTIPLE_MODELS_UNSUPPORTED); } From 9c1e06ca85200a12ea844bec507294a526b28ce9 Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Thu, 6 Feb 2025 17:10:16 +0530 Subject: [PATCH 16/18] fixes model name display in error message --- .../analyzer/recommendations/engine/RecommendationEngine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index 5f83580f8..e45b8d97e 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -159,7 +159,7 @@ private void loadCustomRecommendationModels(List modelName) throws Inval registerModel(performanceBasedRecommendationModel); } else { // user input does not matches standard models - throw new InvalidModelException(modelName + AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.INVALID_MODEL_NAME); + throw new InvalidModelException(model + AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.INVALID_MODEL_NAME); } } } From 7654c5b252c9fa3eda4b5b070c121d3f1087e438 Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Tue, 11 Feb 2025 17:39:16 +0530 Subject: [PATCH 17/18] adds null check --- design/KruizeLocalAPI.md | 2 +- .../analyzer/serviceObjects/Converters.java | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/design/KruizeLocalAPI.md b/design/KruizeLocalAPI.md index 5ae03124c..0d5a462e1 100644 --- a/design/KruizeLocalAPI.md +++ b/design/KruizeLocalAPI.md @@ -2573,7 +2573,7 @@ If no experiment type is specified, it will default to `container`. **Request with `model_settings` and `term_settings` field** Under `recommendation_settings`, the `model_settings` and `term_settings` field is optional -and allows you to specify model and term details. Currently, it supports configurations +and can be used to specify model and term details. Currently, it supports configurations for a single model and a single term. Model can be set to either cost or performance and term can be set to short, medium or long term. diff --git a/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java b/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java index fc139f081..ca83afae1 100644 --- a/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java +++ b/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java @@ -83,12 +83,19 @@ public static KruizeObject convertCreateExperimentAPIObjToKruizeObject(CreateExp kruizeObject.setExperimentType(createExperimentAPIObject.getExperimentType()); kruizeObject.setSloInfo(createExperimentAPIObject.getSloInfo()); kruizeObject.setTrial_settings(createExperimentAPIObject.getTrialSettings()); - TermSettings termSettings = createExperimentAPIObject.getRecommendationSettings().getTermSettings(); RecommendationSettings recommendationSettings = new RecommendationSettings(); - recommendationSettings.setTermSettings(termSettings); - ModelSettings modelSettings = createExperimentAPIObject.getRecommendationSettings().getModelSettings(); - recommendationSettings.setModelSettings(modelSettings); - recommendationSettings.setThreshold(createExperimentAPIObject.getRecommendationSettings().getThreshold()); + RecommendationSettings apiRecommendationSettings = createExperimentAPIObject.getRecommendationSettings(); + if (apiRecommendationSettings != null) { + if (apiRecommendationSettings.getTermSettings() != null) { + recommendationSettings.setTermSettings(apiRecommendationSettings.getTermSettings()); + } + if (apiRecommendationSettings.getModelSettings() != null) { + recommendationSettings.setModelSettings(apiRecommendationSettings.getModelSettings()); + } + if (apiRecommendationSettings.getThreshold() != null) { + recommendationSettings.setThreshold(apiRecommendationSettings.getThreshold()); + } + } kruizeObject.setRecommendation_settings(recommendationSettings); kruizeObject.setExperiment_id(createExperimentAPIObject.getExperiment_id()); kruizeObject.setStatus(createExperimentAPIObject.getStatus()); From 81cc3f2ef889abf0cb6316e51ca0a707c236f37f Mon Sep 17 00:00:00 2001 From: bhanvimenghani Date: Wed, 12 Feb 2025 12:02:33 +0530 Subject: [PATCH 18/18] replace with constants --- .../analyzer/recommendations/engine/RecommendationEngine.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index e45b8d97e..9f6d768f7 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -149,11 +149,11 @@ private void loadCustomRecommendationModels(List modelName) throws Inval // Add new models recommendationModels = new ArrayList<>(); for (String model : modelName) { - if ("cost".equalsIgnoreCase(model)) { + if (KruizeConstants.JSONKeys.COST.equalsIgnoreCase(model)) { // Create Cost based model CostBasedRecommendationModel costBasedRecommendationModel = new CostBasedRecommendationModel(); registerModel(costBasedRecommendationModel); - } else if ("performance".equalsIgnoreCase(model)) { + } else if (KruizeConstants.JSONKeys.PERFORMANCE.equalsIgnoreCase(model)) { // Create Performance based model PerformanceBasedRecommendationModel performanceBasedRecommendationModel = new PerformanceBasedRecommendationModel(); registerModel(performanceBasedRecommendationModel);