From 5b0a36454780e8f29df5c7f2c0da91efc62e89a6 Mon Sep 17 00:00:00 2001 From: mojahidi Date: Thu, 15 Mar 2018 18:45:49 +0530 Subject: Added validation for Interface Operation Added validation for interface Operation, added input parameter names validation Change-Id: Ib02ec89f7fb53bd08481631c705c9f15757bf768 Issue-ID: SDC-1060 Signed-off-by: mojahidi --- .../validation/InterfaceOperationValidation.java | 254 +++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java (limited to 'catalog-be/src/main/java/org') diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java new file mode 100644 index 0000000000..bf3385a076 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java @@ -0,0 +1,254 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * 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 org.openecomp.sdc.be.components.validation; + +import fj.data.Either; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang.StringUtils; +import org.openecomp.sdc.be.components.impl.ResponseFormatManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +@Component("interfaceOperationValidation") +public class InterfaceOperationValidation { + + @Autowired + private ToscaOperationFacade toscaOperationFacade; + private static final String TYPE_VALIDATION_REGEX = "^[a-zA-Z]{1,200}$"; + private static final int DESCRIPTION_MAX_LENGTH = 200; + + private static final Logger LOGGER = LoggerFactory.getLogger(InterfaceOperationValidation.class); + + public Either validateInterfaceOperations( + Collection interfaceOperations, + String resourceId, boolean isUpdate) { + + for(Operation interfaceOperation : interfaceOperations) { + Either interfaceOperationValidatorResponse = validateInterfaceOperation( + interfaceOperation, resourceId, isUpdate); + if (interfaceOperationValidatorResponse.isRight()) { + return interfaceOperationValidatorResponse; + } + } + return Either.left(Boolean.TRUE); + } + + private Either validateInterfaceOperation(Operation interfaceOperation, + String resourceId, boolean isUpdate) { + ResponseFormatManager responseFormatManager = getResponseFormatManager(); + + Either interfaceOperationTypeResponse = validateInterfaceOperationType(interfaceOperation, + responseFormatManager, resourceId, isUpdate); + if (interfaceOperationTypeResponse != null) { + return interfaceOperationTypeResponse; + } + + Either descriptionResponseEither = validateDescription(responseFormatManager, + interfaceOperation.getDescription()); + if (descriptionResponseEither != null) { + return descriptionResponseEither; + } + + Either inputParametersResponse = validateInputParameters(interfaceOperation, + responseFormatManager); + if(inputParametersResponse != null) { + return inputParametersResponse; + } + return Either.left(true); + } + + private Either validateInterfaceOperationType(Operation interfaceOperation, + ResponseFormatManager responseFormatManager, + String resourceId, boolean isUpdate) { + + Either operationTypeEmptyEither = isOperationTypeEmpty(responseFormatManager, + interfaceOperation.getName()); // treating name as type for now + if (operationTypeEmptyEither != null) { + return operationTypeEmptyEither; + } + + Either operationTypeRegexValidationResponse = + validateOperationTypeRegex(responseFormatManager, interfaceOperation.getName()); + if (operationTypeRegexValidationResponse != null) { + return operationTypeRegexValidationResponse; + } + + Either operationTypeUniqueResponse = validateOperationTypeUnique(interfaceOperation, + resourceId, isUpdate, responseFormatManager ); + if(operationTypeUniqueResponse.isRight()) { + return Either.right(operationTypeUniqueResponse.right().value()); + } + if (!operationTypeUniqueResponse.left().value()) { + LOGGER.debug("Interface Operation type {} already in use ", interfaceOperation.getName()); + ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus + .INTERFACE_OPERATION_TYPE_ALREADY_IN_USE, interfaceOperation.getName()); + return Either.right(errorResponse); + } + return null; + } + + private Either validateOperationTypeRegex(ResponseFormatManager responseFormatManager, + String operationType) { + if (!isValidOperationType(operationType)) { + LOGGER.debug("Interface Operation type {} is invalid, Operation type should not contain" + + "Special character, space and should not be greater than 200 characters", operationType); + ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus + .INTERFACE_OPERATION_TYPE_INVALID, operationType); + return Either.right(errorResponse); + } + return null; + } + + private Either isOperationTypeEmpty(ResponseFormatManager responseFormatManager, + String operationType) { + if (StringUtils.isEmpty(operationType)) { + LOGGER.debug("Interface Operation type is mandatory, it can't be empty"); + ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus + .INTERFACE_OPERATION_TYPE_MANDATORY); + return Either.right(errorResponse); + } + return null; + } + + private Either validateDescription(ResponseFormatManager responseFormatManager, + String description) { + if (description.length() > DESCRIPTION_MAX_LENGTH) { + LOGGER.debug("Interface Operation description {} is invalid, maximum 200 characters allowed", description); + ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus + .INTERFACE_OPERATION_DESCRIPTION_MAX_LENGTH); + return Either.right(errorResponse); + } + return null; + } + + private boolean isValidOperationType(String operationType) { + return Pattern.matches(TYPE_VALIDATION_REGEX, operationType); + } + + private Either validateOperationTypeUnique(Operation interfaceOperation, + String resourceId, + boolean isUpdate, + ResponseFormatManager responseFormatManager) { + boolean isOperationTypeUnique = false; + ComponentParametersView filter = new ComponentParametersView(true); + filter.setIgnoreInterfaces(false); + Either interfaceOperationOrigin = toscaOperationFacade + .getToscaElement(resourceId, filter); + if (interfaceOperationOrigin.isRight()){ + LOGGER.debug("Failed to fetch interface operation information by resource id {} ", resourceId); + return Either.right(responseFormatManager.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + Collection interfaceDefinitions = interfaceOperationOrigin.left().value() + .getInterfaces().values(); + if(CollectionUtils.isEmpty(interfaceDefinitions)){ + isOperationTypeUnique = true; + return Either.left(isOperationTypeUnique); + } + Collection allOperations = interfaceDefinitions.stream() + .filter(a -> MapUtils.isNotEmpty(a.getOperationsMap())) + .map(a -> a.getOperationsMap().values()).flatMap(Collection::stream) + .collect(Collectors.toList()); + if(CollectionUtils.isEmpty(allOperations)){ + isOperationTypeUnique = true; + return Either.left(isOperationTypeUnique); + } + + Map operationTypes = new HashMap<>(); + allOperations.forEach(operationType -> operationTypes.put(operationType.getUniqueId(), + operationType.getName()) ); + + if (isUpdate){ + isOperationTypeUnique = validateOperationTypeUniqueForUpdate(interfaceOperation, operationTypes); + } + else + if (!operationTypes.values().contains(interfaceOperation.getName())){ + isOperationTypeUnique = true; + } + return Either.left(isOperationTypeUnique); + } + private Either validateInputParameters(Operation interfaceOperation, + ResponseFormatManager responseFormatManager) { + Either> validateInputParametersUniqueResponse = validateInputParametersUnique(interfaceOperation); + if(validateInputParametersUniqueResponse.isRight()) { + LOGGER.debug("Interface operation input parameter names {} are invalid, Input parameter names should be unique", + validateInputParametersUniqueResponse.right().value().toString()); + ResponseFormat inputResponse = responseFormatManager.getResponseFormat(ActionStatus + .INTERFACE_OPERATION_INPUT_NAME_INVALID, validateInputParametersUniqueResponse.right().value().toString()); + return Either.right(inputResponse); + } + return null; + } + + private Either> validateInputParametersUnique(Operation operationDataDefinition) { + + Set inputParamNamesSet = new HashSet<>(); + Set duplicateParamNamesToReturn = new HashSet<>(); + operationDataDefinition.getInputs().getListToscaDataDefinition() + .forEach(inputParam -> { + if(!inputParamNamesSet.add(inputParam.getLabel())) { + duplicateParamNamesToReturn.add(inputParam.getLabel()); + } + }); + if(!duplicateParamNamesToReturn.isEmpty()) { + return Either.right(duplicateParamNamesToReturn); + } + return Either.left(Boolean.TRUE); + } + + + private boolean validateOperationTypeUniqueForUpdate(Operation interfaceOperation, + Map operationTypes) { + boolean isOperationTypeUnique = false; + for(Map.Entry entry : operationTypes.entrySet()){ + if (entry.getKey().equals(interfaceOperation.getUniqueId()) && entry.getValue(). + equals(interfaceOperation.getName())) { + isOperationTypeUnique = true; + } + + if(entry.getKey().equals(interfaceOperation.getUniqueId()) && !operationTypes.values() + .contains(interfaceOperation.getName())){ + isOperationTypeUnique = true; + } + } + return isOperationTypeUnique; + } + + protected ResponseFormatManager getResponseFormatManager() { + return ResponseFormatManager.getInstance(); + } + +} -- cgit 1.2.3-korg