diff --git a/design/KruizeLocalAPI.md b/design/KruizeLocalAPI.md index 0d5a462e1..218bad490 100644 --- a/design/KruizeLocalAPI.md +++ b/design/KruizeLocalAPI.md @@ -2572,13 +2572,13 @@ 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 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. +Under `recommendation_settings`, the `model_settings` and `term_settings` fields are optional +but can be used to specify model and term details. Currently, for monitoring mode user can set +model as cost and/or performance and terms can be set to short, medium and/or long term. +By default, it provides recommendations for all three terms and both models. -If mode is set to auto or recreate and the above settings are not mentioned then it will -default to `performance` and `short` term. +If mode is set to auto or recreate then there can only be one term and one model chosen. +By default, model will be `performance` and term will be set to `short` term.
Example Request with custom model_settings and term_settings diff --git a/src/main/java/com/autotune/analyzer/autoscaler/vpa/VpaAutoscalerImpl.java b/src/main/java/com/autotune/analyzer/autoscaler/vpa/VpaAutoscalerImpl.java index 227f7c558..be958f1ec 100644 --- a/src/main/java/com/autotune/analyzer/autoscaler/vpa/VpaAutoscalerImpl.java +++ b/src/main/java/com/autotune/analyzer/autoscaler/vpa/VpaAutoscalerImpl.java @@ -17,10 +17,13 @@ package com.autotune.analyzer.autoscaler.vpa; import com.autotune.analyzer.exceptions.ApplyRecommendationsError; +import com.autotune.analyzer.exceptions.InvalidModelException; +import com.autotune.analyzer.exceptions.InvalidTermException; import com.autotune.analyzer.exceptions.UnableToCreateVPAException; import com.autotune.analyzer.kruizeObject.KruizeObject; import com.autotune.analyzer.recommendations.RecommendationConfigItem; import com.autotune.analyzer.autoscaler.AutoscalerImpl; +import com.autotune.analyzer.recommendations.term.Terms; import com.autotune.analyzer.recommendations.utils.RecommendationUtils; import com.autotune.analyzer.utils.AnalyzerConstants; import com.autotune.analyzer.utils.AnalyzerErrorConstants; @@ -28,6 +31,7 @@ import com.autotune.common.data.result.ContainerData; import com.autotune.analyzer.recommendations.objects.MappedRecommendationForTimestamp; import com.autotune.analyzer.recommendations.objects.TermRecommendations; +import com.autotune.utils.KruizeConstants; import io.fabric8.autoscaling.api.model.v1.*; import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.api.model.Quantity; @@ -192,7 +196,7 @@ public void applyResourceRecommendationsForExperiment(KruizeObject kruizeObject) } for (K8sObject k8sObject: kruizeObject.getKubernetes_objects()) { - List containerRecommendations = convertRecommendationsToContainerPolicy(k8sObject.getContainerDataMap()); + List containerRecommendations = convertRecommendationsToContainerPolicy(k8sObject.getContainerDataMap(), kruizeObject); if (containerRecommendations.isEmpty()){ LOGGER.error(AnalyzerErrorConstants.RecommendationUpdaterErrors.RECOMMENDATION_DATA_NOT_PRESENT); } else { @@ -223,7 +227,7 @@ public void applyResourceRecommendationsForExperiment(KruizeObject kruizeObject) } } } - } catch (Exception e) { + } catch (Exception | InvalidTermException | InvalidModelException e) { throw new ApplyRecommendationsError(e.getMessage()); } } @@ -231,7 +235,7 @@ public void applyResourceRecommendationsForExperiment(KruizeObject kruizeObject) /** * This function converts container recommendations for VPA Container Recommendations Object Format */ - private List convertRecommendationsToContainerPolicy(HashMap containerDataMap) { + private List convertRecommendationsToContainerPolicy(HashMap containerDataMap, KruizeObject kruizeObject) throws InvalidTermException, InvalidModelException { List containerRecommendations = new ArrayList<>(); for (Map.Entry containerDataEntry : containerDataMap.entrySet()) { @@ -249,10 +253,31 @@ private List convertRecommendationsToContainerPo * The short-term performance recommendations is currently the default for VPA and is hardcoded. * TODO:// Implement functionality to choose the desired term and model **/ - TermRecommendations termRecommendations = value.getShortTermRecommendations(); - HashMap> recommendationsConfig = termRecommendations.getPerformanceRecommendations().getConfig(); + List terms = new ArrayList<>(kruizeObject.getTerms().values()); + String user_selected_term = terms.get(0).getName(); + + TermRecommendations termRecommendations; + + if (KruizeConstants.JSONKeys.SHORT_TERM.equals(user_selected_term)) { + termRecommendations = value.getShortTermRecommendations(); + } else if (KruizeConstants.JSONKeys.MEDIUM_TERM.equals(user_selected_term)) { + termRecommendations = value.getMediumTermRecommendations(); + } else if (KruizeConstants.JSONKeys.LONG_TERM.equals(user_selected_term)) { + termRecommendations = value.getLongTermRecommendations(); + } else { + throw new IllegalArgumentException("Unknown term: " + user_selected_term); + } + // vpa changes for models + String user_model = kruizeObject.getRecommendation_settings().getModelSettings().getModels().get(0); + HashMap> recommendationsConfig; + + if (KruizeConstants.JSONKeys.COST.equalsIgnoreCase(user_model)) { + recommendationsConfig = termRecommendations.getCostRecommendations().getConfig(); + } else if (KruizeConstants.JSONKeys.PERFORMANCE.equalsIgnoreCase(user_model)) { + recommendationsConfig = termRecommendations.getPerformanceRecommendations().getConfig(); + } else { + throw new IllegalArgumentException("Unknown model: "+ user_model); + } Double cpuRecommendationValue = recommendationsConfig.get(AnalyzerConstants.ResourceSetting.requests).get(AnalyzerConstants.RecommendationItem.CPU).getAmount(); Double memoryRecommendationValue = recommendationsConfig.get(AnalyzerConstants.ResourceSetting.requests).get(AnalyzerConstants.RecommendationItem.MEMORY).getAmount(); diff --git a/src/main/java/com/autotune/analyzer/experiment/ExperimentInitiator.java b/src/main/java/com/autotune/analyzer/experiment/ExperimentInitiator.java index ffc5966e8..87b5d9572 100644 --- a/src/main/java/com/autotune/analyzer/experiment/ExperimentInitiator.java +++ b/src/main/java/com/autotune/analyzer/experiment/ExperimentInitiator.java @@ -15,6 +15,8 @@ *******************************************************************************/ package com.autotune.analyzer.experiment; +import com.autotune.analyzer.exceptions.InvalidModelException; +import com.autotune.analyzer.exceptions.InvalidTermException; import com.autotune.analyzer.exceptions.KruizeResponse; import com.autotune.analyzer.kruizeObject.KruizeObject; import com.autotune.analyzer.serviceObjects.Converters; diff --git a/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java b/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java index c9cc917fd..8426a31d6 100644 --- a/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java +++ b/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java @@ -263,6 +263,73 @@ public ValidationOutputData validateMandatoryFields(KruizeObject expObj) { } ); } + + + if (AnalyzerConstants.AUTO.equalsIgnoreCase(expObj.getMode()) || AnalyzerConstants.RECREATE.equalsIgnoreCase(expObj.getMode())) { + // only vpa specific check for multiple term & model + + if (expObj.getRecommendation_settings().getTermSettings() != null && + expObj.getRecommendation_settings().getTermSettings().getTerms() != null && + expObj.getRecommendation_settings().getTermSettings().getTerms().size() > 1) { + // Checks for multiple terms and throws error + errorMsg = AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.MULTIPLE_TERMS_UNSUPPORTED; + validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); + validationOutputData.setSuccess(false); + validationOutputData.setMessage(errorMsg); + return validationOutputData; + } + // Check for multiple models + if (expObj.getRecommendation_settings().getModelSettings() != null && + expObj.getRecommendation_settings().getModelSettings().getModels() != null && + expObj.getRecommendation_settings().getModelSettings().getModels().size() > 1) { + errorMsg = AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.MULTIPLE_MODELS_UNSUPPORTED; + validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); + validationOutputData.setSuccess(false); + validationOutputData.setMessage(errorMsg); + return validationOutputData; + } + } + + // common check for terms and models + if (expObj.getRecommendation_settings().getTermSettings() != null && + expObj.getRecommendation_settings().getTermSettings().getTerms() != null ) { + Set validTerms = Set.of(KruizeConstants.JSONKeys.SHORT, KruizeConstants.JSONKeys.MEDIUM, KruizeConstants.JSONKeys.LONG); + + for(String term: expObj.getRecommendation_settings().getTermSettings().getTerms()) { + // Check for whitespace in terms + if (term == null || term.trim().isEmpty()) { + errorMsg = AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.WHITESPACE_NOT_ALLOWED; + validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); + validationOutputData.setSuccess(false); + validationOutputData.setMessage(errorMsg); + return validationOutputData; + } + // Check for correct term in terms + if (!validTerms.contains(term)) { + throw new IllegalArgumentException(term + AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.INVALID_TERM_NAME); + } + } + LOGGER.info("All terms are valid"); + } + + if (expObj.getRecommendation_settings().getModelSettings() != null && + expObj.getRecommendation_settings().getModelSettings().getModels() != null) { + Set validModels = Set.of(KruizeConstants.JSONKeys.COST, KruizeConstants.JSONKeys.PERFORMANCE); + + for (String model: expObj.getRecommendation_settings().getModelSettings().getModels()) { + if (model == null || model.trim().isEmpty()) { + errorMsg = AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.WHITESPACE_NOT_ALLOWED; + validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); + validationOutputData.setSuccess(false); + validationOutputData.setMessage(errorMsg); + return validationOutputData; + } + if (!validModels.contains(model)) { + throw new IllegalArgumentException( model + AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.INVALID_MODEL_NAME); + } + } + } + String depType = ""; if (expObj.getExperiment_usecase_type().isRemote_monitoring()) { // In case of RM, kubernetes_obj is mandatory diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java index 8e055a229..026c75612 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/KruizeObject.java @@ -142,15 +142,15 @@ public static void setDefaultTerms(Map terms, KruizeObject kruize // 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, + getTermThresholdInDays(KruizeConstants.JSONKeys.SHORT_TERM, kruizeObject.getTrial_settings().getMeasurement_durationMinutes_inDouble()), 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, + 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, - KruizeConstants.RecommendationEngineConstants.DurationBasedEngine.DurationAmount.LONG_TERM_DURATION_DAYS_THRESHOLD, + getTermThresholdInDays(KruizeConstants.JSONKeys.LONG_TERM, kruizeObject.getTrial_settings().getMeasurement_durationMinutes_inDouble()), 15, 1)); kruizeObject.setTerms(terms); @@ -161,7 +161,7 @@ public static void setDefaultTermsForAutoAndRecreate(Map terms, K // 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, + getTermThresholdInDays(KruizeConstants.JSONKeys.SHORT_TERM, kruizeObject.getTrial_settings().getMeasurement_durationMinutes_inDouble()), 4, 0.25)); kruizeObject.setTerms(terms); @@ -176,20 +176,20 @@ public static void setCustomTerms(Map terms, KruizeObject kruizeO List termList = kruizeObject.getRecommendation_settings().getTermSettings().getTerms(); for (String userInputTerm : termList) { - if (AnalyzerConstants.RecommendationSettings.SHORT.equalsIgnoreCase(userInputTerm)) { + if (KruizeConstants.JSONKeys.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, + getTermThresholdInDays(KruizeConstants.JSONKeys.SHORT_TERM, kruizeObject.getTrial_settings().getMeasurement_durationMinutes_inDouble()), 4, 0.25)); - } else if (AnalyzerConstants.RecommendationSettings.MEDIUM.equalsIgnoreCase(userInputTerm)) { + } else if (KruizeConstants.JSONKeys.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, + getTermThresholdInDays(KruizeConstants.JSONKeys.MEDIUM_TERM, kruizeObject.getTrial_settings().getMeasurement_durationMinutes_inDouble()), 7, 1)); - } else if (AnalyzerConstants.RecommendationSettings.LONG.equalsIgnoreCase(userInputTerm)) { + } else if (KruizeConstants.JSONKeys.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, + getTermThresholdInDays(KruizeConstants.JSONKeys.LONG_TERM, kruizeObject.getTrial_settings().getMeasurement_durationMinutes_inDouble()), 15, 1)); } else { throw new InvalidTermException(userInputTerm + AnalyzerErrorConstants.APIErrors.CreateExperimentAPI.INVALID_TERM_NAME); @@ -412,4 +412,23 @@ 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/ModelSettings.java b/src/main/java/com/autotune/analyzer/kruizeObject/ModelSettings.java index 96fdbc2c3..2dcb5f611 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/ModelSettings.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/ModelSettings.java @@ -1,3 +1,18 @@ +/******************************************************************************* + * 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. + * 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.kruizeObject; import java.util.List; diff --git a/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java b/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java index f5df47af0..d2bb1fb13 100644 --- a/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java +++ b/src/main/java/com/autotune/analyzer/kruizeObject/TermSettings.java @@ -1,3 +1,18 @@ +/******************************************************************************* + * 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. + * 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.kruizeObject; import java.util.List; 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 9f6d768f7..a30f84f1a 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -4,6 +4,7 @@ import com.autotune.analyzer.exceptions.InvalidModelException; import com.autotune.analyzer.exceptions.InvalidTermException; import com.autotune.analyzer.kruizeObject.KruizeObject; +import com.autotune.analyzer.kruizeObject.ModelSettings; import com.autotune.analyzer.kruizeObject.RecommendationSettings; import com.autotune.analyzer.performanceProfiles.MetricProfileCollection; import com.autotune.analyzer.performanceProfiles.PerformanceProfile; @@ -143,6 +144,14 @@ private void loadDefaultRecommendationModelForAutoAndRecreate() { // Create Performance based model PerformanceBasedRecommendationModel performanceBasedRecommendationModel = new PerformanceBasedRecommendationModel(); registerModel(performanceBasedRecommendationModel); + + RecommendationSettings recommendationSettings = kruizeObject.getRecommendation_settings(); + List models = new ArrayList<>() ; + models.add(KruizeConstants.JSONKeys.PERFORMANCE); + ModelSettings modelSettings = new ModelSettings(); + modelSettings.setModels(models); + recommendationSettings.setModelSettings(modelSettings); + } private void loadCustomRecommendationModels(List modelName) throws InvalidModelException { @@ -375,8 +384,7 @@ else if (kruizeObject.getMode().equalsIgnoreCase(AnalyzerConstants.AUTO) || krui setModelNames(kruizeObject.getRecommendation_settings().getModelSettings().getModels()); 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 || diff --git a/src/main/java/com/autotune/analyzer/recommendations/objects/MappedRecommendationForTimestamp.java b/src/main/java/com/autotune/analyzer/recommendations/objects/MappedRecommendationForTimestamp.java index f575d1427..8b8117c5e 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/objects/MappedRecommendationForTimestamp.java +++ b/src/main/java/com/autotune/analyzer/recommendations/objects/MappedRecommendationForTimestamp.java @@ -63,7 +63,7 @@ public void setShortTermRecommendations(TermRecommendations shortTermRecommendat this.recommendationForTermHashMap.put(KruizeConstants.JSONKeys.SHORT_TERM, shortTermRecommendations); } - public MappedRecommendationForTerm getMediumTermRecommendations() { + public TermRecommendations getMediumTermRecommendations() { if (null != this.recommendationForTermHashMap && this.recommendationForTermHashMap.containsKey(KruizeConstants.JSONKeys.MEDIUM_TERM)) return this.recommendationForTermHashMap.get(KruizeConstants.JSONKeys.MEDIUM_TERM); return null; @@ -74,7 +74,7 @@ public void setMediumTermRecommendations(TermRecommendations mediumTermRecommend this.recommendationForTermHashMap.put(KruizeConstants.JSONKeys.MEDIUM_TERM, mediumTermRecommendations); } - public MappedRecommendationForTerm getLongTermRecommendations() { + public TermRecommendations getLongTermRecommendations() { if (null != this.recommendationForTermHashMap && this.recommendationForTermHashMap.containsKey(KruizeConstants.JSONKeys.LONG_TERM)) return this.recommendationForTermHashMap.get(KruizeConstants.JSONKeys.LONG_TERM); return null; diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java index 11fe2c57d..03f53239b 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java @@ -301,15 +301,6 @@ 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 2de4142af..07cc6ed4a 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java @@ -183,10 +183,10 @@ public static final class CreateExperimentAPI { 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 MULTIPLE_TERMS_UNSUPPORTED = "Multiple terms are currently not supported for auto or recreate mode."; 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"; - + public static final String MULTIPLE_MODELS_UNSUPPORTED = "Multiple models are currently not supported for auto or recreate mode."; + public static final String WHITESPACE_NOT_ALLOWED = "Whitespace can not be entered as a term or model value "; private CreateExperimentAPI() { } diff --git a/src/main/java/com/autotune/utils/KruizeConstants.java b/src/main/java/com/autotune/utils/KruizeConstants.java index 3287a99d4..0dbc19f5a 100644 --- a/src/main/java/com/autotune/utils/KruizeConstants.java +++ b/src/main/java/com/autotune/utils/KruizeConstants.java @@ -254,6 +254,9 @@ public static final class JSONKeys { public static final String SHORT_TERM = "short_term"; public static final String MEDIUM_TERM = "medium_term"; public static final String LONG_TERM = "long_term"; + public static final String SHORT = "short"; + public static final String MEDIUM = "medium"; + public static final String LONG= "long"; public static final String RECOMMENDATIONS = "recommendations"; public static final String VARIATION = "variation"; public static final String NOTIFICATIONS = "notifications";