From 152cdaff55b4be33340081f9e59f220c520c50fd Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 24 Dec 2024 17:59:38 +0530 Subject: [PATCH 1/3] Add basic abstractions for metadataProfile --- .../metadataProfiles/MetadataProfile.java | 103 ++++++++ .../MetadataProfileValidation.java | 245 ++++++++++++++++++ .../utils/MetadataProfileUtil.java | 60 +++++ .../analyzer/utils/AnalyzerConstants.java | 16 ++ .../utils/AnalyzerErrorConstants.java | 5 + 5 files changed, 429 insertions(+) create mode 100644 src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfile.java create mode 100644 src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfileValidation.java create mode 100644 src/main/java/com/autotune/analyzer/metadataProfiles/utils/MetadataProfileUtil.java diff --git a/src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfile.java b/src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfile.java new file mode 100644 index 000000000..095ffbfa5 --- /dev/null +++ b/src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfile.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2024, 2024 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.metadataProfiles; + +import com.autotune.common.data.metrics.Metric; +import com.fasterxml.jackson.databind.JsonNode; +import com.google.gson.annotations.SerializedName; + +import java.util.ArrayList; + +/** + * Container class for the MetadataProfile kubernetes kind, which is used to define + * a metadata queries + * + * This class provides a direct representation of MetadataProfile CRD in JSON format, + * corresponding to the structure of MetadataProfile YAML file. It includes mandatory fields + * for API version, kind, metadata and additional custom fields - profile_version, k8s_type and query_variables + */ + +public class MetadataProfile { + private String apiVersion; + + private String kind; + + private JsonNode metadata; + + private String name; + + private double profile_version; + + @SerializedName("k8s_type") + private String k8s_type; + + @SerializedName("query_variables") + private ArrayList metrics; + + public MetadataProfile(String apiVersion, String kind, JsonNode metadata, + double profile_version, String k8s_type, ArrayList metrics) { + + this.apiVersion = apiVersion; + this.kind = kind; + this.metadata = metadata; + this.name = metadata.get("name").asText(); + this.profile_version = profile_version; + this.k8s_type = k8s_type; + this.metrics = metrics; + } + + public String getApiVersion() { + return apiVersion; + } + + public String getKind() { + return kind; + } + + public JsonNode getMetadata() { + return metadata; + } + + public String getName() { + return name; + } + + public double getProfile_version() { + return profile_version; + } + + public String getK8s_type() { + return k8s_type; + } + + public ArrayList getQueryVariables() { + return new ArrayList<>(metrics); + } + + @Override + public String toString() { + return "MetadataProfile{" + + "apiVersion='" + apiVersion + '\'' + + ", kind='" + kind + '\'' + + ", metadata=" + metadata + + ", name='" + name + '\'' + + ", profile_version=" + profile_version + + ", k8s_type='" + k8s_type + '\'' + + ", query_variables=" + metrics + + '}'; + } + +} diff --git a/src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfileValidation.java b/src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfileValidation.java new file mode 100644 index 000000000..8baa524e2 --- /dev/null +++ b/src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfileValidation.java @@ -0,0 +1,245 @@ +/******************************************************************************* + * Copyright (c) 2024, 2024 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.metadataProfiles; + +import com.autotune.analyzer.utils.AnalyzerConstants; +import com.autotune.analyzer.utils.AnalyzerErrorConstants; +import com.autotune.common.data.ValidationOutputData; +import com.autotune.common.data.metrics.Metric; +import com.autotune.utils.KruizeConstants; +import com.autotune.utils.KruizeSupportedTypes; +import com.fasterxml.jackson.databind.JsonNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +public class MetadataProfileValidation { + private static final Logger LOGGER = LoggerFactory.getLogger(MetadataProfileValidation.class); + private boolean success; + private String errorMessage; + private final Map metadataProfilesMap; + + //Mandatory fields for MetadataProfile + private final List mandatoryMetadataFields = new ArrayList<>(Arrays.asList( + AnalyzerConstants.API_VERSION, + AnalyzerConstants.KIND, + AnalyzerConstants.AutotuneObjectConstants.METADATA, + AnalyzerConstants.MetadataProfileConstants.QUERY_VARIABLES + )); + + private final List mandatoryQueryVariables = new ArrayList<>(Arrays.asList( + AnalyzerConstants.AutotuneObjectConstants.NAME, + AnalyzerConstants.AutotuneObjectConstants.DATASOURCE, + AnalyzerConstants.MetadataProfileConstants.VALUE_TYPE + )); + + public MetadataProfileValidation(Map metadataProfilesMap) { + this.metadataProfilesMap = metadataProfilesMap; + } + + /** + * Validates query variables + * + * @param metadataProfile Metadata Profile Object to be validated + * @return Returns the ValidationOutputData containing the response based on the validation + */ + public ValidationOutputData validate(MetadataProfile metadataProfile) { + + return validateMetadataProfileData(metadataProfile); + } + + /** + * Validates the data present in the metadata profile object before adding it to the map + * @param metadataProfile Metadata Profile Object to be validated + * @return Returns the ValidationOutputData containing the response based on the validation + */ + private ValidationOutputData validateMetadataProfileData(MetadataProfile metadataProfile) { + ValidationOutputData validationOutputData = new ValidationOutputData(false, null, null); + StringBuilder errorString = new StringBuilder(); + try { + // validate the mandatory values first + validationOutputData = validateMandatoryMetadataProfileFieldsAndData(metadataProfile); + + // If the mandatory values are present,proceed for further validation else return the validation object directly + if (validationOutputData.isSuccess()) { + // TODO: Loading saved metadata profiles from DB + + // Check if profile metadata exists + JsonNode metadata = metadataProfile.getMetadata(); + if (null == metadata) { + errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.MISSING_METADATA_PROFILE_METADATA); + } + // check if the metadata profile already exists + if (null != metadataProfilesMap.get(metadataProfile.getMetadata().get("name").asText())) { + errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.DUPLICATE_METADATA_PROFILE).append(metadataProfile.getMetadata().get("name").asText()); + return new ValidationOutputData(false, errorString.toString(), HttpServletResponse.SC_CONFLICT); + } + + // Validates fields like k8s_type and slo object + validateCommonProfileFields(metadataProfile, errorString, validationOutputData); + + if (!errorString.toString().isEmpty()) { + validationOutputData.setSuccess(false); + validationOutputData.setMessage(errorString.toString()); + validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); + } else { + validationOutputData.setSuccess(true); + } + } + } catch (Exception e){ + validationOutputData.setSuccess(false); + validationOutputData.setMessage(errorString.toString()); + validationOutputData.setErrorCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + return validationOutputData; + } + + /** + * Check if all mandatory values are present. + * + * @param metadataObj Mandatory fields of this Metadata Profile Object will be validated + * @return ValidationOutputData object containing status of the validations + */ + public ValidationOutputData validateMandatoryMetadataProfileFieldsAndData(MetadataProfile metadataObj) { + List missingMandatoryFields = new ArrayList<>(); + ValidationOutputData validationOutputData = new ValidationOutputData(false, null, null); + String errorMsg; + errorMsg = ""; + mandatoryMetadataFields.forEach( + mField -> { + String methodName = "get" + mField.substring(0, 1).toUpperCase() + mField.substring(1); + try { + LOGGER.debug("MethodName = {}",methodName); + Method getNameMethod = metadataObj.getClass().getMethod(methodName); + if (null == getNameMethod.invoke(metadataObj) || getNameMethod.invoke(metadataObj).toString().isEmpty()) + missingMandatoryFields.add(mField); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + LOGGER.error("Method name {} doesn't exist!", mField); + } + } + ); + if (missingMandatoryFields.isEmpty()) { + try { + String mandatoryMetadataPerf = AnalyzerConstants.MetadataProfileConstants.METADATA_PROFILE_NAME; + try { + JsonNode metadata = metadataObj.getMetadata(); + String metadataProfileName = metadata.get(mandatoryMetadataPerf).asText(); + if (null == metadataProfileName || metadataProfileName.isEmpty() || metadataProfileName.equals("null")) { + missingMandatoryFields.add(mandatoryMetadataPerf); + } + } catch (Exception e) { + LOGGER.error("Method name doesn't exist for: {}!", mandatoryMetadataPerf); + } + + if (missingMandatoryFields.isEmpty()) { + mandatoryQueryVariables.forEach( + mField -> { + String methodName = "get" + mField.substring(0, 1).toUpperCase() + mField.substring(1); + try { + LOGGER.debug("MethodName = {}", methodName); + Method getNameMethod = metadataObj.getQueryVariables().get(0) + .getClass().getMethod(methodName); + if (getNameMethod.invoke(metadataObj.getQueryVariables().get(0)) == null) + missingMandatoryFields.add(mField); + } catch (NoSuchMethodException | IllegalAccessException | + InvocationTargetException e) { + LOGGER.error("Method name {} doesn't exist!", mField); + } + + }); + validationOutputData.setSuccess(true); + + } + + if (!missingMandatoryFields.isEmpty()) { + errorMsg = errorMsg.concat(String.format("Missing mandatory parameters: %s ", missingMandatoryFields)); + validationOutputData.setSuccess(false); + validationOutputData.setMessage(errorMsg); + validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); + LOGGER.error("Validation error message :{}", errorMsg); + } + } catch (Exception e) { + validationOutputData.setSuccess(false); + errorMsg = errorMsg.concat(e.getMessage()); + validationOutputData.setMessage(errorMsg); + validationOutputData.setErrorCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } else { + errorMsg = errorMsg.concat(String.format("Missing mandatory parameters: %s ", missingMandatoryFields)); + validationOutputData.setSuccess(false); + validationOutputData.setMessage(errorMsg); + validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); + LOGGER.error("Validation error message :{}", errorMsg); + } + + return validationOutputData; + } + + /** + * Validates fields like k8s_type and query_variables + * @param metadataProfile Metadata Profile object to be validated + * @param errorString StringBuilder to collect error messages during validation of multiple fields + * @param validationOutputData ValidationOutputData containing the response based on the validation + */ + private void validateCommonProfileFields(MetadataProfile metadataProfile, StringBuilder errorString, ValidationOutputData validationOutputData){ + // Check if k8s type is supported + String k8sType = metadataProfile.getK8s_type(); + if (!KruizeSupportedTypes.K8S_TYPES_SUPPORTED.contains(k8sType)) { + errorString.append(AnalyzerConstants.MetadataProfileConstants.K8S_TYPE).append(k8sType) + .append(AnalyzerErrorConstants.AutotuneObjectErrors.UNSUPPORTED); + } + + + // Check if query_variables is empty + if (metadataProfile.getQueryVariables().isEmpty()) + errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.QUERY_VARIABLES_EMPTY); + + + for (Metric queryVariable : metadataProfile.getQueryVariables()) { + // Check if datasource is supported + if (!KruizeSupportedTypes.MONITORING_AGENTS_SUPPORTED.contains(queryVariable.getDatasource().toLowerCase())) { + errorString.append(AnalyzerConstants.AutotuneObjectConstants.QUERY_VARIABLE) + .append(queryVariable.getName()) + .append(AnalyzerErrorConstants.AutotuneObjectErrors.DATASOURCE_NOT_SUPPORTED); + } + + // Check if value_type is supported + if (!KruizeSupportedTypes.VALUE_TYPES_SUPPORTED.contains(queryVariable.getValueType().toLowerCase())) { + errorString.append(AnalyzerConstants.AutotuneObjectConstants.QUERY_VARIABLE) + .append(queryVariable.getName()) + .append(AnalyzerErrorConstants.AutotuneObjectErrors.VALUE_TYPE_NOT_SUPPORTED); + } + + // Check if kubernetes_object type is supported, set default to 'container' if it's absent. + String kubernetes_object = queryVariable.getKubernetesObject(); + if (null == kubernetes_object) + queryVariable.setKubernetesObject(KruizeConstants.JSONKeys.CONTAINER); + else { + if (!KruizeSupportedTypes.KUBERNETES_OBJECTS_SUPPORTED.contains(kubernetes_object.toLowerCase())) + errorString.append(AnalyzerConstants.KUBERNETES_OBJECTS).append(kubernetes_object) + .append(AnalyzerErrorConstants.AutotuneObjectErrors.UNSUPPORTED); + } + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/autotune/analyzer/metadataProfiles/utils/MetadataProfileUtil.java b/src/main/java/com/autotune/analyzer/metadataProfiles/utils/MetadataProfileUtil.java new file mode 100644 index 000000000..9ed9b48c9 --- /dev/null +++ b/src/main/java/com/autotune/analyzer/metadataProfiles/utils/MetadataProfileUtil.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2024 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.metadataProfiles.utils; + +import com.autotune.analyzer.metadataProfiles.MetadataProfile; +import com.autotune.analyzer.metadataProfiles.MetadataProfileValidation; +import com.autotune.common.data.ValidationOutputData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletResponse; +import java.util.*; + +public class MetadataProfileUtil { + private static final Logger LOGGER = LoggerFactory.getLogger(com.autotune.analyzer.metadataProfiles.utils.MetadataProfileUtil.class); + private MetadataProfileUtil() { + + } + + /** + * validates the metadata profile fields and the data and then adds it to the map + * @param metadataProfile + * @return + */ + public static ValidationOutputData validateAndAddMetadataProfile(Map metadataProfileMapProfilesMap, MetadataProfile metadataProfile) { + ValidationOutputData validationOutputData; + try { + validationOutputData = new MetadataProfileValidation(metadataProfileMapProfilesMap).validate(metadataProfile); + if (validationOutputData.isSuccess()) { + addMetadataProfile(metadataProfileMapProfilesMap, metadataProfile); + } else { + validationOutputData.setMessage("Validation failed: " + validationOutputData.getMessage()); + } + } catch (Exception e) { + LOGGER.error("Validate and add profile failed: {}", e.getMessage()); + validationOutputData = new ValidationOutputData(false, "Validation failed: " + e.getMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + return validationOutputData; + } + + + public static void addMetadataProfile(Map metadataProfileMap, MetadataProfile metadataProfile) { + metadataProfileMap.put(metadataProfile.getMetadata().get("name").asText(), metadataProfile); + LOGGER.debug("Added MetadataProfile: {} ", metadataProfile.getMetadata().get("name")); + } + +} diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java index db256caaa..969251d67 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java @@ -335,6 +335,7 @@ public static final class AutotuneObjectConstants { public static final String HPO_ALGO_IMPL = "hpo_algo_impl"; public static final String DEFAULT_HPO_ALGO_IMPL = "optuna_tpe"; public static final String FUNCTION_VARIABLE = "function_variable: "; + public static final String QUERY_VARIABLE = "query_variable: "; public static final String CLUSTER_NAME = "cluster_name"; private AutotuneObjectConstants() { @@ -599,6 +600,21 @@ public static final class PerformanceProfileConstants { ); } + public static final class MetadataProfileConstants { + + public static final String QUERY_VARIABLES = "queryVariables"; + public static final String METADATA_PROFILE_NAME = "name"; + public static final String K8S_TYPE = "k8s_type"; + public static final String METADATA_PROFILE_MAP = "metadataProfileMap"; + public static final String VALUE_TYPE = "valueType"; + public static final String DEFAULT_API_VERSION = "recommender.com/v1"; + public static final String DEFAULT_KIND = "KruizeMetadataProfile"; + public static final String DEFAULT_PROFILE = "default"; + public static final String METADATA_PROFILE = "metadataProfile"; + public static final String METADATA_PROFILE_PLURALS = "kruizemetadataprofiles"; + public static final String METADATA_PROFILE_RESOURCE_NAME = METADATA_PROFILE_PLURALS + GROUP; + } + public static final class K8sObjectConstants { private K8sObjectConstants() { diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java index b5a092594..806a28357 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java @@ -57,6 +57,7 @@ public static final class AutotuneObjectErrors { public static final String SLO_CLASS_NOT_SUPPORTED = "slo_class " + UNSUPPORTED; public static final String DIRECTION_NOT_SUPPORTED = "direction " + UNSUPPORTED; public static final String FUNCTION_VARIABLES_EMPTY = "function_variables is empty\n"; + public static final String QUERY_VARIABLES_EMPTY = "query_variables is empty\n"; public static final String OBJECTIVE_FUNCTION_MISSING = "objective_function missing\n"; public static final String MODE_NOT_SUPPORTED = "Autotune object mode " + UNSUPPORTED; public static final String TARGET_CLUSTER_NOT_SUPPORTED = "Autotune object targetCluster " + UNSUPPORTED; @@ -82,6 +83,10 @@ public static final class AutotuneObjectErrors { public static final String MISSING_PERF_PROFILE = "Not Found: performance_profile does not exist: "; public static final String MISSING_METRIC_PROFILE_METADATA= "metadata missing\n"; public static final String DUPLICATE_METRIC_PROFILE = "Metric Profile already exists: "; + public static final String MISSING_METADATA_PROFILE = "Not Found: metadata_profile does not exist: "; + public static final String METADATA_PROFILE_NOT_SUPPORTED = "Metadata profile is not supported in remote monitoring: "; + public static final String MISSING_METADATA_PROFILE_METADATA= "metadata missing\n"; + public static final String DUPLICATE_METADATA_PROFILE = "Metadata Profile already exists: "; public static final String MISSING_EXPERIMENT_NAME = "Not Found: experiment_name does not exist: "; public static final String NO_METRICS_AVAILABLE = "No metrics available from %s to %s"; public static final String UNSUPPORTED_EXPERIMENT = String.format("At present, the system does not support bulk entries!"); From 6f294544e5f232957b118c820fb39cca525d580e Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 24 Dec 2024 19:31:22 +0530 Subject: [PATCH 2/3] Add java doc and string constants --- .../MetadataProfileValidation.java | 40 ++++++++++++++----- .../utils/MetadataProfileUtil.java | 14 +++++-- .../analyzer/utils/AnalyzerConstants.java | 7 ++++ .../com/autotune/utils/KruizeConstants.java | 6 +++ 4 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfileValidation.java b/src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfileValidation.java index 8baa524e2..6ee1b2881 100644 --- a/src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfileValidation.java +++ b/src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfileValidation.java @@ -33,6 +33,9 @@ import java.util.List; import java.util.Map; +/** + * This class validates MetadataProfile fields and object + */ public class MetadataProfileValidation { private static final Logger LOGGER = LoggerFactory.getLogger(MetadataProfileValidation.class); private boolean success; @@ -90,8 +93,8 @@ private ValidationOutputData validateMetadataProfileData(MetadataProfile metadat errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.MISSING_METADATA_PROFILE_METADATA); } // check if the metadata profile already exists - if (null != metadataProfilesMap.get(metadataProfile.getMetadata().get("name").asText())) { - errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.DUPLICATE_METADATA_PROFILE).append(metadataProfile.getMetadata().get("name").asText()); + if (null != metadataProfilesMap.get(metadataProfile.getMetadata().get(KruizeConstants.JSONKeys.NAME).asText())) { + errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.DUPLICATE_METADATA_PROFILE).append(metadataProfile.getMetadata().get(KruizeConstants.JSONKeys.NAME).asText()); return new ValidationOutputData(false, errorString.toString(), HttpServletResponse.SC_CONFLICT); } @@ -129,12 +132,12 @@ public ValidationOutputData validateMandatoryMetadataProfileFieldsAndData(Metada mField -> { String methodName = "get" + mField.substring(0, 1).toUpperCase() + mField.substring(1); try { - LOGGER.debug("MethodName = {}",methodName); + LOGGER.debug(AnalyzerConstants.CommonProfileMsgs.METHOD_NAME,methodName); Method getNameMethod = metadataObj.getClass().getMethod(methodName); if (null == getNameMethod.invoke(metadataObj) || getNameMethod.invoke(metadataObj).toString().isEmpty()) missingMandatoryFields.add(mField); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - LOGGER.error("Method name {} doesn't exist!", mField); + LOGGER.error(AnalyzerConstants.CommonProfileMsgs.INVALID_METHOD_NAME, mField); } } ); @@ -148,7 +151,7 @@ public ValidationOutputData validateMandatoryMetadataProfileFieldsAndData(Metada missingMandatoryFields.add(mandatoryMetadataPerf); } } catch (Exception e) { - LOGGER.error("Method name doesn't exist for: {}!", mandatoryMetadataPerf); + LOGGER.error(AnalyzerConstants.CommonProfileMsgs.INVALID_METHOD_NAME, mandatoryMetadataPerf); } if (missingMandatoryFields.isEmpty()) { @@ -156,14 +159,14 @@ public ValidationOutputData validateMandatoryMetadataProfileFieldsAndData(Metada mField -> { String methodName = "get" + mField.substring(0, 1).toUpperCase() + mField.substring(1); try { - LOGGER.debug("MethodName = {}", methodName); + LOGGER.debug(AnalyzerConstants.CommonProfileMsgs.METHOD_NAME, methodName); Method getNameMethod = metadataObj.getQueryVariables().get(0) .getClass().getMethod(methodName); if (getNameMethod.invoke(metadataObj.getQueryVariables().get(0)) == null) missingMandatoryFields.add(mField); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - LOGGER.error("Method name {} doesn't exist!", mField); + LOGGER.error(AnalyzerConstants.CommonProfileMsgs.INVALID_METHOD_NAME, mField); } }); @@ -172,11 +175,11 @@ public ValidationOutputData validateMandatoryMetadataProfileFieldsAndData(Metada } if (!missingMandatoryFields.isEmpty()) { - errorMsg = errorMsg.concat(String.format("Missing mandatory parameters: %s ", missingMandatoryFields)); + errorMsg = errorMsg.concat(String.format(AnalyzerConstants.CommonProfileMsgs.MISSING_MANDATORY_PARAMETERS, missingMandatoryFields)); validationOutputData.setSuccess(false); validationOutputData.setMessage(errorMsg); validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); - LOGGER.error("Validation error message :{}", errorMsg); + LOGGER.error(AnalyzerConstants.CommonProfileMsgs.VALIDATION_ERROR_MSG, errorMsg); } } catch (Exception e) { validationOutputData.setSuccess(false); @@ -185,11 +188,11 @@ public ValidationOutputData validateMandatoryMetadataProfileFieldsAndData(Metada validationOutputData.setErrorCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } } else { - errorMsg = errorMsg.concat(String.format("Missing mandatory parameters: %s ", missingMandatoryFields)); + errorMsg = errorMsg.concat(String.format(AnalyzerConstants.CommonProfileMsgs.MISSING_MANDATORY_PARAMETERS, missingMandatoryFields)); validationOutputData.setSuccess(false); validationOutputData.setMessage(errorMsg); validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); - LOGGER.error("Validation error message :{}", errorMsg); + LOGGER.error(AnalyzerConstants.CommonProfileMsgs.VALIDATION_ERROR_MSG, errorMsg); } return validationOutputData; @@ -242,4 +245,19 @@ private void validateCommonProfileFields(MetadataProfile metadataProfile, String } } + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + @Override + public String toString() { + return "MetadataProfileValidation{" + + "success=" + success + + ", errorMessage='" + errorMessage + '\'' + + '}'; + } + } \ No newline at end of file diff --git a/src/main/java/com/autotune/analyzer/metadataProfiles/utils/MetadataProfileUtil.java b/src/main/java/com/autotune/analyzer/metadataProfiles/utils/MetadataProfileUtil.java index 9ed9b48c9..a3d15fe60 100644 --- a/src/main/java/com/autotune/analyzer/metadataProfiles/utils/MetadataProfileUtil.java +++ b/src/main/java/com/autotune/analyzer/metadataProfiles/utils/MetadataProfileUtil.java @@ -18,12 +18,16 @@ import com.autotune.analyzer.metadataProfiles.MetadataProfile; import com.autotune.analyzer.metadataProfiles.MetadataProfileValidation; import com.autotune.common.data.ValidationOutputData; +import com.autotune.utils.KruizeConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletResponse; import java.util.*; +/** + * Utils class for MetadataProfile + */ public class MetadataProfileUtil { private static final Logger LOGGER = LoggerFactory.getLogger(com.autotune.analyzer.metadataProfiles.utils.MetadataProfileUtil.class); private MetadataProfileUtil() { @@ -42,11 +46,13 @@ public static ValidationOutputData validateAndAddMetadataProfile(Map metadataProfileMap, MetadataProfile metadataProfile) { metadataProfileMap.put(metadataProfile.getMetadata().get("name").asText(), metadataProfile); - LOGGER.debug("Added MetadataProfile: {} ", metadataProfile.getMetadata().get("name")); + LOGGER.debug(KruizeConstants.MetadataProfileConstants.ADD_METADATA_PROFILE, metadataProfile.getMetadata().get("name")); } } diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java index 969251d67..7cd7088b5 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java @@ -615,6 +615,13 @@ public static final class MetadataProfileConstants { public static final String METADATA_PROFILE_RESOURCE_NAME = METADATA_PROFILE_PLURALS + GROUP; } + public static final class CommonProfileMsgs { + public static final String METHOD_NAME = "MethodName = {}"; + public static final String INVALID_METHOD_NAME = "Method name {} doesn't exist!"; + public static final String MISSING_MANDATORY_PARAMETERS = "Missing mandatory parameters: %s "; + public static final String VALIDATION_ERROR_MSG = "Validation error message :{}"; + } + public static final class K8sObjectConstants { private K8sObjectConstants() { diff --git a/src/main/java/com/autotune/utils/KruizeConstants.java b/src/main/java/com/autotune/utils/KruizeConstants.java index ff0b52592..ec65c593e 100644 --- a/src/main/java/com/autotune/utils/KruizeConstants.java +++ b/src/main/java/com/autotune/utils/KruizeConstants.java @@ -910,4 +910,10 @@ public enum WebHookStatus { } } + + public static final class MetadataProfileConstants { + public static final String METADATA_PROFILE_VALIDATION_FAILURE = "MetadataProfile validation failed: "; + public static final String METADATA_PROFILE_VALIDATION_AND_ADD_FAILURE = "Validate and add metadata profile failed: {}"; + public static final String ADD_METADATA_PROFILE = "Added MetadataProfile: {}"; + } } From b0eff3953a87707af896c138857a070d728ce474 Mon Sep 17 00:00:00 2001 From: Shreya Date: Mon, 13 Jan 2025 15:42:57 +0530 Subject: [PATCH 3/3] Add missing EOF and validate datasource at global level --- .../analyzer/metadataProfiles/MetadataProfileValidation.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfileValidation.java b/src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfileValidation.java index 6ee1b2881..cba530c75 100644 --- a/src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfileValidation.java +++ b/src/main/java/com/autotune/analyzer/metadataProfiles/MetadataProfileValidation.java @@ -47,12 +47,12 @@ public class MetadataProfileValidation { AnalyzerConstants.API_VERSION, AnalyzerConstants.KIND, AnalyzerConstants.AutotuneObjectConstants.METADATA, + AnalyzerConstants.AutotuneObjectConstants.DATASOURCE, AnalyzerConstants.MetadataProfileConstants.QUERY_VARIABLES )); private final List mandatoryQueryVariables = new ArrayList<>(Arrays.asList( AnalyzerConstants.AutotuneObjectConstants.NAME, - AnalyzerConstants.AutotuneObjectConstants.DATASOURCE, AnalyzerConstants.MetadataProfileConstants.VALUE_TYPE )); @@ -260,4 +260,4 @@ public String toString() { '}'; } -} \ No newline at end of file +}