diff options
10 files changed, 865 insertions, 342 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java index 0233711a89..6615e9ef37 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java @@ -16,10 +16,15 @@ package org.openecomp.sdc.be.components.utils; +import java.util.List; import java.util.Map; import java.util.Optional; + +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; +import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.Operation; @@ -61,4 +66,16 @@ public class InterfaceOperationUtils { .filter(entry -> entry.getValue().getUniqueId().equals(operationId)).findAny(); } + public static boolean isOperationInputMappedToComponentProperty(OperationInputDefinition input, + List<InputDefinition> inputs) { + if (CollectionUtils.isEmpty(inputs)) { + return false; + } + return inputs.stream().anyMatch(inp -> inp.getUniqueId().equals(input.getInputId())) + || (input.getInputId().contains(".") + && inputs.stream().anyMatch(inp -> inp.getUniqueId().equals( + input.getInputId().substring(0, input.getInputId().lastIndexOf('.'))))) ; + } + + } 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 index c80f57486d..d17762fc90 100644 --- 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 @@ -16,7 +16,11 @@ package org.openecomp.sdc.be.components.validation; +import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToComponentProperty; + +import com.google.common.collect.Sets; import fj.data.Either; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -26,13 +30,17 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.regex.Pattern; +import java.util.stream.Collectors; import java.util.stream.Stream; 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.datatypes.elements.ListDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; -import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition; import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.Operation; import org.openecomp.sdc.exception.ResponseFormat; @@ -47,9 +55,10 @@ public class InterfaceOperationValidation { private static final Logger LOGGER = LoggerFactory.getLogger(InterfaceOperationValidation.class); - public Either<Boolean, ResponseFormat> validateInterfaceOperations(InterfaceDefinition inputInterfaceDefinition, - org.openecomp.sdc.be.model.Component component, InterfaceDefinition storedInterfaceDefinition, - Map<String, InterfaceDefinition> globalInterfaceTypes, boolean isUpdate) { + public Either<Boolean, ResponseFormat> validateInterfaceOperations( + InterfaceDefinition inputInterfaceDefinition, org.openecomp.sdc.be.model.Component component, + InterfaceDefinition storedInterfaceDefinition, Map<String, InterfaceDefinition> globalInterfaceTypes, + boolean isUpdate) { Either<Boolean, ResponseFormat> validateAllowedOperationCountOnLocalInterfaceType = validateAllowedOperationCountOnLocalInterfaceType(inputInterfaceDefinition, storedInterfaceDefinition, @@ -71,8 +80,8 @@ public class InterfaceOperationValidation { } for (Operation interfaceOperation : inputInterfaceDefinition.getOperationsMap().values()) { - Either<Boolean, ResponseFormat> interfaceOperationValidatorResponse = - validateInterfaceOperation(interfaceOperation, storedInterfaceDefinition, component, isUpdate); + Either<Boolean, ResponseFormat> interfaceOperationValidatorResponse = validateInterfaceOperation( + interfaceOperation, storedInterfaceDefinition, inputInterfaceDefinition, component, isUpdate); if (interfaceOperationValidatorResponse.isRight()) { return interfaceOperationValidatorResponse; } @@ -87,15 +96,13 @@ public class InterfaceOperationValidation { boolean isInterfaceTypeExistInGlobalType = globalInterfaceTypes.values().stream().map(InterfaceDefinition::getType) - .anyMatch(type -> type.equalsIgnoreCase(inputInterfaceDefinition.getType())); - if (!isInterfaceTypeExistInGlobalType - && (inputInterfaceDefinition.getOperations().size() > 1 - || (!isUpdate && storedInterfaceDefinition != null - && storedInterfaceDefinition.getType() - .equalsIgnoreCase(inputInterfaceDefinition.getType())))) { + .anyMatch(type -> type.equalsIgnoreCase(inputInterfaceDefinition.getType())); + if (!isInterfaceTypeExistInGlobalType && (inputInterfaceDefinition.getOperations().size() > 1 + || (!isUpdate && storedInterfaceDefinition != null + && storedInterfaceDefinition.getType().equalsIgnoreCase(inputInterfaceDefinition.getType())))) { return Either.right(getResponseFormatManager() - .getResponseFormat(ActionStatus.INTERFACE_OPERATION_INVALID_FOR_LOCAL_TYPE, - inputInterfaceDefinition.getType())); + .getResponseFormat(ActionStatus.INTERFACE_OPERATION_INVALID_FOR_LOCAL_TYPE, + inputInterfaceDefinition.getType())); } return Either.left(Boolean.TRUE); @@ -105,22 +112,17 @@ public class InterfaceOperationValidation { InterfaceDefinition interfaceDefinition, Map<String, InterfaceDefinition> globalInterfaceTypes) { if (globalInterfaceTypes != null) { - boolean isOperationValidOnGlobalInterfaceType = - Stream.of(interfaceDefinition) - .filter(interfaceDef -> globalInterfaceTypes.values().stream().anyMatch( - interfaceDef1 -> interfaceDef1.getType().equalsIgnoreCase(interfaceDef.getType()))) - .flatMap(interfaceDef -> interfaceDef.getOperationsMap().values().stream() - .map(Operation::getName)) - .allMatch(operationName -> globalInterfaceTypes.values().stream() - .flatMap(interfaceDef -> interfaceDef.getOperationsMap() - .keySet().stream()) - .anyMatch(opName -> - opName.equalsIgnoreCase( - operationName))); + boolean isOperationValidOnGlobalInterfaceType = Stream.of(interfaceDefinition) + .filter(interfaceDef -> globalInterfaceTypes.values().stream().anyMatch(interfaceDef1 -> + interfaceDef1.getType().equalsIgnoreCase(interfaceDef.getType()))) + .flatMap(interfaceDef -> interfaceDef.getOperationsMap().values().stream().map(Operation::getName)) + .allMatch(operationName -> globalInterfaceTypes.values().stream() + .flatMap(interfaceDef -> interfaceDef.getOperationsMap().keySet().stream()) + .anyMatch(opName -> opName.equalsIgnoreCase(operationName))); if (!isOperationValidOnGlobalInterfaceType) { return Either.right(getResponseFormatManager() - .getResponseFormat(ActionStatus.INTERFACE_OPERATION_INVALID_FOR_GLOBAL_TYPE, - interfaceDefinition.getType())); + .getResponseFormat(ActionStatus.INTERFACE_OPERATION_INVALID_FOR_GLOBAL_TYPE, + interfaceDefinition.getType())); } } return Either.left(Boolean.TRUE); @@ -140,16 +142,19 @@ public class InterfaceOperationValidation { } private Either<Boolean, ResponseFormat> validateInterfaceOperation(Operation interfaceOperation, - InterfaceDefinition interfaceDefinition, org.openecomp.sdc.be.model.Component component, boolean isUpdate) { + InterfaceDefinition storedInterfaceDefinition, InterfaceDefinition inputInterfaceDefinition, + org.openecomp.sdc.be.model.Component component, boolean isUpdate) { ResponseFormatManager responseFormatManager = getResponseFormatManager(); Either<Boolean, ResponseFormat> interfaceOperationTypeResponse = - isInterfaceOperationTypeValid(interfaceOperation, responseFormatManager, interfaceDefinition, isUpdate); + isInterfaceOperationTypeValid(interfaceOperation, responseFormatManager, storedInterfaceDefinition, + isUpdate); if (interfaceOperationTypeResponse.isRight()) { return Either.right(interfaceOperationTypeResponse.right().value()); } - if (null != interfaceOperation.getInputs()) { + if (null != interfaceOperation.getInputs() + && CollectionUtils.isNotEmpty(interfaceOperation.getInputs().getListToscaDataDefinition())) { Either<Boolean, ResponseFormat> inputParametersResponse = validateInputParameters(interfaceOperation, responseFormatManager); if (inputParametersResponse.isRight()) { @@ -157,14 +162,15 @@ public class InterfaceOperationValidation { } Either<Boolean, ResponseFormat> inputPropertyExistInComponent = - validateInputPropertyExistInComponent(interfaceOperation, component, responseFormatManager); + validateInputPropertyExistInComponent(interfaceOperation, + inputInterfaceDefinition, component, responseFormatManager); if (inputPropertyExistInComponent.isRight()) { return Either.right(inputPropertyExistInComponent.right().value()); - } } - if (null != interfaceOperation.getOutputs()) { + if (null != interfaceOperation.getOutputs() + && CollectionUtils.isNotEmpty(interfaceOperation.getOutputs().getListToscaDataDefinition())) { Either<Boolean, ResponseFormat> outputParametersResponse = validateOutputParameters(interfaceOperation, responseFormatManager); if (outputParametersResponse.isRight()) { @@ -172,15 +178,81 @@ public class InterfaceOperationValidation { } } + if (MapUtils.isNotEmpty(component.getInterfaces()) && isUpdate) { + Either<Boolean, ResponseFormat> mappedOutputDeletedResponse = + validateMappedOutputNotDeleted(interfaceOperation, component, inputInterfaceDefinition, + responseFormatManager); + if (mappedOutputDeletedResponse.isRight()) { + return Either.right(mappedOutputDeletedResponse.right().value()); + } + } + return Either.left(Boolean.TRUE); } + + private Either<Boolean, ResponseFormat> validateMappedOutputNotDeleted(Operation interfaceOperation, + org.openecomp.sdc.be.model.Component component, InterfaceDefinition interfaceDefinition, + ResponseFormatManager responseFormatManager) { + + List<OperationOutputDefinition> existingOperationOutputs = + getInterfaceOperationOutputs(interfaceOperation.getUniqueId(), component.getInterfaces()); + if (existingOperationOutputs.isEmpty()) { + return Either.left(Boolean.TRUE); + } + Set<String> existingOperationOutputNames = existingOperationOutputs.stream() + .map(OperationOutputDefinition::getName) + .collect(Collectors.toSet()); + + ListDataDefinition<OperationOutputDefinition> currentOutputs = interfaceOperation.getOutputs(); + Set<String> currentOperationOutputNames = new HashSet<>(); + if (currentOutputs != null && !currentOutputs.isEmpty()) { + currentOperationOutputNames = currentOutputs.getListToscaDataDefinition().stream() + .map(OperationOutputDefinition::getName) + .collect(Collectors.toSet()); + } + String mappedOutputPrefix = interfaceDefinition.getType() + "." + interfaceOperation.getName(); + Set<String> deletedOutputs = Sets.difference(existingOperationOutputNames, currentOperationOutputNames); + Set<String> deletedMappedOutputs = deletedOutputs.stream() + .filter(deletedOutputName -> isMappedOutputDeleted(mappedOutputPrefix, deletedOutputName, + component.getInterfaces())) + .map(this::getOperationOutputName) + .collect(Collectors.toSet()); + + if (CollectionUtils.isNotEmpty(deletedMappedOutputs)) { + return getMappedOutputErrorResponse(responseFormatManager, deletedMappedOutputs); + } + return Either.left(Boolean.TRUE); + } + + private boolean isMappedOutputDeleted(String mappedOutputPrefix, String outputName, + Map<String, InterfaceDefinition> componentInterfaces) { + List<OperationInputDefinition> interfaceOperationInputs = + getOtherOperationInputsOfComponent(mappedOutputPrefix, componentInterfaces); + return interfaceOperationInputs.stream() + .anyMatch(operationInputDefinition -> operationInputDefinition.getInputId() + .equals(mappedOutputPrefix + "." + outputName)); + } + + private Either<Boolean, ResponseFormat> getMappedOutputErrorResponse(ResponseFormatManager responseFormatManager, + Set<String> deletedMappedOutputs) { + String deletedOutputNameList = String.join(",", deletedMappedOutputs); + LOGGER.error("Cannot update name or delete interface operation output(s) '{}' mapped to an operation input", + deletedOutputNameList); + ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus + .INTERFACE_OPERATION_MAPPED_OUTPUT_DELETED, deletedOutputNameList); + return Either.right(errorResponse); + } + + protected ResponseFormatManager getResponseFormatManager() { return ResponseFormatManager.getInstance(); } private Either<Boolean, ResponseFormat> isInterfaceOperationTypeValid(Operation interfaceOperation, - ResponseFormatManager responseFormatManager, InterfaceDefinition interfaceDefinition, boolean isUpdate) { + ResponseFormatManager responseFormatManager, + InterfaceDefinition interfaceDefinition, + boolean isUpdate) { Either<Boolean, ResponseFormat> operationTypeEmptyEither = isOperationTypeEmpty(responseFormatManager, interfaceOperation.getName()); @@ -194,8 +266,8 @@ public class InterfaceOperationValidation { return Either.right(operationTypeRegexValidationResponse.right().value()); } - Either<Boolean, ResponseFormat> operationTypeUniqueResponse = - validateOperationTypeUnique(interfaceOperation, interfaceDefinition, isUpdate); + Either<Boolean, ResponseFormat> operationTypeUniqueResponse = validateOperationTypeUnique(interfaceOperation, + interfaceDefinition, isUpdate); if (operationTypeUniqueResponse.isRight()) { return Either.right(operationTypeUniqueResponse.right().value()); } @@ -209,7 +281,7 @@ public class InterfaceOperationValidation { } private Either<Boolean, ResponseFormat> validateInputParameters(Operation interfaceOperation, - ResponseFormatManager responseFormatManager) { + ResponseFormatManager responseFormatManager) { if (isInputParameterNameEmpty(interfaceOperation)) { LOGGER.error("Interface operation input parameter name can't be empty"); ResponseFormat inputResponse = @@ -222,38 +294,16 @@ public class InterfaceOperationValidation { if (validateInputParametersUniqueResponse.isRight()) { LOGGER.error("Interface operation input parameter names {} already in use", validateInputParametersUniqueResponse.right().value()); - ResponseFormat inputResponse = responseFormatManager.getResponseFormat( - ActionStatus.INTERFACE_OPERATION_INPUT_NAME_ALREADY_IN_USE, - validateInputParametersUniqueResponse.right().value().toString()); + ResponseFormat inputResponse = + responseFormatManager.getResponseFormat(ActionStatus.INTERFACE_OPERATION_INPUT_NAME_ALREADY_IN_USE, + validateInputParametersUniqueResponse.right().value().toString()); return Either.right(inputResponse); } return Either.left(Boolean.TRUE); } - private Either<Boolean, ResponseFormat> validateInputPropertyExistInComponent(Operation operation, - org.openecomp.sdc.be.model.Component component, ResponseFormatManager responseFormatManager) { - - List<OperationInputDefinition> inputListToscaDataDefinition = - operation.getInputs().getListToscaDataDefinition(); - for (OperationInputDefinition inputDefinition : inputListToscaDataDefinition) { - if (!validateInputExistsInComponent(inputDefinition, component.getInputs())) { - String missingPropertyName = inputDefinition.getInputId().contains(".") - ? inputDefinition.getInputId().substring( - inputDefinition.getInputId().indexOf('.') + 1) - : inputDefinition.getInputId(); - LOGGER.error("Interface operation input property {} not found in component input properties", - missingPropertyName); - ResponseFormat inputResponse = responseFormatManager.getResponseFormat( - ActionStatus.INTERFACE_OPERATION_INPUT_PROPERTY_NOT_FOUND_IN_COMPONENT, missingPropertyName, - component.getComponentType().getValue()); - return Either.right(inputResponse); - } - } - return Either.left(Boolean.TRUE); - } - private Either<Boolean, ResponseFormat> validateOutputParameters(Operation interfaceOperation, - ResponseFormatManager responseFormatManager) { + ResponseFormatManager responseFormatManager) { if (isOutputParameterNameEmpty(interfaceOperation)) { LOGGER.error("Interface operation output parameter name can't be empty"); ResponseFormat inputResponse = @@ -266,9 +316,9 @@ public class InterfaceOperationValidation { if (validateOutputParametersUniqueResponse.isRight()) { LOGGER.error("Interface operation output parameter names {} already in use", validateOutputParametersUniqueResponse.right().value()); - ResponseFormat inputResponse = responseFormatManager.getResponseFormat( - ActionStatus.INTERFACE_OPERATION_OUTPUT_NAME_ALREADY_IN_USE, - validateOutputParametersUniqueResponse.right().value().toString()); + ResponseFormat inputResponse = + responseFormatManager.getResponseFormat(ActionStatus.INTERFACE_OPERATION_OUTPUT_NAME_ALREADY_IN_USE, + validateOutputParametersUniqueResponse.right().value().toString()); return Either.right(inputResponse); } return Either.left(Boolean.TRUE); @@ -330,31 +380,22 @@ public class InterfaceOperationValidation { inputParam -> inputParam.getName() == null || inputParam.getName().trim().equals(StringUtils.EMPTY)); } + private Either<Boolean, Set<String>> isInputParametersUnique(Operation operationDataDefinition) { Set<String> inputParamNamesSet = new HashSet<>(); Set<String> duplicateParamNamesToReturn = new HashSet<>(); - operationDataDefinition.getInputs().getListToscaDataDefinition().forEach(inputParam -> { - if (!inputParamNamesSet.add(inputParam.getName().trim())) { - duplicateParamNamesToReturn.add(inputParam.getName().trim()); - } - }); + operationDataDefinition.getInputs().getListToscaDataDefinition() + .forEach(inputParam -> { + if (!inputParamNamesSet.add(inputParam.getName().trim())) { + duplicateParamNamesToReturn.add(inputParam.getName().trim()); + } + }); if (!duplicateParamNamesToReturn.isEmpty()) { return Either.right(duplicateParamNamesToReturn); } return Either.left(Boolean.TRUE); } - private boolean validateInputExistsInComponent(OperationInputDefinition input, List<InputDefinition> inputs) { - return inputs.stream().anyMatch(inp -> inp.getUniqueId().equals(input.getInputId())) - || (input.getInputId().contains(".") - && inputs.stream() - .anyMatch(inp -> inp.getUniqueId() - .equals(input.getInputId() - .substring(0, - input.getInputId() - .lastIndexOf('.'))))); - } - private Boolean isOutputParameterNameEmpty(Operation operationDataDefinition) { return operationDataDefinition.getOutputs().getListToscaDataDefinition().stream().anyMatch( outputParam -> outputParam.getName() == null || outputParam.getName().trim().equals(StringUtils.EMPTY)); @@ -363,17 +404,170 @@ public class InterfaceOperationValidation { private Either<Boolean, Set<String>> isOutputParametersUnique(Operation operationDataDefinition) { Set<String> outputParamNamesSet = new HashSet<>(); Set<String> duplicateParamNamesToReturn = new HashSet<>(); - operationDataDefinition.getOutputs().getListToscaDataDefinition().forEach(outputParam -> { - if (!outputParamNamesSet.add(outputParam.getName().trim())) { - duplicateParamNamesToReturn.add(outputParam.getName().trim()); - } - }); + operationDataDefinition.getOutputs().getListToscaDataDefinition() + .forEach(outputParam -> { + if (!outputParamNamesSet.add(outputParam.getName().trim())) { + duplicateParamNamesToReturn.add(outputParam.getName().trim()); + } + }); if (!duplicateParamNamesToReturn.isEmpty()) { return Either.right(duplicateParamNamesToReturn); } return Either.left(Boolean.TRUE); } + private Either<Boolean, ResponseFormat> validateInputPropertyExistInComponent(Operation operation, + InterfaceDefinition inputInterfaceDefinition, org.openecomp.sdc.be.model.Component component, + ResponseFormatManager responseFormatManager) { + + boolean isOperationInputToInputPropertyMappingValid = false; + boolean isOperationInputToOtherOperationOutputMappingValid = false; + String mappingName = ""; + List<OperationInputDefinition> inputListToscaDataDefinition = + operation.getInputs().getListToscaDataDefinition(); + for (OperationInputDefinition inputDefinition : inputListToscaDataDefinition) { + if (isOperationInputMappedToComponentProperty(inputDefinition, component.getInputs())) { + isOperationInputToInputPropertyMappingValid = true; + } else { + mappingName = inputDefinition.getInputId().contains(".") + ? inputDefinition.getInputId().substring(inputDefinition.getInputId().lastIndexOf(".") + 1) + : inputDefinition.getInputId(); + break; + } + } + if (isOperationInputToInputPropertyMappingValid) { + return Either.left(Boolean.TRUE); + } + + //Mapped property not found in the component properties.. Check in other operation output parameters of + // component (other operation => not having the same full name) + ListDataDefinition<OperationOutputDefinition> outputListDataDefinition = + getOtherOperationOutputsOfComponent(inputInterfaceDefinition.getType(), operation.getName(), component); + + List<OperationOutputDefinition> componentOutputsFromOtherOperations = + outputListDataDefinition.getListToscaDataDefinition(); + if (validateOutputExistsInComponent(mappingName, componentOutputsFromOtherOperations)) { + isOperationInputToOtherOperationOutputMappingValid = true; + } else { + //Get the output parameter display name from the full name + mappingName = getOperationOutputName(mappingName); + } + + if (!isOperationInputToOtherOperationOutputMappingValid) { + LOGGER.error("Interface operation input parameter property {} not found in component input properties or" + + " outputs of other operations.", mappingName); + ResponseFormat inputResponse = responseFormatManager + .getResponseFormat(ActionStatus.INTERFACE_OPERATION_INPUT_PROPERTY_NOT_FOUND_IN_COMPONENT, + mappingName, component.getComponentType().getValue()); + return Either.right(inputResponse); + } + return Either.left(Boolean.TRUE); + } + + private boolean validateOutputExistsInComponent(String mappedOutputName, + List<OperationOutputDefinition> outputs) { + return outputs.stream() + .anyMatch(output -> output.getName().equals(mappedOutputName)); + } + + /** + * Get the list of outputs of other operations of all the interfaces in the component. + * @param currentInterfaceName Fully qualified interface name e.g. org.test.interfaces.node.lifecycle.Abc + * @param currentOperationName Name entered on the operation screen e.g. create + * @param component VF or service + */ + + private ListDataDefinition<OperationOutputDefinition> getOtherOperationOutputsOfComponent( + String currentInterfaceName, String currentOperationName, org.openecomp.sdc.be.model.Component component) { + ListDataDefinition<OperationOutputDefinition> componentOutputs = new ListDataDefinition<>(); + Map<String, InterfaceDefinition> componentInterfaces = component.getInterfaces(); + if (MapUtils.isEmpty(componentInterfaces)) { + return componentOutputs; + } + for (Map.Entry<String, InterfaceDefinition> interfaceDefinitionEntry : componentInterfaces.entrySet()) { + String interfaceName = interfaceDefinitionEntry.getKey(); + final Map<String, OperationDataDefinition> operations = interfaceDefinitionEntry.getValue().getOperations(); + if (MapUtils.isEmpty(operations)) { + continue; + } + String actualOperationIdentifier = currentInterfaceName + "." + currentOperationName; + for (Map.Entry<String, OperationDataDefinition> operationEntry : operations.entrySet()) { + ListDataDefinition<OperationOutputDefinition> outputs = operationEntry.getValue().getOutputs(); + String expectedOperationIdentifier = interfaceName + "." + operationEntry.getKey(); + if (!actualOperationIdentifier.equals(expectedOperationIdentifier) && !outputs.isEmpty()) { + outputs.getListToscaDataDefinition().forEach(componentOutputs::add); + } + } + } + return componentOutputs; + } + + /** + * Get the input definitions of other operations of the component from current as well as other interfaces. + * @param currentOperationIdentifier Identifier for the request operation (interface_name.operation_name) + * @param componentInterfaces Interfaces of the component + */ + private List<OperationInputDefinition> getOtherOperationInputsOfComponent(String currentOperationIdentifier, + Map<String, InterfaceDefinition> + componentInterfaces) { + List<OperationInputDefinition> otherOperationInputs = new ArrayList<>(); + if (MapUtils.isEmpty(componentInterfaces)) { + return otherOperationInputs; + } + for (Map.Entry<String, InterfaceDefinition> interfaceDefinitionEntry : componentInterfaces.entrySet()) { + final Map<String, OperationDataDefinition> operations = interfaceDefinitionEntry.getValue().getOperations(); + if (MapUtils.isEmpty(operations)) { + continue; + } + for (Map.Entry<String, OperationDataDefinition> operationEntry : operations.entrySet()) { + ListDataDefinition<OperationInputDefinition> inputs = operationEntry.getValue().getInputs(); + String expectedOperationIdentifier = + interfaceDefinitionEntry.getValue().getType() + "." + operationEntry.getValue().getName(); + if (!currentOperationIdentifier.equals(expectedOperationIdentifier) && !inputs.isEmpty()) { + otherOperationInputs.addAll(inputs.getListToscaDataDefinition()); + } + } + } + return otherOperationInputs; + } + + private String getOperationOutputName(String outputName) { + return outputName.contains(".") + ? outputName.substring(outputName.lastIndexOf(".") + 1) + : outputName; + } + + /** + * Get the output of an operation in an interface. + * @param inputOperationId Unique identifier for the request operation + * @param componentInterfaces Interfaces of the component + */ + private List<OperationOutputDefinition> getInterfaceOperationOutputs(String inputOperationId, + Map<String, InterfaceDefinition> + componentInterfaces) { + List<OperationOutputDefinition> operationOutputDefinitions = new ArrayList<>(); + if (MapUtils.isEmpty(componentInterfaces)) { + return operationOutputDefinitions; + } + for (Map.Entry<String, InterfaceDefinition> interfaceDefinitionEntry : componentInterfaces.entrySet()) { + final Map<String, OperationDataDefinition> operations = interfaceDefinitionEntry.getValue().getOperations(); + if (MapUtils.isEmpty(operations)) { + continue; + } + for (Map.Entry<String, OperationDataDefinition> operationEntry : operations.entrySet()) { + String expectedOperationId = operationEntry.getValue().getUniqueId(); + if (expectedOperationId.equals(inputOperationId)) { + ListDataDefinition<OperationOutputDefinition> operationOutputs = + operationEntry.getValue().getOutputs(); + return (Objects.isNull(operationOutputs) || operationOutputs.isEmpty()) + ? operationOutputDefinitions + : operationOutputs.getListToscaDataDefinition(); + } + } + } + return operationOutputDefinitions; + } + private boolean isValidOperationType(String operationType) { return Pattern.matches(TYPE_VALIDATION_REGEX, operationType); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java index fbef11d2e8..efed3e9f15 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java @@ -16,6 +16,8 @@ package org.openecomp.sdc.be.tosca.utils; +import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToComponentProperty; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; @@ -47,10 +49,12 @@ public class InterfacesOperationsToscaUtil { private static final String DEFAULT = "default"; private static final String DEFAULT_HAS_UNDERSCORE = "_default"; private static final String DOT = "."; - private static final String SELF = "SELF"; - private static final String GET_PROPERTY = "get_property"; private static final String DEFAULTP = "defaultp"; + static final String SELF = "SELF"; + static final String GET_PROPERTY = "get_property"; + static final String GET_OPERATION_OUTPUT = "get_operation_output"; + private InterfacesOperationsToscaUtil() { } @@ -127,7 +131,7 @@ public class InterfacesOperationsToscaUtil { toscaOperation.setImplementation(operationArtifactPath); } toscaOperation.setDescription(operationEntry.getValue().getDescription()); - fillToscaOperationInputs(operationEntry.getValue(), toscaOperation); + fillToscaOperationInputs(operationEntry.getValue(), toscaOperation, interfaceType, component); toscaOperations.put(operationEntry.getValue().getName(), toscaOperation); } @@ -176,7 +180,9 @@ public class InterfacesOperationsToscaUtil { } private static void fillToscaOperationInputs(OperationDataDefinition operation, - ToscaLifecycleOperationDefinition toscaOperation) { + ToscaLifecycleOperationDefinition toscaOperation, + String interfaceType, + Component component) { if (Objects.isNull(operation.getInputs()) || operation.getInputs().isEmpty()) { toscaOperation.setInputs(null); return; @@ -186,12 +192,16 @@ public class InterfacesOperationsToscaUtil { for (OperationInputDefinition input : operation.getInputs().getListToscaDataDefinition()) { ToscaProperty toscaInput = new ToscaProperty(); toscaInput.setDescription(input.getDescription()); - String mappedPropertyName = null; + String mappedPropertyName; if (Objects.nonNull(input.getInputId())) { - mappedPropertyName = input.getInputId().substring(input.getInputId().indexOf(DOT) + 1); + if (isOperationInputMappedToComponentProperty(input, component.getInputs())) { + mappedPropertyName = input.getInputId().substring(input.getInputId().indexOf(DOT) + 1); + toscaInput.setDefaultp(createMappedInputPropertyDefaultValue(mappedPropertyName)); + } else { + mappedPropertyName = input.getInputId(); + toscaInput.setDefaultp(createMappedOutputDefaultValue(mappedPropertyName, interfaceType)); + } } - toscaInput.setDefaultp(createDefaultValue(mappedPropertyName)); - toscaInput.setType(input.getType()); toscaInput.setRequired(input.isRequired()); toscaInputs.put(input.getName(), toscaInput); @@ -200,7 +210,7 @@ public class InterfacesOperationsToscaUtil { toscaOperation.setInputs(toscaInputs); } - private static Map<String, List<String>> createDefaultValue(String propertyName) { + private static Map<String, List<String>> createMappedInputPropertyDefaultValue(String propertyName) { Map<String, List<String>> getPropertyMap = new HashMap<>(); List<String> values = new ArrayList<>(); values.add(SELF); @@ -213,6 +223,27 @@ public class InterfacesOperationsToscaUtil { return getPropertyMap; } + /** + * Create the value for operation input mapped to an operation output + * @param propertyName the mapped other operation output full name + * @param interfaceType full interface name + * @return input map for tosca + */ + private static Map<String, List<String>> createMappedOutputDefaultValue(String propertyName, String interfaceType) { + Map<String, List<String>> getOperationOutputMap = new HashMap<>(); + //For operation input mapped to other operation output parameter, the mapped property value + // should be of the format <interface name>.<operation name>.<output parameter name> + List<String> defaultMappedOperationOutputValue = new ArrayList<>(); + defaultMappedOperationOutputValue.add(SELF); + String fullOutputPropertyName = + propertyName.substring(propertyName.indexOf(interfaceType) + interfaceType.length() + 1); + defaultMappedOperationOutputValue.add(interfaceType); + //Output name should not contain dot + defaultMappedOperationOutputValue.addAll(Arrays.asList(fullOutputPropertyName.split("\\."))); + getOperationOutputMap.put(GET_OPERATION_OUTPUT, defaultMappedOperationOutputValue); + return getOperationOutputMap; + } + private static Map<String, Object> getObjectAsMap(Object obj) { ObjectMapper objectMapper = new ObjectMapper(); if (obj instanceof ToscaInterfaceDefinition) { diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml index ff86aff820..315027b43e 100644 --- a/catalog-be/src/main/resources/config/error-configuration.yaml +++ b/catalog-be/src/main/resources/config/error-configuration.yaml @@ -2137,7 +2137,7 @@ errors: # %1 - Interface Operation input property name, component type INTERFACE_OPERATION_INPUT_PROPERTY_NOT_FOUND_IN_COMPONENT: { code: 404, - message: "Error: Interface operation input parameter property '%1' not found in '%2' input properties.", + message: "Error: Interface operation input parameter property '%1' not found in '%2' input properties or outputs of other operations.", messageId: "SVC4708" } #---------SVC4709----------------------------- @@ -2172,4 +2172,11 @@ errors: code: 400, message: "Error: Invalid input, only pre-defined operation names are allowed in global interface type '%1'", messageId: "SVC4713" + } +#---------SVC4714----------------------------- +# %1 - Interface Operation output name + INTERFACE_OPERATION_MAPPED_OUTPUT_DELETED: { + code: 400, + message: "Error: Cannot update name or delete interface operation output(s) '%1' mapped to an operation input", + messageId: "SVC4714" }
\ No newline at end of file diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java index 8509f3e749..df4ef646ee 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java @@ -24,12 +24,13 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; -import fj.data.Either; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; + +import fj.data.Either; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -70,6 +71,8 @@ public class InterfaceOperationBusinessLogicTest { private static final String RESOURCE_NAME = "Resource1"; private static final String operationId1 = "operationId1"; private static final String interfaceId1 = "interfaceId1"; + private static final String operationName = "createOperation"; + @InjectMocks private InterfaceOperationBusinessLogic interfaceOperationBusinessLogic; @Mock @@ -97,7 +100,8 @@ public class InterfaceOperationBusinessLogicTest { public void setup() { resource = new ResourceBuilder().setComponentType(ComponentTypeEnum.RESOURCE).setUniqueId(resourceId) .setName(RESOURCE_NAME).build(); - resource.setInterfaces(InterfaceOperationTestUtils.createMockInterfaceDefinitionMap(interfaceId, operationId)); + resource.setInterfaces(InterfaceOperationTestUtils.createMockInterfaceDefinitionMap(interfaceId, operationId, + operationName)); resource.setInputs(createInputsForResource()); user = new User(); @@ -126,11 +130,11 @@ public class InterfaceOperationBusinessLogicTest { when(interfaceLifecycleOperation.getAllInterfaceLifecycleTypes()) .thenReturn(Either.left(Collections.emptyMap())); when(interfaceOperation.updateInterfaces(any(), any())).thenReturn(Either.left( - Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId)))); + Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId, operationName)))); Either<List<InterfaceDefinition>, ResponseFormat> interfaceOperationEither = interfaceOperationBusinessLogic.createInterfaceOperation(resourceId, - Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, - operationId)), + Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, + operationId, operationName)), user, true); Assert.assertTrue(interfaceOperationEither.isLeft()); } @@ -141,13 +145,13 @@ public class InterfaceOperationBusinessLogicTest { when(interfaceLifecycleOperation.getAllInterfaceLifecycleTypes()) .thenReturn(Either.left(Collections.emptyMap())); when(interfaceOperation.addInterfaces(any(), any())).thenReturn(Either.left( - Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId)))); + Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId, operationName)))); when(interfaceOperation.updateInterfaces(any(), any())).thenReturn(Either.left( - Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId)))); + Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId, operationName)))); Either<List<InterfaceDefinition>, ResponseFormat> interfaceOperationEither = interfaceOperationBusinessLogic.createInterfaceOperation(resourceId, Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, - operationId)), + operationId, operationName)), user, true); Assert.assertTrue(interfaceOperationEither.isLeft()); } @@ -162,7 +166,7 @@ public class InterfaceOperationBusinessLogicTest { Either<List<InterfaceDefinition>, ResponseFormat> interfaceOperationEither = interfaceOperationBusinessLogic.createInterfaceOperation(resourceId, Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, - operationId)), + operationId, operationName)), user, true); Assert.assertTrue(interfaceOperationEither.isRight()); } @@ -174,7 +178,7 @@ public class InterfaceOperationBusinessLogicTest { when(interfaceOperation.updateInterfaces(any(), any())) .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND)); Assert.assertTrue(interfaceOperationBusinessLogic.createInterfaceOperation(resourceId, - Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId)), + Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId, operationName)), user, true).isRight()); } @@ -185,11 +189,11 @@ public class InterfaceOperationBusinessLogicTest { when(artifactCassandraDao.getCountOfArtifactById(any(String.class))).thenReturn(Either.left(new Long(1))); when(artifactCassandraDao.deleteArtifact(any(String.class))).thenReturn(CassandraOperationStatus.OK); when(interfaceOperation.updateInterfaces(any(), any())).thenReturn(Either.left( - Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId)))); + Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId, operationName)))); Either<List<InterfaceDefinition>, ResponseFormat> interfaceOperation = interfaceOperationBusinessLogic.updateInterfaceOperation(resourceId, Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, - operationId)), + operationId, operationName)), user, true); Assert.assertTrue(interfaceOperation.isLeft()); } @@ -203,7 +207,7 @@ public class InterfaceOperationBusinessLogicTest { Either<List<InterfaceDefinition>, ResponseFormat> interfaceOperation = interfaceOperationBusinessLogic.updateInterfaceOperation(resourceId, Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, - operationId)), + operationId, operationName)), user, true); Assert.assertTrue(interfaceOperation.isRight()); } @@ -215,11 +219,11 @@ public class InterfaceOperationBusinessLogicTest { when(artifactCassandraDao.getCountOfArtifactById(any(String.class))) .thenReturn(Either.right(CassandraOperationStatus.NOT_FOUND)); when(interfaceOperation.updateInterfaces(any(), any())).thenReturn(Either.left( - Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId)))); + Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId, operationName)))); Either<List<InterfaceDefinition>, ResponseFormat> interfaceOperation = interfaceOperationBusinessLogic.updateInterfaceOperation(resourceId, Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, - operationId)), + operationId, operationName)), user, true); Assert.assertTrue(interfaceOperation.isLeft()); } @@ -231,7 +235,7 @@ public class InterfaceOperationBusinessLogicTest { Either<List<InterfaceDefinition>, ResponseFormat> interfaceOperation = interfaceOperationBusinessLogic.updateInterfaceOperation(resourceId, Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, - operationId)), + operationId, operationName)), user, true); Assert.assertTrue(interfaceOperation.isRight()); } @@ -244,7 +248,7 @@ public class InterfaceOperationBusinessLogicTest { Either<List<InterfaceDefinition>, ResponseFormat> interfaceOperationEither = interfaceOperationBusinessLogic.createInterfaceOperation(resourceId, Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, - operationId)), + operationId, operationName)), user, true); Assert.assertTrue(interfaceOperationEither.isRight()); } @@ -256,7 +260,7 @@ public class InterfaceOperationBusinessLogicTest { Either<List<InterfaceDefinition>, ResponseFormat> interfaceOperationEither = interfaceOperationBusinessLogic.createInterfaceOperation(resourceId, Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, - operationId)), + operationId, operationName)), user, true); Assert.assertTrue(interfaceOperationEither.isRight()); } @@ -271,7 +275,7 @@ public class InterfaceOperationBusinessLogicTest { Either<List<InterfaceDefinition>, ResponseFormat> interfaceOperationEither = interfaceOperationBusinessLogic.createInterfaceOperation(resourceId, Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, - operationId)), + operationId, operationName)), user, true); Assert.assertTrue(interfaceOperationEither.isRight()); } @@ -291,7 +295,7 @@ public class InterfaceOperationBusinessLogicTest { @Test public void deleteInterfaceOperationTestSuccess() { resource.getInterfaces().get(interfaceId).getOperations() - .putAll(InterfaceOperationTestUtils.createMockOperationMap(operationId1)); + .putAll(InterfaceOperationTestUtils.createMockOperationMap(operationId1, operationName)); when(artifactCassandraDao.deleteArtifact(any(String.class))).thenReturn(CassandraOperationStatus.OK); when(interfaceOperation.updateInterfaces(any(), any())).thenReturn(Either.left(Collections.emptyList())); Assert.assertTrue(interfaceOperationBusinessLogic.deleteInterfaceOperation(resourceId, interfaceId, @@ -374,7 +378,7 @@ public class InterfaceOperationBusinessLogicTest { Assert.assertTrue(interfaceOperationBusinessLogic.getInterfaceOperation(resourceId, interfaceId, Collections.singletonList(operationId), user, true).isRight()); Assert.assertTrue(interfaceOperationBusinessLogic.createInterfaceOperation(resourceId, - Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId)), + Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId, operationName)), user, true).isRight()); } @@ -387,8 +391,8 @@ public class InterfaceOperationBusinessLogicTest { Assert.assertTrue(interfaceOperationBusinessLogic.getInterfaceOperation(resourceId, interfaceId, Collections.singletonList(operationId), user, true).isRight()); Assert.assertTrue(interfaceOperationBusinessLogic.createInterfaceOperation(resourceId, - Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId)), - user, true).isRight()); + Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId, + operationName)), user, true).isRight()); } @Test diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtilsTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtilsTest.java index 59f95ba8da..8ceac17d46 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtilsTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtilsTest.java @@ -15,6 +15,7 @@ public class InterfaceOperationUtilsTest { private static final String TEST_RESOURCE_NAME = "TestResource"; private static final String operationId = "operationId"; + private static final String operationName = "createOperation"; private static final String interfaceId = "interfaceId"; private static Resource resource; @@ -22,7 +23,8 @@ public class InterfaceOperationUtilsTest { public void setup() { resource = new ResourceBuilder().setComponentType(ComponentTypeEnum.RESOURCE).setName(TEST_RESOURCE_NAME).build(); - resource.setInterfaces(InterfaceOperationTestUtils.createMockInterfaceDefinitionMap(interfaceId, operationId)); + resource.setInterfaces(InterfaceOperationTestUtils.createMockInterfaceDefinitionMap(interfaceId, operationId, + operationName)); } @Test @@ -72,20 +74,20 @@ public class InterfaceOperationUtilsTest { @Test public void testGetOperationFromInterfaceDefinitionSuccess() { Assert.assertTrue(InterfaceOperationUtils.getOperationFromInterfaceDefinition( - InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId), operationId).isPresent()); + InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId, operationName), operationId).isPresent()); } @Test public void testGetOperationFromInterfaceDefinitionFailure() { Assert.assertFalse(InterfaceOperationUtils.getOperationFromInterfaceDefinition( - InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId), TEST_RESOURCE_NAME) + InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId, operationName), TEST_RESOURCE_NAME) .isPresent()); } @Test public void testGetOperationFromInterfaceDefinitionNoOperationMap() { InterfaceDefinition interfaceDefinition = - InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId); + InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId, operationName); interfaceDefinition.getOperations().clear(); Optional<Map.Entry<String, Operation>> operationEntry = InterfaceOperationUtils.getOperationFromInterfaceDefinition(interfaceDefinition, TEST_RESOURCE_NAME); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java index fc1b03ed78..e2d83aef29 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java @@ -18,12 +18,14 @@ package org.openecomp.sdc.be.components.validation; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; +import static org.openecomp.sdc.test.utils.InterfaceOperationTestUtils.createMockOperation; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; + import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -46,317 +48,476 @@ import org.openecomp.sdc.test.utils.InterfaceOperationTestUtils; public class InterfaceOperationValidationTest { private static final String resourceId = "resourceId"; - private static final String interfaceId = "interfaceId"; private static final String operationId = "operationId"; - private static final String interfaceType = "interfaceType"; - private static final String operationType = "operationType"; private static final String operationId2 = "operationId2"; - private static final String inputId = "inputId"; - private static final String outputId = "outputId"; + private static final String interfaceType1 = "org.test.lifecycle.standard.interfaceType.first"; + private static final String interfaceType2 = "org.test.lifecycle.standard.interfaceType.second"; + private static final String interfaceType3 = "org.test.lifecycle.standard.interfaceType.third"; + private static final String operationType1 = "createOperation"; + private static final String operationType2 = "updateOperation"; + private static final String inputName1 = "Input1"; + private static final String outputName1 = "Output1"; + private static final String outputName2 = "Output2"; + private final InterfaceOperationValidationUtilTest interfaceOperationValidationUtilTest = new InterfaceOperationValidationUtilTest(); private final ListDataDefinition<OperationInputDefinition> operationInputDefinitionList = new ListDataDefinition<>(); private final ListDataDefinition<OperationOutputDefinition> operationOutputDefinitionList = new ListDataDefinition<>(); + private Component component; private ResponseFormatManager responseFormatManagerMock; @Before public void setup() { + MockitoAnnotations.initMocks(this); responseFormatManagerMock = Mockito.mock(ResponseFormatManager.class); when(responseFormatManagerMock.getResponseFormat(any())).thenReturn(new ResponseFormat()); when(responseFormatManagerMock.getResponseFormat(any(), any())).thenReturn(new ResponseFormat()); when(responseFormatManagerMock.getResponseFormat(any(), any(), any())).thenReturn(new ResponseFormat()); - component = new ResourceBuilder().setComponentType(ComponentTypeEnum.RESOURCE).setUniqueId(resourceId) - .setName(resourceId).build(); - component.setInterfaces(InterfaceOperationTestUtils.createMockInterfaceDefinitionMap(interfaceId, operationId)); + component = new ResourceBuilder() + .setComponentType(ComponentTypeEnum.RESOURCE) + .setUniqueId(resourceId) + .setName(resourceId) + .build(); + component.setInterfaces(InterfaceOperationTestUtils.createMockInterfaceDefinitionMap(interfaceType1, + operationId, operationType1)); component.setInputs(createInputsForComponent()); } - private List<InputDefinition> createInputsForComponent() { - InputDefinition inputDefinition1 = new InputDefinition(); - inputDefinition1.setName(inputId); - inputDefinition1.setInputId(inputId); - inputDefinition1.setUniqueId(inputId); - inputDefinition1.setValue(inputId); - inputDefinition1.setDefaultValue(inputId); - - InputDefinition inputDefinition2 = new InputDefinition(); - inputDefinition2.setName(outputId); - inputDefinition2.setInputId(outputId); - inputDefinition2.setUniqueId(outputId); - inputDefinition2.setValue(outputId); - inputDefinition2.setDefaultValue(outputId); - - return Arrays.asList(inputDefinition1, inputDefinition2); - } - @Test public void shouldPassOperationValidationForHappyScenario() { - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputId)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputName1)); InterfaceDefinition interfaceDefinition = createInterfaceOperationData(operationId2, operationId2, new ArtifactDefinition(), operationInputDefinitionList, operationOutputDefinitionList, "upgrade"); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(interfaceDefinition, component, - component.getInterfaces().get(interfaceId), Collections.emptyMap(), false) + .validateInterfaceOperations(interfaceDefinition, component, + component.getInterfaces().get(interfaceType1), Collections.emptyMap(), false) .isLeft()); } - private InterfaceDefinition createInterfaceOperationData(String uniqueId, String description, - ArtifactDefinition artifactDefinition, ListDataDefinition<OperationInputDefinition> inputs, - ListDataDefinition<OperationOutputDefinition> outputs, String name) { - Operation operation = new Operation(); - operation.setUniqueId(uniqueId); - operation.setDescription(description); - operation.setImplementation(artifactDefinition); - operation.setInputs(inputs); - operation.setOutputs(outputs); - operation.setName(name); - Map<String, Operation> operationMap = new HashMap<>(); - operationMap.put(operation.getUniqueId(), operation); - InterfaceDefinition interfaceDefinition = new InterfaceDefinition(); - interfaceDefinition.setOperationsMap(operationMap); - return interfaceDefinition; - } - @Test public void shouldFailWhenOperationNameIsEmpty() { - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputId)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputName1)); InterfaceDefinition interfaceDefinition = createInterfaceOperationData(operationId2, operationId2, new ArtifactDefinition(), operationInputDefinitionList, operationOutputDefinitionList, ""); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(interfaceDefinition, component, - component.getInterfaces().get(interfaceId), Collections.emptyMap(), false) - .isRight()); + .validateInterfaceOperations(interfaceDefinition, component, + component.getInterfaces().get(interfaceType1), Collections.emptyMap(), false).isRight()); } @Test public void shouldFailWhenOperationNamesAreNotUniqueForCreate() { - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputId)); - InterfaceDefinition interfaceDefinition = - createInterfaceOperationData(operationId, operationId2, new ArtifactDefinition(), - operationInputDefinitionList, operationOutputDefinitionList, operationId); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputName1)); + InterfaceDefinition interfaceDefinition = createInterfaceOperationData(operationId, operationId2, + new ArtifactDefinition(), operationInputDefinitionList, operationOutputDefinitionList, operationType1); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(interfaceDefinition, component, - component.getInterfaces().get(interfaceId), Collections.emptyMap(), false) - .isRight()); + .validateInterfaceOperations(interfaceDefinition, component, + component.getInterfaces().get(interfaceType1), Collections.emptyMap(), false).isRight()); } @Test public void shouldNotFailWhenOperationNamesAreNotUniqueForUpdate() { - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputId)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputName1)); InterfaceDefinition interfaceDefinition = createInterfaceOperationData(operationId, operationId2, new ArtifactDefinition(), operationInputDefinitionList, operationOutputDefinitionList, operationId); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(interfaceDefinition, component, - component.getInterfaces().get(interfaceId), Collections.emptyMap(), true) - .isLeft()); + .validateInterfaceOperations(interfaceDefinition, component, + component.getInterfaces().get(interfaceType1), Collections.emptyMap(), true).isLeft()); } @Test public void shouldFailWhenOperationNameLengthIsInvalid() { - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputId)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputName1)); InterfaceDefinition interfaceDefinition = createInterfaceOperationData(operationId2, operationId2, new ArtifactDefinition(), - operationInputDefinitionList, operationOutputDefinitionList, + operationInputDefinitionList,operationOutputDefinitionList, + "interface operation2 - The Spring Initializer provides a project generator to make you " + "productive with the certain technology stack from the beginning. " - + "You can create a skeleton project" - + "with web, data access (relational and NoSQL data stores), " - + "cloud, or messaging support"); + + "You can create a " + + "skeleton project with web, data access (relational and NoSQL data stores), " + + "cloud, " + + "or messaging support"); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(interfaceDefinition, component, - component.getInterfaces() - .get(interfaceId), Collections.emptyMap(), false) - .isRight()); + .validateInterfaceOperations(interfaceDefinition, component, + component.getInterfaces().get(interfaceType1), Collections.emptyMap(), false).isRight()); } @Test public void shouldFailWhenOperationInputParamNamesAreNotUnique() { - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputId)); - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputId)); - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(outputId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputId)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); + operationInputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationInputDefinition(outputName1, 1)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputName1)); InterfaceDefinition interfaceDefinition = createInterfaceOperationData(operationId2, operationId2, new ArtifactDefinition(), operationInputDefinitionList, operationOutputDefinitionList, "create"); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(interfaceDefinition, component, - component.getInterfaces().get(interfaceId), Collections.emptyMap(), false) - .isRight()); + .validateInterfaceOperations(interfaceDefinition, component, + component.getInterfaces().get(interfaceType1), Collections.emptyMap(), false).isRight()); } @Test public void shouldPassWhenOperationInputParamNamesAreUnique() { - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputId)); - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(outputId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputId)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); + operationInputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationInputDefinition(outputName1, 1)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputName1)); InterfaceDefinition interfaceDefinition = createInterfaceOperationData(operationId2, operationId2, new ArtifactDefinition(), operationInputDefinitionList, operationOutputDefinitionList, "update"); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(interfaceDefinition, component, - component.getInterfaces().get(interfaceId), Collections.emptyMap(), false) - .isLeft()); + .validateInterfaceOperations(interfaceDefinition, component, + component.getInterfaces().get(interfaceType1), Collections.emptyMap(), false).isLeft()); } @Test public void shouldPassWhenOperationInputParamNamesHasSubProperty() { - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputId)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputName1)); InterfaceDefinition interfaceDefinition = createInterfaceOperationData(operationId2, operationId2, new ArtifactDefinition(), operationInputDefinitionList, operationOutputDefinitionList, "update"); operationInputDefinitionList.getListToscaDataDefinition().get(0).setInputId( operationInputDefinitionList.getListToscaDataDefinition().get(0).getInputId().concat(".subproperty")); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(interfaceDefinition, component, - component.getInterfaces().get(interfaceId), Collections.emptyMap(), false) - .isLeft()); + .validateInterfaceOperations(interfaceDefinition, component, + component.getInterfaces().get(interfaceType1), Collections.emptyMap(), false).isLeft()); } @Test public void shouldFailWhenOperationInputParamNameEmpty() { - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(" ")); - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputId)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(" ", 1)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputName1)); InterfaceDefinition interfaceDefinition = createInterfaceOperationData(operationId2, operationId2, new ArtifactDefinition(), operationInputDefinitionList, operationOutputDefinitionList, "update"); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(interfaceDefinition, component, - component.getInterfaces().get(interfaceId), Collections.emptyMap(), false) - .isRight()); + .validateInterfaceOperations(interfaceDefinition, component, + component.getInterfaces().get(interfaceType1), Collections.emptyMap(), false).isRight()); } @Test public void shouldFailWhenOperationOutputParamNameEmpty() { - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputId)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(" ")); InterfaceDefinition interfaceDefinition = createInterfaceOperationData(operationId2, operationId2, new ArtifactDefinition(), operationInputDefinitionList, operationOutputDefinitionList, "update"); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(interfaceDefinition, component, - component.getInterfaces().get(interfaceId), Collections.emptyMap(), false) - .isRight()); + .validateInterfaceOperations(interfaceDefinition, component, + component.getInterfaces().get(interfaceType1), Collections.emptyMap(), false).isRight()); } @Test public void shouldPassWhenInterfaceOperationOutputParamNamesUnique() { - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(inputId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputId)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(inputName1)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputName1)); InterfaceDefinition interfaceDefinition = createInterfaceOperationData(operationId2, operationId2, new ArtifactDefinition(), operationInputDefinitionList, operationOutputDefinitionList, "update"); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(interfaceDefinition, component, - component.getInterfaces().get(interfaceId), Collections.emptyMap(), false) - .isLeft()); + .validateInterfaceOperations(interfaceDefinition, component, + component.getInterfaces().get(interfaceType1), Collections.emptyMap(), false).isLeft()); } @Test public void shouldFailWhenOperationOutputParamNamesAreNotUnique() { - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(inputId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputId)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(inputName1)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputName1)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputName1)); InterfaceDefinition interfaceDefinition = createInterfaceOperationData(operationId2, operationId2, new ArtifactDefinition(), operationInputDefinitionList, operationOutputDefinitionList, "update"); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(interfaceDefinition, component, - component.getInterfaces().get(interfaceId), Collections.emptyMap(), false) - .isRight()); + .validateInterfaceOperations(interfaceDefinition, component, + component.getInterfaces().get(interfaceType1), Collections.emptyMap(), false).isRight()); } @Test public void shouldPassWhenOperationInputParamExistInComponentProperty() { - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputId)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputName1)); InterfaceDefinition interfaceDefinition = createInterfaceOperationData(operationId2, operationId2, new ArtifactDefinition(), operationInputDefinitionList, operationOutputDefinitionList, "update"); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(interfaceDefinition, component, - component.getInterfaces().get(interfaceId), Collections.emptyMap(), false) - .isLeft()); + .validateInterfaceOperations(interfaceDefinition, component, + component.getInterfaces().get(interfaceType1), Collections.emptyMap(), false).isLeft()); } @Test public void shouldFailWhenOperationInputParamDoesntExistInComponentProperty() { - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputId)); - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(operationId)); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputId)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 2)); + operationOutputDefinitionList + .add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(outputName1)); InterfaceDefinition interfaceDefinition = createInterfaceOperationData(operationId2, operationId2, new ArtifactDefinition(), operationInputDefinitionList, operationOutputDefinitionList, "update"); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(interfaceDefinition, component, - component.getInterfaces().get(interfaceId), Collections.emptyMap(), false) - .isRight()); + .validateInterfaceOperations(interfaceDefinition, component, + component.getInterfaces().get(interfaceType1), Collections.emptyMap(), false).isRight()); } @Test public void shouldFailValidateAllowedOperationCountOnLocalInterfaceType() { InterfaceDefinition inputInterfaceDefinition = - InterfaceOperationTestUtils.createMockInterface(interfaceId, operationType); + InterfaceOperationTestUtils.createMockInterface(interfaceType1 + , operationId, operationType1); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(inputInterfaceDefinition, component, - component.getInterfaces().get(interfaceId), - InterfaceOperationTestUtils.createMockInterfaceTypeMap(interfaceType, - operationType), - false).isRight()); + .validateInterfaceOperations(inputInterfaceDefinition, component, + component.getInterfaces().get(interfaceType1), + InterfaceOperationTestUtils.createMockInterfaceTypeMap( + interfaceType2, operationType1), false).isRight()); } @Test public void shouldFailValidateAllowedOperationsOnGlobalInterfaceType() { InterfaceDefinition inputInterfaceDefinition = - InterfaceOperationTestUtils.createMockInterface(interfaceType, operationId); + InterfaceOperationTestUtils.createMockInterface(interfaceType1 + , operationId, operationType1); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(inputInterfaceDefinition, component, - component.getInterfaces().get(interfaceId), - InterfaceOperationTestUtils.createMockInterfaceTypeMap(interfaceType, - operationType), - false).isRight()); + .validateInterfaceOperations(inputInterfaceDefinition, component, + component.getInterfaces().get(interfaceType1), + InterfaceOperationTestUtils.createMockInterfaceTypeMap( + interfaceType1, operationType1), false).isRight()); } @Test public void shouldPassValidateAllowedOperationsOnGlobalInterfaceType() { InterfaceDefinition inputInterfaceDefinition = - InterfaceOperationTestUtils.createMockInterface(interfaceType, operationType); + InterfaceOperationTestUtils.createMockInterface(interfaceType2, + operationId2, operationType2); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(inputInterfaceDefinition, component, - component.getInterfaces().get(interfaceId), - InterfaceOperationTestUtils.createMockInterfaceTypeMap(interfaceType, - operationType), - false).isLeft()); + .validateInterfaceOperations(inputInterfaceDefinition, component, + component.getInterfaces().get(interfaceType1), + InterfaceOperationTestUtils.createMockInterfaceTypeMap( + interfaceType2, operationType2), false).isLeft()); } @Test public void shouldFailValidateOperationNameUniquenessInCollection() { - InterfaceDefinition inputInterfaceDefinition = - InterfaceOperationTestUtils.createMockInterface(interfaceType, operationType); - inputInterfaceDefinition.getOperations() - .put(operationId, InterfaceOperationTestUtils.createMockOperation(operationType)); + InterfaceDefinition inputInterfaceDefinition = InterfaceOperationTestUtils.createMockInterface(interfaceType1, + operationId, operationType1); + inputInterfaceDefinition.getOperations().put(operationId, + createMockOperation(operationId, operationType1)); Assert.assertTrue(interfaceOperationValidationUtilTest - .validateInterfaceOperations(inputInterfaceDefinition, component, - component.getInterfaces().get(interfaceId), - InterfaceOperationTestUtils.createMockInterfaceTypeMap(interfaceType, - operationType), - false).isRight()); + .validateInterfaceOperations(inputInterfaceDefinition, component, + component.getInterfaces().get(interfaceType1), + InterfaceOperationTestUtils.createMockInterfaceTypeMap( + interfaceType1, operationType1), false).isRight()); + } + + @Test + public void shouldPassValidateWhenInputIsMappedToValidOutput() { + InterfaceDefinition inputInterfaceDefinition = InterfaceOperationTestUtils.createMockInterface(interfaceType2, + operationId, operationType1); + inputInterfaceDefinition.getOperationsMap().values() + .forEach(operation -> operation.getInputs().getListToscaDataDefinition() + .forEach(operationInputDefinition -> operationInputDefinition.setInputId(interfaceType1 + + "." + operationType1 + "." + outputName1))); + Assert.assertTrue(interfaceOperationValidationUtilTest.validateInterfaceOperations(inputInterfaceDefinition, + component, null, Collections.emptyMap(), false).isLeft()); + } + + @Test + public void shouldPassValidateWhenOutputNameIsUnchanged() { + InterfaceDefinition inputInterfaceDefinition = InterfaceOperationTestUtils.createMockInterface(interfaceType2, + operationId, operationType1); + InterfaceDefinition inputParamOutputMappedInterface = InterfaceOperationTestUtils.createMockInterface( + interfaceType2, operationId, operationType1); + inputParamOutputMappedInterface.getOperationsMap().values() + .forEach(operation -> operation.getInputs().getListToscaDataDefinition() + .forEach(operationInputDefinition -> operationInputDefinition.setInputId(interfaceType2 + + "." + operationType2 + "." + outputName1))); + component.getInterfaces().put(interfaceType2, inputParamOutputMappedInterface); + component.getInterfaces().put(interfaceType3, InterfaceOperationTestUtils.createMockInterface(interfaceType3, + operationId, operationType2)); + Assert.assertTrue(interfaceOperationValidationUtilTest.validateInterfaceOperations(inputInterfaceDefinition, + component, component.getInterfaces().get(interfaceType1), + Collections.emptyMap(), true).isLeft()); + } + + @Test + public void shouldPassValidateWhenDeletedOutputIsUnMapped() { + InterfaceDefinition inputInterfaceDefinition = InterfaceOperationTestUtils.createMockInterface(interfaceType2, + operationId, operationType1); + inputInterfaceDefinition.getOperationsMap().values() + .forEach(operation -> operation.getOutputs().getListToscaDataDefinition() + .forEach(operationOutputDefinition -> operationOutputDefinition.setName(outputName2))); + component.getInterfaces().put(interfaceType3, InterfaceOperationTestUtils.createMockInterface( + interfaceType3, operationId, operationType2)); + component.getInterfaces().put(interfaceType2, InterfaceOperationTestUtils.createMockInterface(interfaceType2, + operationId, operationType1)); + Assert.assertTrue(interfaceOperationValidationUtilTest.validateInterfaceOperations(inputInterfaceDefinition, + component, component.getInterfaces().get(interfaceType2), + Collections.emptyMap(), true).isLeft()); + } + + @Test + public void shouldPassValidateNoOutputsInExistingInterfaceOperation() { + InterfaceDefinition inputInterfaceDefinition = InterfaceOperationTestUtils.createMockInterface(interfaceType1, + operationId, operationType1); + inputInterfaceDefinition.getOperationsMap().values() + .forEach(operation -> operation.getOutputs().getListToscaDataDefinition() + .forEach(operationOutputDefinition -> operationOutputDefinition.setName(outputName2))); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(inputName1, 1)); + InterfaceDefinition noOutputInterface = createInterfaceOperationData(operationId, "desc", + new ArtifactDefinition(), operationInputDefinitionList, null, operationType1); + component.getInterfaces().put(interfaceType1, noOutputInterface); + component.getInterfaces().put(interfaceType3, InterfaceOperationTestUtils.createMockInterface( + interfaceType3, operationId, operationType2)); + Assert.assertTrue(interfaceOperationValidationUtilTest.validateInterfaceOperations(inputInterfaceDefinition, + component, component.getInterfaces().get(interfaceType1), + Collections.emptyMap(), true).isLeft()); + } + + @Test + public void shouldFailValidateMappedOutputDoesNotExistInComponent() { + //Input parameter is mapped to invalid output (which does not exist in any of the other operations) + InterfaceDefinition inputInterfaceDefinition = InterfaceOperationTestUtils.createMockInterface(interfaceType2, + operationId, operationType1); + inputInterfaceDefinition.getOperationsMap().values() + .forEach(operation -> operation.getInputs().getListToscaDataDefinition() + .forEach(operationInputDefinition -> operationInputDefinition.setInputId(outputName2))); + + Assert.assertTrue(interfaceOperationValidationUtilTest.validateInterfaceOperations(inputInterfaceDefinition, + component, null, Collections.emptyMap(), false).isRight()); + } + + @Test + public void shouldFailValidateComponentFirstInterfaceInvalidInputMapping() { + //Input parameter is mapped to invalid output (which does not exist in any of the other operations) + InterfaceDefinition inputInterfaceDefinition = InterfaceOperationTestUtils.createMockInterface(interfaceType2, + operationId, operationType1); + inputInterfaceDefinition.getOperationsMap().values() + .forEach(operation -> operation.getInputs().getListToscaDataDefinition() + .forEach(operationInputDefinition -> operationInputDefinition.setInputId(outputName2))); + component.setInterfaces(null); + Assert.assertTrue(interfaceOperationValidationUtilTest.validateInterfaceOperations(inputInterfaceDefinition, + component, null, Collections.emptyMap(), false).isRight()); + } + + + @Test + public void shouldFailValidateMappedOutputDeletion() { + //Input interface from user with new output name (Output2) + InterfaceDefinition inputInterfaceDefinition = InterfaceOperationTestUtils.createMockInterface(interfaceType2, + operationId, operationType1); + inputInterfaceDefinition.getOperationsMap().values() + .forEach(operation -> operation.getOutputs().getListToscaDataDefinition() + .forEach(operationOutputDefinition -> operationOutputDefinition.setName(outputName2))); + + InterfaceDefinition inputParamOutputMappedInterface = InterfaceOperationTestUtils.createMockInterface( + interfaceType3, operationId, operationType2); + inputParamOutputMappedInterface.getOperationsMap().values() + .forEach(operation -> operation.getInputs().getListToscaDataDefinition() + .forEach(operationInputDefinition -> operationInputDefinition.setInputId(interfaceType2 + + "." + operationType1 + "." + outputName1))); + component.getInterfaces().put(interfaceType3, inputParamOutputMappedInterface); + component.getInterfaces().put(interfaceType2, InterfaceOperationTestUtils.createMockInterface(interfaceType2, + operationId, operationType1)); + Assert.assertTrue(interfaceOperationValidationUtilTest.validateInterfaceOperations(inputInterfaceDefinition, + component, component.getInterfaces().get(interfaceType2), + Collections.emptyMap(), true).isRight()); + } + + @Test + public void shouldFailValidateAllMappedOutputsDeleted() { + //Input interface from user with all outputs deleted + InterfaceDefinition inputInterfaceDefinition = InterfaceOperationTestUtils.createMockInterface(interfaceType2, + operationId, operationType1); + Map<String, Operation> operationsMap = inputInterfaceDefinition.getOperationsMap(); + for (Map.Entry<String, Operation> operationEntry : operationsMap.entrySet()) { + operationEntry.getValue().setOutputs(null); + } + inputInterfaceDefinition.setOperationsMap(operationsMap); + + InterfaceDefinition inputParamOutputMappedInterface = InterfaceOperationTestUtils.createMockInterface( + interfaceType3, operationId, operationType2); + inputParamOutputMappedInterface.getOperationsMap().values() + .forEach(operation -> operation.getInputs().getListToscaDataDefinition() + .forEach(operationInputDefinition -> operationInputDefinition.setInputId(interfaceType2 + + "." + operationType1 + "." + outputName1))); + component.getInterfaces().put(interfaceType3, inputParamOutputMappedInterface); + component.getInterfaces().put(interfaceType2, InterfaceOperationTestUtils.createMockInterface(interfaceType2, + operationId, operationType1)); + Assert.assertTrue(interfaceOperationValidationUtilTest.validateInterfaceOperations(inputInterfaceDefinition, + component, component.getInterfaces().get(interfaceType2), + Collections.emptyMap(), true).isRight()); + } + + + private InterfaceDefinition createInterfaceOperationData(String uniqueID, String description, + ArtifactDefinition artifactDefinition, + ListDataDefinition<OperationInputDefinition> inputs, + ListDataDefinition<OperationOutputDefinition> outputs, + String name) { + Operation operation = new Operation(); + operation.setUniqueId(uniqueID); + operation.setDescription(description); + operation.setImplementation(artifactDefinition); + operation.setInputs(inputs); + operation.setOutputs(outputs); + operation.setName(name); + Map<String, Operation> operationMap = new HashMap<>(); + operationMap.put(operation.getUniqueId(), operation); + InterfaceDefinition interfaceDefinition = new InterfaceDefinition(); + interfaceDefinition.setType(interfaceType2); + interfaceDefinition.setOperationsMap(operationMap); + return interfaceDefinition; + } + + private List<InputDefinition> createInputsForComponent() { + String componentInputName = "ComponentInput1"; + InputDefinition inputDefinition1 = new InputDefinition(); + inputDefinition1.setName(componentInputName); + inputDefinition1.setInputId(componentInputName + "_inputId"); + inputDefinition1.setUniqueId(componentInputName + "_uniqueId"); + inputDefinition1.setValue(componentInputName + "_value"); + inputDefinition1.setDefaultValue(componentInputName + "_defaultValue"); + + String componentInputName2 = "ComponentInput2"; + InputDefinition inputDefinition2 = new InputDefinition(); + inputDefinition2.setName(componentInputName2); + inputDefinition2.setInputId(componentInputName2 + "_inputId"); + inputDefinition2.setUniqueId(componentInputName2 + "_uniqueId"); + inputDefinition2.setValue(componentInputName2 + "_value"); + inputDefinition2.setDefaultValue(componentInputName2 + "_defaultValue"); + + return Arrays.asList(inputDefinition1, inputDefinition2); } private class InterfaceOperationValidationUtilTest extends InterfaceOperationValidation { diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtilTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtilTest.java index 983ef91a8c..36dd5d9796 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtilTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtilTest.java @@ -16,12 +16,20 @@ package org.openecomp.sdc.be.tosca.utils; +import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.GET_OPERATION_OUTPUT; +import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.GET_PROPERTY; +import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.SELF; +import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.addInterfaceDefinitionElement; +import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.addInterfaceTypeElement; + import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Objects; import org.junit.Assert; import org.junit.BeforeClass; @@ -31,15 +39,15 @@ import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition; import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.Service; import org.openecomp.sdc.be.tosca.ToscaExportHandler; import org.openecomp.sdc.be.tosca.ToscaRepresentation; -import org.openecomp.sdc.be.tosca.model.ToscaLifecycleOperationDefinition; import org.openecomp.sdc.be.tosca.model.ToscaNodeType; -import org.openecomp.sdc.be.tosca.model.ToscaProperty; import org.openecomp.sdc.be.tosca.model.ToscaTemplate; import org.openecomp.sdc.common.util.YamlToObjectConverter; @@ -47,6 +55,7 @@ public class InterfacesOperationsToscaUtilTest { private static final String MAPPED_PROPERTY_NAME = "mapped_property"; private static final String INPUT_NAME_PREFIX = "input_"; + private static final String OUTPUT_NAME_PREFIX = "output_"; private static final String NODE_TYPE_NAME = "test"; private String[] inputTypes = {"string", "integer", "float", "boolean"}; private static ObjectMapper mapper; @@ -65,12 +74,12 @@ public class InterfacesOperationsToscaUtilTest { component.setNormalizedName("normalizedComponentName"); InterfaceDefinition addedInterface = new InterfaceDefinition(); addedInterface.setType("interface.types.test_resource_name"); - addOperationsToInterface(addedInterface, 5, 3, true); + addOperationsToInterface(component, addedInterface, 5, 3, true, false); final String interfaceType = "normalizedComponentName-interface"; component.setInterfaces(new HashMap<>()); component.getInterfaces().put(interfaceType, addedInterface); final Map<String, Object> interfaceTypeElement = - InterfacesOperationsToscaUtil.addInterfaceTypeElement(component, new ArrayList<>()); + addInterfaceTypeElement(component, new ArrayList<>()); ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null); ToscaTemplate template = new ToscaTemplate("test"); @@ -87,12 +96,12 @@ public class InterfacesOperationsToscaUtilTest { component.setNormalizedName("normalizedServiceComponentName"); InterfaceDefinition addedInterface = new InterfaceDefinition(); addedInterface.setType("interface.types.test_service_name"); - addOperationsToInterface(addedInterface, 5, 3, true); + addOperationsToInterface(component, addedInterface, 5, 3, true, false); final String interfaceType = "normalizedServiceComponentName-interface"; component.setInterfaces(new HashMap<>()); component.getInterfaces().put(interfaceType, addedInterface); final Map<String, Object> interfaceTypeElement = - InterfacesOperationsToscaUtil.addInterfaceTypeElement(component, new ArrayList<>()); + addInterfaceTypeElement(component, new ArrayList<>()); ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null); ToscaTemplate template = new ToscaTemplate("testService"); @@ -110,12 +119,12 @@ public class InterfacesOperationsToscaUtilTest { InterfaceDefinition addedInterface = new InterfaceDefinition(); addedInterface.setType("com.some.resource.or.other.resourceName"); - addOperationsToInterface(addedInterface, 3, 2, true); + addOperationsToInterface(component, addedInterface, 3, 2, true, false); final String interfaceType = "normalizedComponentName-interface"; component.setInterfaces(new HashMap<>()); component.getInterfaces().put(interfaceType, addedInterface); ToscaNodeType nodeType = new ToscaNodeType(); - InterfacesOperationsToscaUtil.addInterfaceDefinitionElement(component, nodeType, false); + addInterfaceDefinitionElement(component, nodeType, false); ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null); ToscaTemplate template = new ToscaTemplate(NODE_TYPE_NAME); @@ -128,7 +137,7 @@ public class InterfacesOperationsToscaUtilTest { Assert.assertFalse(mainYaml.contains("operations")); Assert.assertTrue(mainYaml.contains("resourceName:")); Assert.assertTrue(mainYaml.contains("inputs:")); - validateOperationInputs(mainYaml); + validateOperationInputs(mainYaml, 2, null); Assert.assertFalse(mainYaml.contains("defaultp")); Assert.assertTrue(mainYaml.contains("has description")); Assert.assertTrue(mainYaml.contains(MAPPED_PROPERTY_NAME)); @@ -141,12 +150,12 @@ public class InterfacesOperationsToscaUtilTest { component.setNormalizedName("normalizedServiceComponentName"); InterfaceDefinition addedInterface = new InterfaceDefinition(); addedInterface.setType("com.some.service.or.other.serviceName"); - addOperationsToInterface(addedInterface, 3, 2, true); + addOperationsToInterface(component, addedInterface, 3, 2, true, false); final String interfaceType = "normalizedServiceComponentName-interface"; component.setInterfaces(new HashMap<>()); component.getInterfaces().put(interfaceType, addedInterface); ToscaNodeType nodeType = new ToscaNodeType(); - InterfacesOperationsToscaUtil.addInterfaceDefinitionElement(component, nodeType, false); + addInterfaceDefinitionElement(component, nodeType, false); ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null); ToscaTemplate template = new ToscaTemplate("testService"); @@ -158,7 +167,7 @@ public class InterfacesOperationsToscaUtilTest { Assert.assertFalse(mainYaml.contains("operations")); Assert.assertTrue(mainYaml.contains("serviceName:")); Assert.assertTrue(mainYaml.contains("inputs:")); - validateOperationInputs(mainYaml); + validateOperationInputs(mainYaml, 2, null); Assert.assertFalse(mainYaml.contains("defaultp")); Assert.assertTrue(mainYaml.contains("has description")); Assert.assertTrue(mainYaml.contains(MAPPED_PROPERTY_NAME)); @@ -171,12 +180,12 @@ public class InterfacesOperationsToscaUtilTest { component.setNormalizedName("normalizedComponentName"); InterfaceDefinition addedInterface = new InterfaceDefinition(); addedInterface.setType("com.some.resource.or.other.resourceNameNoInputs"); - addOperationsToInterface(addedInterface, 3, 3, false); + addOperationsToInterface(component, addedInterface, 3, 3, false, false); final String interfaceType = "normalizedComponentName-interface"; component.setInterfaces(new HashMap<>()); component.getInterfaces().put(interfaceType, addedInterface); ToscaNodeType nodeType = new ToscaNodeType(); - InterfacesOperationsToscaUtil.addInterfaceDefinitionElement(component, nodeType, false); + addInterfaceDefinitionElement(component, nodeType, false); ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null); ToscaTemplate template = new ToscaTemplate("test"); @@ -193,9 +202,42 @@ public class InterfacesOperationsToscaUtilTest { Assert.assertTrue(toscaRepresentation.getMainYaml().contains("com.some.resource.or.other.resourceName")); } + @Test + public void addInterfaceDefinitionElementInputMappedToOtherOperationOutput() { + String addedInterfaceType = "com.some.resource.or.other.resourceNameInputMappedToOutput"; + Component component = new Resource(); + component.setNormalizedName("normalizedComponentName"); + InterfaceDefinition addedInterface = new InterfaceDefinition(); + addedInterface.setType(addedInterfaceType); + addOperationsToInterface(component, addedInterface, 2, 2, true, true); + addedInterface.getOperationsMap().values().stream() + .filter(operationInputDefinition -> operationInputDefinition.getName().equalsIgnoreCase( + "name_for_op_0")) + .forEach(operation -> operation.getInputs().getListToscaDataDefinition().stream() + .filter(operationInputDefinition -> operationInputDefinition.getName().contains("integer")) + .forEach(operationInputDefinition -> operationInputDefinition.setInputId(addedInterfaceType + + ".name_for_op_1.output_integer_1"))); + component.setInterfaces(new HashMap<>()); + component.getInterfaces().put(addedInterfaceType, addedInterface); + ToscaNodeType nodeType = new ToscaNodeType(); + addInterfaceDefinitionElement(component, nodeType, false); + + ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null); + ToscaTemplate template = new ToscaTemplate("test"); + Map<String, ToscaNodeType> nodeTypes = new HashMap<>(); + nodeTypes.put("test", nodeType); + template.setNode_types(nodeTypes); + final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); + + String mainYaml = toscaRepresentation.getMainYaml(); + Assert.assertFalse(mainYaml.contains("operations")); + Assert.assertTrue(mainYaml.contains("resourceNameInputMappedToOutput:")); + Assert.assertTrue(mainYaml.contains("inputs:")); + validateOperationInputs(mainYaml, 2, "name_for_op_1"); + } - private void addOperationsToInterface(InterfaceDefinition addedInterface, int numOfOps, int numOfInputsPerOp, - boolean hasInputs) { + private void addOperationsToInterface(Component component, InterfaceDefinition addedInterface, int numOfOps, + int numOfInputsPerOp, boolean hasInputs, boolean hasOutputs) { addedInterface.setOperations(new HashMap<>()); for (int i = 0; i < numOfOps; i++) { @@ -206,23 +248,46 @@ public class InterfacesOperationsToscaUtilTest { implementation.setArtifactName(i + "_createBPMN.bpmn"); operation.setImplementation(implementation); if (hasInputs) { - operation.setInputs(createInputs(numOfInputsPerOp)); + operation.setInputs(createInputs(component, numOfInputsPerOp)); + } + if (hasOutputs) { + operation.setOutputs(createOutputs(numOfInputsPerOp)); } addedInterface.getOperations().put(operation.getName(), operation); } } - private ListDataDefinition<OperationInputDefinition> createInputs(int numOfInputs) { + private ListDataDefinition<OperationInputDefinition> createInputs(Component component, int numOfInputs) { ListDataDefinition<OperationInputDefinition> operationInputDefinitionList = new ListDataDefinition<>(); for (int i = 0; i < numOfInputs; i++) { + String mappedPropertyName = java.util.UUID.randomUUID().toString() + "." + MAPPED_PROPERTY_NAME + i; operationInputDefinitionList.add(createMockOperationInputDefinition( - INPUT_NAME_PREFIX + inputTypes[i] + "_" + i, - java.util.UUID.randomUUID().toString() + "." + MAPPED_PROPERTY_NAME, i)); + INPUT_NAME_PREFIX + inputTypes[i] + "_" + i, mappedPropertyName, i)); + addMappedPropertyAsComponentInput(component, mappedPropertyName); + } return operationInputDefinitionList; } + private void addMappedPropertyAsComponentInput(Component component, String mappedPropertyName) { + InputDefinition componentInput = new InputDefinition(); + componentInput.setUniqueId(mappedPropertyName.split("\\.")[0]); + componentInput.setName(mappedPropertyName.split("\\.")[1]); + if (Objects.isNull(component.getInputs())) { + component.setInputs(new ArrayList<>()); + } + component.getInputs().add(componentInput); + } + + private ListDataDefinition<OperationOutputDefinition> createOutputs(int numOfOutputs) { + ListDataDefinition<OperationOutputDefinition> operationOutputDefinitionList = new ListDataDefinition<>(); + for (int i = 0; i < numOfOutputs; i++) { + operationOutputDefinitionList.add(createMockOperationOutputDefinition( + OUTPUT_NAME_PREFIX + inputTypes[i] + "_" + i, i)); + } + return operationOutputDefinitionList; + } private OperationInputDefinition createMockOperationInputDefinition(String name, String id, int index) { OperationInputDefinition operationInputDefinition = new OperationInputDefinition(); @@ -233,31 +298,70 @@ public class InterfacesOperationsToscaUtilTest { return operationInputDefinition; } - private void validateOperationInputs(String mainYaml) { + private OperationOutputDefinition createMockOperationOutputDefinition(String name, int index) { + OperationOutputDefinition operationInputDefinition = new OperationOutputDefinition(); + operationInputDefinition.setName(name); + operationInputDefinition.setType(inputTypes[index]); + operationInputDefinition.setRequired(index % 2 == 0); + return operationInputDefinition; + } + + private void validateOperationInputs(String mainYaml, int numOfInputsPerOp, String mappedOperationName) { String nodeTypeKey = NODE_TYPE_NAME + ":"; String nodeTypesRepresentation = mainYaml.substring(mainYaml.indexOf(nodeTypeKey) + nodeTypeKey.length(), - mainYaml.lastIndexOf(MAPPED_PROPERTY_NAME) + MAPPED_PROPERTY_NAME.length()); + mainYaml.lastIndexOf(MAPPED_PROPERTY_NAME) + MAPPED_PROPERTY_NAME.length() + + String.valueOf(numOfInputsPerOp).length()); YamlToObjectConverter objectConverter = new YamlToObjectConverter(); ToscaNodeType toscaNodeType = objectConverter.convert(nodeTypesRepresentation.getBytes(), ToscaNodeType.class); Map<String, Object> interfaces = toscaNodeType.getInterfaces(); - for (Object interfaceVal : interfaces.values()) { - Map<String, Object> interfaceDefinition = mapper.convertValue(interfaceVal, Map.class); - for (Object operationVal : interfaceDefinition.values()) { + for (Map.Entry<String, Object> interfaceEntry : interfaces.entrySet()) { + Map<String, Object> interfaceDefinition = mapper.convertValue(interfaceEntry.getValue(), Map.class); + for (Map.Entry<String, Object> operationEntry : interfaceDefinition.entrySet()) { + Object operationVal = operationEntry.getValue(); if (operationVal instanceof Map) { - validateOperationInputDefinition(operationVal); + validateOperationInputDefinition((String) interfaceDefinition.get("type"), mappedOperationName, + operationVal); } } } } - private void validateOperationInputDefinition(Object operationVal) { - ToscaLifecycleOperationDefinition operation = - mapper.convertValue(operationVal, ToscaLifecycleOperationDefinition.class); - Map<String, ToscaProperty> inputs = operation.getInputs(); - for (Map.Entry<String, ToscaProperty> inputEntry : inputs.entrySet()) { - Assert.assertEquals(inputEntry.getKey().split("_")[1], inputEntry.getValue().getType()); - Boolean expectedIsRequired = Integer.parseInt(inputEntry.getKey().split("_")[2]) % 2 == 0; - Assert.assertEquals(expectedIsRequired, inputEntry.getValue().getRequired()); + private void validateOperationInputDefinition(String interfaceType, String operationName, Object operationVal) { + Map<String, Object> operation = mapper.convertValue(operationVal, Map.class); + Map<String, Object> inputs = (Map<String, Object>) operation.get("inputs"); + for (Map.Entry<String, Object> inputEntry : inputs.entrySet()) { + String[] inputNameSplit = inputEntry.getKey().split("_"); + Map<String, Object> inputValueObject = (Map<String, Object>) inputEntry.getValue(); + Assert.assertEquals(inputNameSplit[1], inputValueObject.get("type")); + Boolean expectedIsRequired = Integer.parseInt(inputNameSplit[2]) % 2 == 0; + Assert.assertEquals(expectedIsRequired, inputValueObject.get("required")); + validateOperationInputDefinitionDefaultValue(interfaceType, operationName, inputNameSplit[1], + Integer.parseInt(inputNameSplit[2]), inputValueObject); + } + } + + + private void validateOperationInputDefinitionDefaultValue(String interfaceType, String operationName, + String inputType, int index, + Map<String, Object> inputValueObject) { + Map<String, Object> mappedInputValue = (Map<String, Object>) inputValueObject.get("default"); + if(mappedInputValue.containsKey(GET_PROPERTY)) { + String mappedPropertyValue = MAPPED_PROPERTY_NAME + index; + List<String> mappedPropertyDefaultValue = (List<String>) mappedInputValue.get(GET_PROPERTY); + Assert.assertEquals(2, mappedPropertyDefaultValue.size()); + Assert.assertTrue(mappedPropertyDefaultValue.contains(SELF)); + Assert.assertTrue(mappedPropertyDefaultValue.contains(mappedPropertyValue)); + } else if(mappedInputValue.containsKey(GET_OPERATION_OUTPUT)) { + List<String> mappedPropertyDefaultValue = (List<String>) mappedInputValue.get(GET_OPERATION_OUTPUT); + Assert.assertEquals(4, mappedPropertyDefaultValue.size()); + String mappedPropertyValue = OUTPUT_NAME_PREFIX + inputType + "_" + index; + Assert.assertTrue(mappedPropertyDefaultValue.contains(SELF)); + Assert.assertTrue(mappedPropertyDefaultValue.contains(interfaceType)); + Assert.assertTrue(mappedPropertyDefaultValue.contains(operationName)); + Assert.assertTrue(mappedPropertyDefaultValue.contains(mappedPropertyValue)); + } else { + Assert.fail("Invalid Tosca function in default value. Allowed values: "+ GET_PROPERTY + + "/"+ GET_OPERATION_OUTPUT); } } } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/test/utils/InterfaceOperationTestUtils.java b/catalog-be/src/test/java/org/openecomp/sdc/test/utils/InterfaceOperationTestUtils.java index f21d5a9dcf..c614c6e6e9 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/test/utils/InterfaceOperationTestUtils.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/test/utils/InterfaceOperationTestUtils.java @@ -18,6 +18,7 @@ package org.openecomp.sdc.test.utils; import java.util.HashMap; import java.util.Map; + import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition; @@ -27,17 +28,6 @@ import org.openecomp.sdc.be.model.Operation; public class InterfaceOperationTestUtils { - public static Map<String, InterfaceDefinition> createMockInterfaceDefinitionMap(String interfaceId, - String operationId) { - Map<String, InterfaceDefinition> interfaceDefinitionMap = new HashMap<>(); - interfaceDefinitionMap.put(interfaceId, createMockInterface(interfaceId, operationId)); - return interfaceDefinitionMap; - } - - public static InterfaceDefinition createMockInterface(String interfaceId, String operationId) { - return createInterface(interfaceId, interfaceId, interfaceId, interfaceId, createMockOperationMap(operationId)); - } - private static InterfaceDefinition createInterface(String uniqueId, String description, String type, String toscaResourceName, Map<String, Operation> op) { InterfaceDefinition id = new InterfaceDefinition(); @@ -49,24 +39,37 @@ public class InterfaceOperationTestUtils { return id; } - public static Map<String, Operation> createMockOperationMap(String operationId) { + public static Map<String, InterfaceDefinition> createMockInterfaceDefinitionMap(String interfaceId, + String operationId, + String operationName) { + Map<String, InterfaceDefinition> interfaceDefinitionMap = new HashMap<>(); + interfaceDefinitionMap.put(interfaceId, createMockInterface(interfaceId, operationId, operationName)); + return interfaceDefinitionMap; + } + + public static InterfaceDefinition createMockInterface(String interfaceId, String operationId, String operationName) { + return createInterface(interfaceId, interfaceId, interfaceId, interfaceId, createMockOperationMap(operationId, + operationName)); + } + + public static Map<String, Operation> createMockOperationMap(String operationId, String operationName) { Map<String, Operation> operationMap = new HashMap<>(); - operationMap.put(operationId, createMockOperation(operationId)); + operationMap.put(operationId, createMockOperation(operationId, operationName)); return operationMap; } - public static Operation createMockOperation(String operationId) { + public static Operation createMockOperation(String operationId, String operationName) { Operation operation = new Operation(); ListDataDefinition<OperationInputDefinition> operationInputDefinitionList = new ListDataDefinition<>(); - operationInputDefinitionList.add(createMockOperationInputDefinition("inputId")); + operationInputDefinitionList.add(createMockOperationInputDefinition("Input1", 1)); operation.setInputs(operationInputDefinitionList); ListDataDefinition<OperationOutputDefinition> operationOutputDefList = new ListDataDefinition<>(); - operationOutputDefList.add(createMockOperationOutputDefinition("outputId")); + operationOutputDefList.add(createMockOperationOutputDefinition("Output1")); operation.setOutputs(operationOutputDefList); operation.setDefinition(false); - operation.setName(operationId); + operation.setName(operationName); operation.setUniqueId(operationId); ArtifactDefinition implementation = new ArtifactDefinition(); implementation.setUniqueId("uniqId"); @@ -77,23 +80,22 @@ public class InterfaceOperationTestUtils { return operation; } - public static OperationInputDefinition createMockOperationInputDefinition(String inputId) { + public static OperationInputDefinition createMockOperationInputDefinition(String inputName, int num) { OperationInputDefinition operationInputDefinition = new OperationInputDefinition(); - operationInputDefinition.setName(inputId); - operationInputDefinition.setUniqueId(inputId); - operationInputDefinition.setInputId(inputId); - operationInputDefinition.setValue(inputId); - operationInputDefinition.setDefaultValue(inputId); + operationInputDefinition.setName(inputName); + operationInputDefinition.setUniqueId(inputName + "_uniqueId"); + operationInputDefinition.setInputId("ComponentInput" + num + "_uniqueId"); + operationInputDefinition.setValue(inputName + "_value"); + operationInputDefinition.setDefaultValue(inputName + "_defaultValue"); return operationInputDefinition; } - public static OperationOutputDefinition createMockOperationOutputDefinition(String outputId) { + public static OperationOutputDefinition createMockOperationOutputDefinition(String outputName) { OperationOutputDefinition operationOutputDefinition = new OperationOutputDefinition(); - operationOutputDefinition.setName(outputId); - operationOutputDefinition.setUniqueId(outputId); - operationOutputDefinition.setInputId(outputId); - operationOutputDefinition.setValue(outputId); - operationOutputDefinition.setDefaultValue(outputId); + operationOutputDefinition.setName(outputName); + operationOutputDefinition.setUniqueId(outputName + "_uniqueId"); + operationOutputDefinition.setValue(outputName + "_value"); + operationOutputDefinition.setDefaultValue(outputName + "_defaultValue"); return operationOutputDefinition; } diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java index 82041b4180..fd6bace35e 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java @@ -124,6 +124,7 @@ public enum ActionStatus { INTERFACE_OPERATION_NOT_FOUND, INTERFACE_OPERATION_NAME_ALREADY_IN_USE, INTERFACE_OPERATION_NAME_MANDATORY, INTERFACE_OPERATION_NAME_INVALID, INTERFACE_OPERATION_INPUT_NAME_ALREADY_IN_USE, INTERFACE_OPERATION_OUTPUT_NAME_ALREADY_IN_USE, INTERFACE_OPERATION_NOT_DELETED, + INTERFACE_OPERATION_MAPPED_OUTPUT_DELETED, INTERFACE_OPERATION_INPUT_NAME_MANDATORY, INTERFACE_OPERATION_OUTPUT_NAME_MANDATORY, INTERFACE_OPERATION_INPUT_PROPERTY_NOT_FOUND_IN_COMPONENT, INTERFACE_OPERATION_INVALID_FOR_LOCAL_TYPE, INTERFACE_OPERATION_INVALID_FOR_GLOBAL_TYPE, |