From 95ad93091d5fa6e377e76f312d495151bddc9da8 Mon Sep 17 00:00:00 2001 From: "andre.schmid" Date: Wed, 14 Oct 2020 20:56:11 +0100 Subject: Support interface input during import VFC Change-Id: I097ce258a7dadbedf1aff6ce53dd1286da074552 Issue-ID: SDC-3372 Signed-off-by: andre.schmid --- .../files/default/error-configuration.yaml | 12 + .../sdc/be/components/impl/ImportUtils.java | 51 +- .../impl/InterfaceDefinitionHandler.java | 255 ++++++++ .../be/components/impl/ResourceImportManager.java | 194 +----- .../be/tosca/InterfacesOperationsConverter.java | 85 ++- .../be/tosca/model/ToscaInterfaceDefinition.java | 27 +- .../main/resources/config/error-configuration.yaml | 12 + .../be/components/ResourceImportManagerTest.java | 64 +- .../sdc/be/components/impl/ImportUtilsTest.java | 8 +- .../impl/InterfaceDefinitionHandlerTest.java | 174 ++++++ .../tosca/InterfacesOperationsConverterTest.java | 669 +++++++++++++++++++++ .../tosca/model/ToscaInterfaceDefinitionTest.java | 72 --- .../utils/InterfacesOperationsConverterTest.java | 563 ----------------- .../config/catalog-be/error-configuration.yaml | 12 + .../interfaceDefinition-legacy.yaml | 24 + .../interfaceDefinition-tosca1.3.yaml | 25 + 16 files changed, 1332 insertions(+), 915 deletions(-) create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandler.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandlerTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverterTest.java delete mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaInterfaceDefinitionTest.java delete mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsConverterTest.java create mode 100644 catalog-be/src/test/resources/interfaceDefinition/interfaceDefinition-legacy.yaml create mode 100644 catalog-be/src/test/resources/interfaceDefinition/interfaceDefinition-tosca1.3.yaml (limited to 'catalog-be') diff --git a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml index d2a79909d6..4aa93cb268 100644 --- a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml +++ b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml @@ -2060,6 +2060,18 @@ errors: message: "Error: Failed to delete interface operation.", messageId: "SVC4702" } + #SVC4732 + INTERFACE_UNKNOWN: { + code: 400, + message: "Error: The interface '%1' does not exists in the database.", + messageId: "SVC4732" + } + #SVC4733 + INTERFACE_OPERATION_NOT_DEFINED: { + code: 400, + message: "Error: The operation '%1' does not exists in the interface '%2'.", + messageId: "SVC4733" + } #-----------SVC4692--------------------------- RESOURCE_LIFECYCLE_STATE_NOT_VALID: { code: 400, diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ImportUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ImportUtils.java index 4127faa820..614b261b4a 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ImportUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ImportUtils.java @@ -47,6 +47,7 @@ import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentEx import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.datatypes.elements.Annotation; +import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; @@ -348,24 +349,24 @@ public final class ImportUtils { } } - private static List getPropertyConstraints(Map propertyValue, - String propertyType) { - List propertyFieldConstraints = findCurrentLevelConstraintsElement(propertyValue); - if (CollectionUtils.isNotEmpty(propertyFieldConstraints)) { - List constraintList = new ArrayList<>(); - Type constraintType = new TypeToken() { - }.getType(); - Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()) - .create(); + private static List getPropertyConstraints(final Map propertyValue, + final String propertyType) { + final List propertyFieldConstraints = findCurrentLevelConstraintsElement(propertyValue); + if (CollectionUtils.isEmpty(propertyFieldConstraints)) { + return Collections.emptyList(); + } + final List constraintList = new ArrayList<>(); + final Type constraintType = new TypeToken() { + }.getType(); + final Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()) + .create(); - for (Object constraintJson : propertyFieldConstraints) { - PropertyConstraint propertyConstraint = validateAndGetPropertyConstraint(propertyType, constraintType, - gson, constraintJson); - constraintList.add(propertyConstraint); - } - return constraintList; + for (final Object constraintJson : propertyFieldConstraints) { + final PropertyConstraint propertyConstraint = validateAndGetPropertyConstraint(propertyType, constraintType, + gson, constraintJson); + constraintList.add(propertyConstraint); } - return null; + return constraintList; } private static List findCurrentLevelConstraintsElement(Map toscaJson) { @@ -485,10 +486,13 @@ public final class ImportUtils { return result; } - public static InputDefinition createModuleInput(Map inputValue, - AnnotationTypeOperations annotationTypeOperations) { + public static InputDefinition createModuleInput(final Map inputValue, + final AnnotationTypeOperations annotationTypeOperations) { + return parseAnnotationsAndAddItToInput(createModuleInput(inputValue), inputValue, annotationTypeOperations); + } - InputDefinition inputDef = new InputDefinition(); + public static InputDefinition createModuleInput(final Map inputValue) { + final InputDefinition inputDef = new InputDefinition(); setField(inputValue, TypeUtils.ToscaTagNamesEnum.TYPE, inputDef::setType); setFieldBoolean(inputValue, ToscaTagNamesEnum.REQUIRED, req -> inputDef.setRequired(Boolean.parseBoolean(req))); setField(inputValue, TypeUtils.ToscaTagNamesEnum.DESCRIPTION, inputDef::setDescription); @@ -504,9 +508,7 @@ public final class ImportUtils { setScheme(inputValue, inputDef); setPropertyConstraints(inputValue, inputDef); - - return parseAnnotationsAndAddItToInput(inputDef, inputValue, annotationTypeOperations); - + return inputDef; } public static InputDefinition parseAnnotationsAndAddItToInput(InputDefinition inputDef, @@ -608,6 +610,11 @@ public final class ImportUtils { } + public static Either, ResultStatusEnum> getInputs(final Map toscaJson) { + return getElements(toscaJson, TypeUtils.ToscaTagNamesEnum.INPUTS, ImportUtils::createInputs, + ImportUtils::createModuleInput); + } + public static Either, ResultStatusEnum> getElements(Map toscaJson, TypeUtils.ToscaTagNamesEnum elementTagName, Function elementGenByName, diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandler.java new file mode 100644 index 0000000000..aeb4376c15 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandler.java @@ -0,0 +1,255 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.components.impl; + +import static org.openecomp.sdc.be.components.impl.ImportUtils.Constants.QUOTE; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DEFAULT; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DESCRIPTION; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.IMPLEMENTATION; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.INPUTS; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.NOTIFICATIONS; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.OPERATIONS; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.REQUIRED; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.STATUS; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TYPE; + +import fj.data.Either; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.stream.Collectors; +import org.apache.commons.collections.MapUtils; +import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; +import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.InputDataDefinition; +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.model.InterfaceDefinition; +import org.openecomp.sdc.be.tosca.utils.OperationArtifactUtil; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * Handles interface definition TOSCA conversions + */ +@Component("interfaceDefinitionHandler") +public class InterfaceDefinitionHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(InterfaceDefinitionHandler.class); + + private final InterfaceOperationBusinessLogic interfaceOperationBusinessLogic; + + public InterfaceDefinitionHandler(final InterfaceOperationBusinessLogic interfaceOperationBusinessLogic) { + this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic; + } + + /** + * Creates an interface definition based on a TOSCA map representing an interface definition. + * + * @param interfaceDefinitionToscaMap the TOSCA interface definition structure + * @return an interface definition representation + */ + public InterfaceDefinition create(final Map interfaceDefinitionToscaMap) { + + final InterfaceDefinition interfaceDefinition = new InterfaceDefinition(); + + if (interfaceDefinitionToscaMap.containsKey(TYPE.getElementName())) { + final Object typeObj = interfaceDefinitionToscaMap.get(TYPE.getElementName()); + if (!(typeObj instanceof String)) { + throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML); + } + final String type = (String) typeObj; + interfaceDefinition.setType(type); + interfaceDefinition.setUniqueId(type.toLowerCase()); + } + + final Map inputDefinitionMap = handleInputs(interfaceDefinitionToscaMap); + if (!inputDefinitionMap.isEmpty()) { + final Map collect = inputDefinitionMap.entrySet().stream(). + collect(Collectors.toMap(Entry::getKey, value -> new InputDataDefinition(value.getValue()))); + interfaceDefinition.setInputs(collect); + } + final Map operationMap; + if (interfaceDefinitionToscaMap.containsKey(OPERATIONS.getElementName()) || interfaceDefinitionToscaMap + .containsKey(NOTIFICATIONS.getElementName())) { + operationMap = handleOperations(interfaceDefinitionToscaMap); + //TODO handle notifications + } else { + operationMap = handleLegacyOperations(interfaceDefinitionToscaMap); + } + if (!operationMap.isEmpty()) { + validateOperations(interfaceDefinition.getType(), operationMap); + interfaceDefinition.setOperations(operationMap); + } + + return interfaceDefinition; + } + + private void validateOperations(final String interfaceType, + final Map operationMap) { + if (MapUtils.isEmpty(operationMap)) { + return; + } + Either, ResponseFormat> interfaceDefinitionMapEither = + interfaceOperationBusinessLogic.getAllInterfaceLifecycleTypes(); + if (interfaceDefinitionMapEither.isRight() || MapUtils.isEmpty(interfaceDefinitionMapEither.left().value())) { + throw new ByActionStatusComponentException(ActionStatus.INTERFACE_UNKNOWN, interfaceType); + } + + final Map interfaceDefinitionMap = interfaceDefinitionMapEither.left().value(); + final Optional interfaceDefinitionOptional = interfaceDefinitionMap.entrySet().stream() + .filter(interfaceDefinitionEntry -> interfaceDefinitionEntry.getKey().equalsIgnoreCase(interfaceType)) + .map(Entry::getValue).findFirst(); + if (interfaceDefinitionOptional.isEmpty()) { + throw new ByActionStatusComponentException(ActionStatus.INTERFACE_UNKNOWN, interfaceType); + } + final InterfaceDefinition interfaceDefinition = interfaceDefinitionOptional.get(); + operationMap.keySet().forEach(operation1 -> { + if (!interfaceDefinition.hasOperation(operation1)) { + throw new ByActionStatusComponentException(ActionStatus.INTERFACE_OPERATION_NOT_DEFINED, + operation1, interfaceType); + } + }); + } + + private Map handleOperations( + final Map interfaceDefinitionToscaMap) { + if (!interfaceDefinitionToscaMap.containsKey(OPERATIONS.getElementName())) { + return Collections.emptyMap(); + } + final Map operationMap = + (Map) interfaceDefinitionToscaMap.get(OPERATIONS.getElementName()); + return operationMap.entrySet().stream() + .map(interfaceEntry -> createOperation(interfaceEntry.getKey(), + (Map) interfaceEntry.getValue())) + .collect( + Collectors.toMap(OperationDataDefinition::getName, operationDataDefinition -> operationDataDefinition)); + } + + private Map handleLegacyOperations( + final Map interfaceDefinitionToscaMap) { + final List notALegacyOperationEntry = Arrays + .asList(OPERATIONS.getElementName(), + TYPE.getElementName(), + INPUTS.getElementName(), + NOTIFICATIONS.getElementName()); + return interfaceDefinitionToscaMap.entrySet().stream() + .filter(interfaceEntry -> !notALegacyOperationEntry.contains(interfaceEntry.getKey())) + .map(interfaceEntry -> createOperation(interfaceEntry.getKey(), + (Map) interfaceEntry.getValue())) + .collect( + Collectors.toMap(OperationDataDefinition::getName, operationDataDefinition -> operationDataDefinition)); + } + + + private OperationDataDefinition createOperation(final String operationName, + final Map operationDefinitionMap) { + final OperationDataDefinition operation = new OperationDataDefinition(); + operation.setName(operationName); + + handleOperationImplementation(operationDefinitionMap).ifPresent(operation::setImplementation); + if (operationDefinitionMap.containsKey(INPUTS.getElementName())) { + final Map interfaceInputs = + (Map) operationDefinitionMap.get(INPUTS.getElementName()); + operation.setInputs(handleInterfaceOperationInputs(interfaceInputs)); + } + + return operation; + } + + private ListDataDefinition handleInterfaceOperationInputs( + final Map interfaceInputs) { + final ListDataDefinition inputs = new ListDataDefinition<>(); + for (final Entry interfaceInput : interfaceInputs.entrySet()) { + final OperationInputDefinition operationInput = new OperationInputDefinition(); + operationInput.setName(interfaceInput.getKey()); + if (interfaceInput.getValue() instanceof Map) { + final LinkedHashMap inputPropertyValue = + (LinkedHashMap) interfaceInput.getValue(); + LOGGER.info("createModuleInterface: i interfaceInput.getKey() {}, {} , {} ", + interfaceInput.getKey(), inputPropertyValue.keySet(), inputPropertyValue.values()); + if (inputPropertyValue.get(TYPE.getElementName()) != null) { + operationInput.setType(inputPropertyValue.get(TYPE.getElementName()).toString()); + } + if (inputPropertyValue.get(DESCRIPTION.getElementName()) != null) { + operationInput.setDescription(inputPropertyValue.get(DESCRIPTION.getElementName()).toString()); + } + if (inputPropertyValue.get(REQUIRED.getElementName()) != null) { + operationInput.setRequired( + Boolean.getBoolean(inputPropertyValue.get(REQUIRED.getElementName()).toString())); + } + if (inputPropertyValue.get(DEFAULT.getElementName()) != null) { + operationInput.setToscaDefaultValue(inputPropertyValue.get(DEFAULT.getElementName()).toString()); + } + if (inputPropertyValue.get(STATUS.getElementName()) != null) { + operationInput.setStatus(inputPropertyValue.get(STATUS.getElementName()).toString()); + } + + } else if (interfaceInput.getValue() instanceof String) { + final String value = (String) interfaceInput.getValue(); + operationInput.setDefaultValue(value); + operationInput.setToscaDefaultValue(value); + operationInput.setValue(value); + } + inputs.add(operationInput); + } + return inputs; + } + + private Optional handleOperationImplementation( + final Map operationDefinitionMap) { + if (!operationDefinitionMap.containsKey(IMPLEMENTATION.getElementName())) { + return Optional.empty(); + } + final ArtifactDataDefinition artifactDataDefinition = new ArtifactDataDefinition(); + final String artifactName = (String) operationDefinitionMap.get(IMPLEMENTATION.getElementName()); + if (OperationArtifactUtil.artifactNameIsALiteralValue(artifactName)) { + artifactDataDefinition.setArtifactName(artifactName); + } else { + artifactDataDefinition.setArtifactName(QUOTE + artifactName + QUOTE); + } + return Optional.of(artifactDataDefinition); + } + + private Map handleInputs(final Map interfaceDefinitionToscaMap) { + if (!interfaceDefinitionToscaMap.containsKey(INPUTS.getElementName())) { + return Collections.emptyMap(); + } + + final Either, ResultStatusEnum> inputMapEither = + ImportUtils.getInputs(interfaceDefinitionToscaMap); + if (inputMapEither.isRight()) { + return Collections.emptyMap(); + } + + return inputMapEither.left().value(); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java index 7ff916df32..b96e4e58e2 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java @@ -22,7 +22,6 @@ package org.openecomp.sdc.be.components.impl; -import static org.openecomp.sdc.be.components.impl.ImportUtils.Constants.QUOTE; import static org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaElementOperation.createDataType; import static org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaElementOperation.createDataTypeDefinitionWithName; import static org.openecomp.sdc.be.utils.TypeUtils.setField; @@ -34,7 +33,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -62,11 +60,7 @@ import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; -import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; -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.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; @@ -94,7 +88,6 @@ import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; import org.openecomp.sdc.be.resources.data.auditing.model.CommonAuditData; import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo; import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo; -import org.openecomp.sdc.be.tosca.utils.OperationArtifactUtil; import org.openecomp.sdc.be.utils.TypeUtils; import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum; import org.openecomp.sdc.common.log.wrappers.Logger; @@ -112,13 +105,7 @@ public class ResourceImportManager { private static final Logger log = Logger.getLogger(ResourceImportManager.class); static final Pattern PROPERTY_NAME_PATTERN_IGNORE_LENGTH = Pattern.compile("[\\w\\-\\_\\d\\:]+"); - private static final String IMPLEMENTATION = "implementation"; - private static final String INPUTS = "inputs"; - private static final String TYPE = "type"; - private static final String DESCRIPTION = "description"; - private static final String REQUIRED = "required"; - private static final String DEFAULT = "default"; - private static final String STATUS = "status"; + private final InterfaceDefinitionHandler interfaceDefinitionHandler; private ServletContext servletContext; @@ -134,7 +121,6 @@ public class ResourceImportManager { @Autowired private ServiceBusinessLogic serviceBusinessLogic; - private InterfaceOperationBusinessLogic interfaceOperationBusinessLogic; private IGraphLockOperation graphLockOperation; private ToscaOperationFacade toscaOperationFacade; @@ -145,9 +131,11 @@ public class ResourceImportManager { private ResponseFormatManager responseFormatManager; @Autowired - public ResourceImportManager(ComponentsUtils componentsUtils, CapabilityTypeOperation capabilityTypeOperation) { + public ResourceImportManager(ComponentsUtils componentsUtils, CapabilityTypeOperation capabilityTypeOperation, + final InterfaceDefinitionHandler interfaceDefinitionHandler) { this.componentsUtils = componentsUtils; this.capabilityTypeOperation = capabilityTypeOperation; + this.interfaceDefinitionHandler = interfaceDefinitionHandler; } @Autowired @@ -380,11 +368,9 @@ public class ResourceImportManager { if (toscaInterfaces.isLeft()) { Map jsonInterfaces = toscaInterfaces.left().value(); Map moduleInterfaces = new HashMap<>(); - Iterator> interfacesNameValue = jsonInterfaces.entrySet().iterator(); - while (interfacesNameValue.hasNext()) { - Entry interfaceNameValue = interfacesNameValue.next(); - Either eitherInterface = createModuleInterface(interfaceNameValue - .getValue(), resource); + for (final Entry interfaceNameValue : jsonInterfaces.entrySet()) { + final Either eitherInterface = + createModuleInterface(interfaceNameValue.getValue()); if (eitherInterface.isRight()) { log.info("error when creating interface:{}, for resource:{}", interfaceNameValue.getKey(), resource.getName()); @@ -393,165 +379,32 @@ public class ResourceImportManager { } } - if (moduleInterfaces.size() > 0) { + if (!moduleInterfaces.isEmpty()) { resource.setInterfaces(moduleInterfaces); } } } - private Either createModuleInterface(Object interfaceJson, - Resource resource) { - final InterfaceDefinition interf = new InterfaceDefinition(); - Either result = Either.left(interf); - + private Either createModuleInterface(final Object interfaceJson) { try { if (interfaceJson instanceof String) { - final String requirementJsonString = (String) interfaceJson; - interf.setType(requirementJsonString); - } else if (interfaceJson instanceof Map && ResourceTypeEnum.VFC.equals(resource.getResourceType())) { - final Map requirementJsonMap = (Map) interfaceJson; - final Map operations = new HashMap<>(); - - for (final Entry entry : requirementJsonMap.entrySet()) { - if (entryIsInterfaceType(entry)) { - final String type = (String) requirementJsonMap - .get(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName()); - interf.setType(type); - interf.setUniqueId(type.toLowerCase()); - } else if (entryContainsImplementationForAKnownOperation(entry, interf.getType())) { - - final OperationDataDefinition operation = new OperationDataDefinition(); - operation.setName(entry.getKey()); - - final Map entryValue = (Map) entry.getValue(); - if (entryValue.containsKey(IMPLEMENTATION)) { - operation.setImplementation(handleOperationImplementation(entry)); - } - if (entryValue.containsKey(INPUTS)) { - final Map interfaceInputs = (Map) entryValue - .get(ToscaTagNamesEnum.INPUTS.getElementName()); - operation.setInputs(handleInterfaceInput(interfaceInputs)); - } - operations.put(entry.getKey(), operation); - } - } - if (!operations.isEmpty()) { - interf.setOperations(operations); - } - } else { - result = Either.right(ResultStatusEnum.GENERAL_ERROR); - } - - } catch (Exception e) { - BeEcompErrorManager.getInstance().logBeSystemError("Import Resource- create interface"); - log.debug("error when creating interface, message:{}", e.getMessage(), e); - result = Either.right(ResultStatusEnum.GENERAL_ERROR); - } - - return result; - } - - private ArtifactDataDefinition handleOperationImplementation(final Entry entry) { - final ArtifactDataDefinition implementation = new ArtifactDataDefinition(); - final String artifactName = ((Map) entry.getValue()).get(IMPLEMENTATION); - if (OperationArtifactUtil.artifactNameIsALiteralValue(artifactName)) { - implementation.setArtifactName(artifactName); - } else { - implementation.setArtifactName(QUOTE + artifactName + QUOTE); - } - return implementation; - } - - private ListDataDefinition handleInterfaceInput( - final Map interfaceInputs) { - final ListDataDefinition inputs = new ListDataDefinition<>(); - for (final Entry interfaceInput : interfaceInputs.entrySet()) { - final OperationInputDefinition operationInput = new OperationInputDefinition(); - operationInput.setName(interfaceInput.getKey()); - if (interfaceInput.getValue() instanceof Map) { - final LinkedHashMap inputPropertyValue = - (LinkedHashMap) interfaceInput.getValue(); - log.info("createModuleInterface: i interfaceInput.getKey() {}, {} , {} ", - interfaceInput.getKey(), inputPropertyValue.keySet(), - inputPropertyValue.values()); - if (inputPropertyValue.get(TYPE) != null) { - operationInput.setType(inputPropertyValue.get(TYPE).toString()); - } - if (inputPropertyValue.get(DESCRIPTION) != null) { - operationInput.setDescription(inputPropertyValue.get(DESCRIPTION).toString()); - } - if (inputPropertyValue.get(REQUIRED) != null) { - operationInput.setRequired( - Boolean.getBoolean(inputPropertyValue.get(REQUIRED).toString())); - } - if (inputPropertyValue.get(DEFAULT) != null) { - operationInput.setToscaDefaultValue(inputPropertyValue.get(DEFAULT).toString()); - } - if (inputPropertyValue.get(STATUS) != null) { - operationInput.setStatus(inputPropertyValue.get(STATUS).toString()); - } - - } else if (interfaceInput.getValue() instanceof String) { - final String value = (String) interfaceInput.getValue(); - operationInput.setDefaultValue(value); - operationInput.setToscaDefaultValue(value); - operationInput.setValue(value); + final InterfaceDefinition interfaceDefinition = new InterfaceDefinition(); + interfaceDefinition.setType((String) interfaceJson); + return Either.left(interfaceDefinition); } - inputs.getListToscaDataDefinition().add(operationInput); - inputs.add(operationInput); - } - return inputs; - } - private boolean entryIsInterfaceType(final Entry entry) { - if(entry.getKey().equals(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName())) { - if (entry.getValue() instanceof String) { - return true; + if (interfaceJson instanceof Map) { + final Map interfaceJsonMap = (Map) interfaceJson; + final InterfaceDefinition interfaceDefinition = interfaceDefinitionHandler.create(interfaceJsonMap); + return Either.left(interfaceDefinition); } - throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML); - } - return false; - } - - private boolean entryContainsImplementationForAKnownOperation(final Entry entry, - final String interfaceType) { - if (entry.getValue() instanceof Map && ((Map)entry.getValue()).containsKey(IMPLEMENTATION)) { - if (isAKnownOperation(interfaceType, entry.getKey())){ - return true; - } - throw new ByActionStatusComponentException(ActionStatus.INTERFACE_OPERATION_NOT_FOUND); - } - return false; - } - - private boolean isAKnownOperation(String interfaceType, String operation) { - Either, ResponseFormat> interfaceLifecycleTypes = interfaceOperationBusinessLogic - .getAllInterfaceLifecycleTypes(); - if (interfaceLifecycleTypes.isRight() || interfaceLifecycleTypes.left().value() == null) { - return false; - } - for (Entry interfaceLifecycleType : interfaceLifecycleTypes.left().value() - .entrySet()) { - if (interfaceTypeAndOperationMatches(interfaceLifecycleType, interfaceType, operation)) { - return true; - } - } - return false; - } - - private boolean interfaceTypeAndOperationMatches(Entry interfaceLifecycleType, - String interfaceType, String operation) { - if (interfaceLifecycleType.getKey().equalsIgnoreCase(interfaceType) - && interfaceLifecycleType.getValue().getOperations() != null) { - for (String interfaceLifecycleTypeOperation : interfaceLifecycleType.getValue().getOperations().keySet()) { - if (interfaceLifecycleTypeOperation != null && interfaceLifecycleTypeOperation - .equalsIgnoreCase(operation)) { - return true; - } - } + return Either.right(ResultStatusEnum.GENERAL_ERROR); + } catch (final Exception e) { + BeEcompErrorManager.getInstance().logBeSystemError("Import Resource- create interface"); + log.debug("error when creating interface, message:{}", e.getMessage(), e); + return Either.right(ResultStatusEnum.GENERAL_ERROR); } - return false; } private void setRequirements(Map toscaJson, Resource resource, @@ -1165,11 +1018,6 @@ public class ResourceImportManager { this.resourceBusinessLogic = resourceBusinessLogic; } - @Autowired - public void setInterfaceOperationBusinessLogic(InterfaceOperationBusinessLogic interfaceOperationBusinessLogic) { - this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic; - } - public IGraphLockOperation getGraphLockOperation() { return graphLockOperation; } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverter.java index 9e9d834691..1f1dcfed8c 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverter.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverter.java @@ -16,10 +16,21 @@ package org.openecomp.sdc.be.tosca; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DEFAULT; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.INPUTS; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.OPERATIONS; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; import org.apache.commons.collections.MapUtils; +import org.openecomp.sdc.be.datatypes.elements.InputDataDefinition; import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; import org.openecomp.sdc.be.model.Component; @@ -27,30 +38,27 @@ import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.Product; -import org.openecomp.sdc.tosca.datatypes.ToscaFunctions; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType; +import org.openecomp.sdc.be.tosca.model.ToscaInput; import org.openecomp.sdc.be.tosca.model.ToscaInterfaceDefinition; import org.openecomp.sdc.be.tosca.model.ToscaInterfaceNodeType; 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.utils.OperationArtifactUtil; +import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum; +import org.openecomp.sdc.tosca.datatypes.ToscaFunctions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - @Service public class InterfacesOperationsConverter { private static final String DERIVED_FROM_STANDARD_INTERFACE = "tosca.interfaces.node.lifecycle.Standard"; private static final String DERIVED_FROM_BASE_DEFAULT = "org.openecomp.interfaces.node.lifecycle."; - private static final String OPERATIONS_KEY = "operations"; - private static final String DEFAULT = "default"; private static final String DEFAULT_HAS_UNDERSCORE = "_default"; private static final String DOT = "."; private static final String DEFAULTP = "defaultp"; @@ -58,10 +66,10 @@ public class InterfacesOperationsConverter { public static final String SELF = "SELF"; private static final String LOCAL_INTERFACE_TYPE = "Local"; - private PropertyConvertor propertyConvertor; + private final PropertyConvertor propertyConvertor; @Autowired - public InterfacesOperationsConverter(PropertyConvertor propertyConvertor) { + public InterfacesOperationsConverter(final PropertyConvertor propertyConvertor) { this.propertyConvertor = propertyConvertor; } @@ -96,7 +104,7 @@ public class InterfacesOperationsConverter { } toscaInterfaceType.setOperations(toscaOperations); Map interfacesAsMap = getObjectAsMap(toscaInterfaceType); - Map operationsMap = (Map) interfacesAsMap.remove(OPERATIONS_KEY); + Map operationsMap = (Map) interfacesAsMap.remove(OPERATIONS.getElementName()); interfacesAsMap.putAll(operationsMap); toscaInterfaceTypes.put(getInterfaceType(component, LOCAL_INTERFACE_TYPE), interfacesAsMap); @@ -134,12 +142,12 @@ public class InterfacesOperationsConverter { return getInterfacesMap(component, null, component.getInterfaces(), dataTypes, isAssociatedComponent, false); } - public Map getInterfacesMap(Component component, - ComponentInstance componentInstance, - Map interfaces, - Map dataTypes, - boolean isAssociatedComponent, - boolean isServiceProxyInterface) { + public Map getInterfacesMap(final Component component, + final ComponentInstance componentInstance, + final Map interfaces, + final Map dataTypes, + final boolean isAssociatedComponent, + final boolean isServiceProxyInterface) { if(MapUtils.isEmpty(interfaces)) { return null; } @@ -155,7 +163,7 @@ public class InterfacesOperationsConverter { } toscaInterfaceDefinition.setType(interfaceType); final Map operations = interfaceDefinition.getOperations(); - Map toscaOperations = new HashMap<>(); + Map toscaOperationMap = new HashMap<>(); String operationArtifactPath; for (Map.Entry operationEntry : operations.entrySet()) { @@ -169,12 +177,20 @@ public class InterfacesOperationsConverter { toscaOperation.setDescription(operationEntry.getValue().getDescription()); fillToscaOperationInputs(operationEntry.getValue(), dataTypes, toscaOperation, isServiceProxyInterface); - toscaOperations.put(operationEntry.getValue().getName(), toscaOperation); + toscaOperationMap.put(operationEntry.getValue().getName(), toscaOperation); + } + toscaInterfaceDefinition.setOperations(toscaOperationMap); + + final Map interfaceInputMap = createInterfaceInputMap(interfaceDefinition, dataTypes); + if (!interfaceInputMap.isEmpty()) { + toscaInterfaceDefinition.setInputs(interfaceInputMap); } - toscaInterfaceDefinition.setOperations(toscaOperations); Map interfaceDefAsMap = getObjectAsMap(toscaInterfaceDefinition); - Map operationsMap = (Map) interfaceDefAsMap.remove(OPERATIONS_KEY); + if (interfaceDefAsMap.containsKey(INPUTS.getElementName())) { + handleDefaults((Map) interfaceDefAsMap.get(INPUTS.getElementName())); + } + Map operationsMap = (Map) interfaceDefAsMap.remove(OPERATIONS.getElementName()); if (isServiceProxyInterface) { //Remove input type and copy default value directly into the proxy node template from the node type handleServiceProxyOperationInputValue(operationsMap, interfaceType); @@ -188,6 +204,22 @@ public class InterfacesOperationsConverter { return toscaInterfaceDefinitions; } + private Map createInterfaceInputMap(final InterfaceDefinition interfaceDefinition, + final Map allDataTypeMap) { + final Map inputMap = interfaceDefinition.getInputs(); + if (MapUtils.isEmpty(inputMap)) { + return Collections.emptyMap(); + } + final Map toscaInterfaceInputMap = new HashMap<>(); + for (final Entry inputEntry : inputMap.entrySet()) { + final InputDataDefinition inputDataDefinition = inputEntry.getValue(); + final ToscaProperty toscaProperty = propertyConvertor + .convertProperty(allDataTypeMap, new PropertyDefinition(inputDataDefinition), PropertyType.INPUT); + toscaInterfaceInputMap.put(inputEntry.getKey(), new ToscaInput(toscaProperty)); + } + return toscaInterfaceInputMap; + } + private static void handleServiceProxyOperationInputValue(Map operationsMap, String parentKey) { for (Map.Entry operationEntry : operationsMap.entrySet()) { final Object value = operationEntry.getValue(); @@ -223,7 +255,7 @@ public class InterfacesOperationsConverter { * ToscaExportHandler so, any string Map key named "defaultp" will have its named changed to "default" * @param operationsMap the map to update */ - private static void handleDefaults(Map operationsMap) { + private void handleDefaults(Map operationsMap) { for (Map.Entry operationEntry : operationsMap.entrySet()) { final Object value = operationEntry.getValue(); if (value instanceof Map) { @@ -232,7 +264,7 @@ public class InterfacesOperationsConverter { final String key = operationEntry.getKey(); if (key.equals(DEFAULTP)) { Object removed = operationsMap.remove(key); - operationsMap.put(DEFAULT, removed); + operationsMap.put(ToscaTagNamesEnum.DEFAULT.getElementName(), removed); } } } @@ -314,10 +346,9 @@ public class InterfacesOperationsConverter { Map objectAsMap = obj instanceof Map ? (Map) obj : objectMapper.convertValue(obj, Map.class); - if (objectAsMap.containsKey(DEFAULT)) { - Object defaultValue = objectAsMap.get(DEFAULT); - objectAsMap.remove(DEFAULT); - objectAsMap.put(DEFAULT_HAS_UNDERSCORE, defaultValue); + final String defaultEntry = DEFAULT.getElementName(); + if (objectAsMap.containsKey(defaultEntry)) { + objectAsMap.put(DEFAULT_HAS_UNDERSCORE, objectAsMap.remove(defaultEntry)); } return objectAsMap; } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaInterfaceDefinition.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaInterfaceDefinition.java index 1d444e697a..2f4a3d8ac1 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaInterfaceDefinition.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaInterfaceDefinition.java @@ -16,35 +16,20 @@ package org.openecomp.sdc.be.tosca.model; import java.util.Map; +import lombok.Getter; +import lombok.Setter; /** * @author KATYR * @since March 26, 2018 */ - +@Setter +@Getter public class ToscaInterfaceDefinition { private String type; - private Map operations; // ToscaLifecycleOperationDefinition <-> Object - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public Map getOperations() { - return operations; - } - -// public void setOperations(Map operations) { -// this.operations = operations; -// } + private Map operations; + private Map inputs; - public void setOperations(Map toscaOperations) { - this.operations = toscaOperations; - } } diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml index 14b4ece4b0..96bfa245e3 100644 --- a/catalog-be/src/main/resources/config/error-configuration.yaml +++ b/catalog-be/src/main/resources/config/error-configuration.yaml @@ -2060,6 +2060,18 @@ errors: message: "Error: Failed to delete interface operation.", messageId: "SVC4702" } + #SVC4732 + INTERFACE_UNKNOWN: { + code: 400, + message: "Error: The interface '%1' does not exists in the database.", + messageId: "SVC4732" + } + #SVC4733 + INTERFACE_OPERATION_NOT_DEFINED: { + code: 400, + message: "Error: The operation '%1' does not exists in the interface '%2'.", + messageId: "SVC4733" + } #-----------SVC4692--------------------------- RESOURCE_LIFECYCLE_STATE_NOT_VALID: { code: 400, diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/ResourceImportManagerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/ResourceImportManagerTest.java index b497253118..336b8ec940 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/ResourceImportManagerTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/ResourceImportManagerTest.java @@ -22,7 +22,20 @@ package org.openecomp.sdc.be.components; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + import fj.data.Either; +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.apache.commons.lang3.tuple.ImmutablePair; import org.junit.Before; import org.junit.BeforeClass; @@ -32,6 +45,7 @@ import org.mockito.stubbing.Answer; import org.openecomp.sdc.be.auditing.impl.AuditingManager; import org.openecomp.sdc.be.components.impl.ImportUtils; import org.openecomp.sdc.be.components.impl.ImportUtilsTest; +import org.openecomp.sdc.be.components.impl.InterfaceDefinitionHandler; import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceImportManager; @@ -63,27 +77,15 @@ import org.openecomp.sdc.common.impl.FSConfigurationSource; import org.openecomp.sdc.exception.PolicyException; import org.openecomp.sdc.exception.ResponseFormat; -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.when; - public class ResourceImportManagerTest { - private static ConfigurationManager configurationManager; static ResourceImportManager importManager; static AuditingManager auditingManager = Mockito.mock(AuditingManager.class); static ResponseFormatManager responseFormatManager = Mockito.mock(ResponseFormatManager.class); static ResourceBusinessLogic resourceBusinessLogic = Mockito.mock(ResourceBusinessLogic.class); static InterfaceOperationBusinessLogic interfaceOperationBusinessLogic = Mockito.mock(InterfaceOperationBusinessLogic.class); + static InterfaceDefinitionHandler interfaceDefinitionHandler = + new InterfaceDefinitionHandler(interfaceOperationBusinessLogic); static UserBusinessLogic userAdmin = Mockito.mock(UserBusinessLogic.class); static ToscaOperationFacade toscaOperationFacade = Mockito.mock(ToscaOperationFacade.class); @@ -93,17 +95,16 @@ public class ResourceImportManagerTest { @BeforeClass public static void beforeClass() { - importManager = new ResourceImportManager(componentsUtils, capabilityTypeOperation); + importManager = new ResourceImportManager(componentsUtils, capabilityTypeOperation, interfaceDefinitionHandler); importManager.setAuditingManager(auditingManager); when(toscaOperationFacade.getLatestByToscaResourceName(Mockito.anyString())).thenReturn(Either.left(null)); importManager.setResponseFormatManager(responseFormatManager); importManager.setResourceBusinessLogic(resourceBusinessLogic); - importManager.setInterfaceOperationBusinessLogic(interfaceOperationBusinessLogic); importManager.setToscaOperationFacade(toscaOperationFacade); String appConfigDir = "src/test/resources/config/catalog-be"; ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), appConfigDir); - configurationManager = new ConfigurationManager(configurationSource); + final ConfigurationManager configurationManager = new ConfigurationManager(configurationSource); Configuration configuration = new Configuration(); configuration.setJanusGraphInMemoryGraph(true); @@ -223,8 +224,9 @@ public class ResourceImportManagerTest { interfaceTypes.put("tosca.interfaces.node.lifecycle.standard", interfaceDefinition); when(interfaceOperationBusinessLogic.getAllInterfaceLifecycleTypes()).thenReturn(Either.left(interfaceTypes)); - ImmutablePair createResource = importManager.importNormativeResource(jsonContent, resourceMD, user, true, true); - testSetInterfaceImplementation(createResource.left); + final ImmutablePair createResource = importManager + .importNormativeResource(jsonContent, resourceMD, user, true, true); + assertSetInterfaceImplementation(createResource.left); } @Test @@ -342,12 +344,12 @@ public class ResourceImportManagerTest { assertTrue(properties.containsKey("volume_id")); propertyDefinition = properties.get("volume_id"); assertEquals("string", propertyDefinition.getType()); - assertTrue(!propertyDefinition.isRequired()); + assertFalse(propertyDefinition.isRequired()); assertTrue(properties.containsKey("snapshot_id")); propertyDefinition = properties.get("snapshot_id"); assertEquals("string", propertyDefinition.getType()); - assertTrue(!propertyDefinition.isRequired()); + assertFalse(propertyDefinition.isRequired()); } @@ -398,20 +400,19 @@ public class ResourceImportManagerTest { } - private void testSetInterfaceImplementation(Resource resource) { - Map interfaces = resource.getInterfaces(); + private void assertSetInterfaceImplementation(final Resource resource) { + final Map interfaces = resource.getInterfaces(); assertEquals(1, interfaces.size()); assertTrue(interfaces.containsKey("Standard")); - - InterfaceDefinition interfaceDefinition = interfaces.get("Standard"); + + final InterfaceDefinition interfaceDefinition = interfaces.get("Standard"); assertEquals("tosca.interfaces.node.lifecycle.Standard", interfaceDefinition.getType()); assertEquals("tosca.interfaces.node.lifecycle.standard", interfaceDefinition.getUniqueId()); - Map operations = interfaceDefinition.getOperations(); + final Map operations = interfaceDefinition.getOperations(); assertEquals(1, operations.size()); - OperationDataDefinition operation = operations.get("configure"); + final OperationDataDefinition operation = operations.get("configure"); assertEquals("'camunda/vnfConfigure'", operation.getImplementation().getArtifactName()); - } private void testSetDerivedFrom(Resource resource) { @@ -421,19 +422,12 @@ public class ResourceImportManagerTest { } private void testSetMetaDataFromJson(Resource resource, UploadResourceInfo resourceMD) { - - // assertTrue( resource.getCategory().equals(resourceMD.getCategory()) - // ); assertEquals(resource.getDescription(), resourceMD.getDescription()); assertEquals(resource.getIcon(), resourceMD.getResourceIconPath()); assertEquals(resource.getName(), resourceMD.getName()); assertEquals(resource.getResourceVendorModelNumber(), resourceMD.getResourceVendorModelNumber()); assertEquals(resource.getContactId(), resourceMD.getContactId()); assertEquals(resource.getCreatorUserId(), resourceMD.getContactId()); - - // assertTrue( resource.isAbstract() == - // Constants.ABSTRACT_CATEGORY.equals(resourceMD.getCategory())); - assertEquals(resourceMD.getTags().size(), resource.getTags().size()); for (String tag : resource.getTags()) { assertTrue(resourceMD.getTags().contains(tag)); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ImportUtilsTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ImportUtilsTest.java index 87875d8f20..9cd095b5b5 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ImportUtilsTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ImportUtilsTest.java @@ -324,7 +324,7 @@ public class ImportUtilsTest { PropertyDefinition property = properties.get("service_type"); assertTrue(property.getConstraints()!= null && property.getConstraints().size() == 1); assertTrue(property.getConstraints().get(0) instanceof ValidValuesConstraint); - assertTrue(((ValidValuesConstraint) property.getConstraints().get(0)).getValidValues() != null); + assertNotNull(((ValidValuesConstraint) property.getConstraints().get(0)).getValidValues()); List validValues = ((ValidValuesConstraint) property.getConstraints().get(0)).getValidValues(); assertTrue(validValues.containsAll(Lists.newArrayList("firewall", "analyzer", "source-nat", "loadbalancer"))); @@ -334,7 +334,7 @@ public class ImportUtilsTest { PropertyDefinition innerProperty = new PropertyDefinition(property.getSchema().getProperty()); List innerConstraints = innerProperty.getConstraints(); assertTrue(innerConstraints.get(0) instanceof ValidValuesConstraint); - assertTrue(((ValidValuesConstraint) innerConstraints.get(0)).getValidValues() != null); + assertNotNull(((ValidValuesConstraint) innerConstraints.get(0)).getValidValues()); validValues = ((ValidValuesConstraint) innerConstraints.get(0)).getValidValues(); assertTrue(validValues.containsAll(Lists.newArrayList("management", "left", "right", "other"))); } @@ -352,6 +352,10 @@ public class ImportUtilsTest { Map> expectedProperties = getElements(toscaJson, TypeUtils.ToscaTagNamesEnum.INPUTS); compareProperties(expectedProperties, actualInputs.left().value()); + actualInputs = ImportUtils.getInputs(toscaJson); + assertTrue(actualInputs.isLeft()); + expectedProperties = getElements(toscaJson, TypeUtils.ToscaTagNamesEnum.INPUTS); + compareProperties(expectedProperties, actualInputs.left().value()); } private void compareAttributes(Map> expected, Map actual) { diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandlerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandlerTest.java new file mode 100644 index 0000000000..f819eceb43 --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandlerTest.java @@ -0,0 +1,174 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.components.impl; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.aMapWithSize; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.hasSize; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.Mockito.when; + +import fj.data.Either; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.apache.commons.collections.MapUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.InputDataDefinition; +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.InterfaceDefinition; +import org.yaml.snakeyaml.Yaml; + +@ExtendWith(MockitoExtension.class) +class InterfaceDefinitionHandlerTest { + + @Mock + private InterfaceOperationBusinessLogic interfaceOperationBusinessLogic; + private InterfaceDefinitionHandler interfaceDefinitionHandler; + private InterfaceDefinition interfaceLifecyleStandard; + private static final Path TEST_RESOURCE_PATH = Paths.get("src/test/resources/interfaceDefinition"); + private static final String CREATE_OPERATION = "create"; + private static final String DELETE_OPERATION = "delete"; + private static final String START_OPERATION = "start"; + private static final String STOP_OPERATION = "stop"; + private static final String INTERFACE_TYPE = "tosca.interfaces.node.lifecycle.Standard"; + + @BeforeEach + void setUp() { + interfaceDefinitionHandler = new InterfaceDefinitionHandler(interfaceOperationBusinessLogic); + mockAllInterfacesLifecycle(); + } + + private void mockAllInterfacesLifecycle() { + final Map interfaceTypes = new HashMap<>(); + interfaceLifecyleStandard = new InterfaceDefinition(); + interfaceLifecyleStandard.setType(INTERFACE_TYPE); + final Map operations = new HashMap<>(); + operations.put(CREATE_OPERATION, new OperationDataDefinition()); + operations.put(START_OPERATION, new OperationDataDefinition()); + operations.put(STOP_OPERATION, new OperationDataDefinition()); + operations.put(DELETE_OPERATION, new OperationDataDefinition()); + interfaceLifecyleStandard.setOperations(operations); + interfaceTypes.put(INTERFACE_TYPE, interfaceLifecyleStandard); + when(interfaceOperationBusinessLogic.getAllInterfaceLifecycleTypes()).thenReturn(Either.left(interfaceTypes)); + } + + @Test + void testCreateWithLegacyOperationDeclarationSuccess() throws FileNotFoundException { + final Map load = loadYaml(Paths.get("interfaceDefinition-legacy.yaml")); + final InterfaceDefinition actualInterfaceDefinition = interfaceDefinitionHandler.create(load); + assertInterfaceDefinition(actualInterfaceDefinition); + } + + @Test + void testCreateWithOperationSuccess() throws FileNotFoundException { + final Map load = loadYaml(Paths.get("interfaceDefinition-tosca1.3.yaml")); + final InterfaceDefinition actualInterfaceDefinition = interfaceDefinitionHandler.create(load); + assertInterfaceDefinition(actualInterfaceDefinition); + } + + private void assertInterfaceDefinition(final InterfaceDefinition actualInterfaceDefinition) { + interfaceLifecyleStandard.getOperations().keySet().forEach(operation -> + assertTrue(actualInterfaceDefinition.hasOperation(operation))); + assertThat("Interface type should be as expected", actualInterfaceDefinition.getType(), + equalTo(actualInterfaceDefinition.getType())); + assertThat("Interface should contain 2 inputs", actualInterfaceDefinition.getInputs(), aMapWithSize(2)); + assertThat("Interface inputs should be as expected", actualInterfaceDefinition.getInputs().keySet(), + containsInAnyOrder("stringInput", "actionInput")); + + final InputDataDefinition stringInput = actualInterfaceDefinition.getInputs().get("stringInput"); + assertInput("string", "stringInput description", true, "defaultValue", "aStatus", stringInput); + final InputDataDefinition actionInput = actualInterfaceDefinition.getInputs().get("actionInput"); + assertInput("org.openecomp.resource.datatypes.Action", null, false, null, null, actionInput); + + final OperationDataDefinition createOperation = actualInterfaceDefinition.getOperations().get(CREATE_OPERATION); + assertOperation("'camunda/serviceSelect'", createOperation); + + final OperationDataDefinition deleteOperation = actualInterfaceDefinition.getOperations().get(DELETE_OPERATION); + assertOperation("'camunda/serviceDeselect'", deleteOperation); + + final Map expectedInputMap = new HashMap<>(); + expectedInputMap.put("action", "org.openecomp.resource.datatypes.Action"); + final OperationDataDefinition startOperation = actualInterfaceDefinition.getOperations().get(START_OPERATION); + assertOperation("'camunda/executeAction'", expectedInputMap, startOperation); + final OperationDataDefinition stopOperation = actualInterfaceDefinition.getOperations().get(STOP_OPERATION); + assertOperation("'camunda/executeAction'", expectedInputMap, stopOperation); + } + + private void assertOperation(final String implementation, final OperationDataDefinition actualOperation) { + assertOperation(implementation, Collections.emptyMap(), actualOperation); + } + + private void assertOperation(final String implementation, final Map inputNameTypeMap, + final OperationDataDefinition actualOperation) { + final ArtifactDataDefinition artifactDefinition = actualOperation.getImplementation(); + assertThat("Implementation should be as expected", artifactDefinition.getArtifactName(), equalTo(implementation)); + final ListDataDefinition inputListDataDef = actualOperation.getInputs(); + if (inputListDataDef == null) { + if (MapUtils.isNotEmpty(inputNameTypeMap)) { + final String expectedInputNames = String.join(",", inputNameTypeMap.keySet()); + fail(String.format("No inputs were found, but some inputs are expected: %s", expectedInputNames)); + } + return; + } + + final String msgFormat = "Operation should have %s"; + final List inputList = inputListDataDef.getListToscaDataDefinition(); + assertThat(String.format(msgFormat, "the expected quantity of inputs"), inputList, hasSize(inputNameTypeMap.size())); + + final List inputNames = inputList.stream() + .map(OperationInputDefinition::getName).collect(Collectors.toList()); + + assertThat(String.format(msgFormat, "the expected inputs"), inputNames, + hasItems(inputNameTypeMap.keySet().toArray(new String[0]))); + } + + private void assertInput(final String type, final String description, final Boolean required, + final String defaultValue, final String status, final InputDataDefinition actualInput) { + assertThat("Input type should be as expected", type, equalTo(actualInput.getType())); + assertThat("Input description should be as expected", description, equalTo(actualInput.getDescription())); + assertThat("Input required should be as expected", required, equalTo(required != null && required)); + assertThat("Input default should be as expected", defaultValue, equalTo(actualInput.getDefaultValue())); + assertThat("Input status should be as expected", status, equalTo(actualInput.getStatus())); + } + + private Map loadYaml(final Path filePathFromResource) throws FileNotFoundException { + final Path filePath = Paths.get(TEST_RESOURCE_PATH.toString(), filePathFromResource.toString()); + final FileInputStream fileInputStream = new FileInputStream(filePath.toString()); + return (Map) new Yaml().load(fileInputStream); + } +} \ No newline at end of file diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverterTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverterTest.java new file mode 100644 index 0000000000..0281317b89 --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/InterfacesOperationsConverterTest.java @@ -0,0 +1,669 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.tosca; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.openecomp.sdc.be.tosca.InterfacesOperationsConverter.SELF; +import static org.openecomp.sdc.be.tosca.InterfacesOperationsConverter.addInterfaceTypeElement; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DEFAULT; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DESCRIPTION; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.INPUTS; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.INTERFACES; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.NODE_TYPES; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.REQUIRED; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TYPE; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; +import org.apache.commons.collections4.MapUtils; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.sdc.tosca.services.YamlUtil; +import org.openecomp.sdc.be.DummyConfigurationManager; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.InputDataDefinition; +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.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.DataTypeDefinition; +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.model.ServiceMetadataDefinition; +import org.openecomp.sdc.be.tosca.model.ToscaNodeType; +import org.openecomp.sdc.be.tosca.model.ToscaTemplate; +import org.openecomp.sdc.common.util.YamlToObjectConverter; +import org.openecomp.sdc.tosca.datatypes.ToscaFunctions; +import org.yaml.snakeyaml.Yaml; + +class InterfacesOperationsConverterTest { + + 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 final String[] inputTypes = {"string", "integer", "float", "boolean"}; + private static ObjectMapper mapper; + private static final Map dataTypes = new HashMap<>(); + + private InterfacesOperationsConverter interfacesOperationsConverter; + + @BeforeAll + public static void setUp() { + //initialize the static configuration manager + new DummyConfigurationManager(); + mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + + @BeforeEach + public void setUpBeforeTest() { + interfacesOperationsConverter = + new InterfacesOperationsConverter(new PropertyConvertor()); + } + + @Test + void addInterfaceTypeElementToResource() { + Component component = new Resource(); + component.setNormalizedName("normalizedComponentName"); + component.setComponentMetadataDefinition(new ServiceMetadataDefinition()); + component.getComponentMetadataDefinition().getMetadataDataDefinition().setName("NodeTypeName"); + component.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName("NodeTypeName"); + InterfaceDefinition addedInterface = new InterfaceDefinition(); + addedInterface.setType("Local"); + addOperationsToInterface(component, addedInterface, 5, 3, true, false); + final String interfaceType = "normalizedComponentName-interface"; + component.setInterfaces(new HashMap<>()); + component.getInterfaces().put(interfaceType, addedInterface); + final Map interfaceTypeElement = + addInterfaceTypeElement(component, new ArrayList<>()); + + ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, + interfacesOperationsConverter); + ToscaTemplate template = new ToscaTemplate("test"); + template.setInterface_types(interfaceTypeElement); + final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); + + assertTrue(all( + containsAll("NodeTypeName"), + containsNone("operations") + ).apply(new String(toscaRepresentation.getMainYaml()))); + } + + @Test + void addInterfaceTypeElementToService() { + Component component = new Service(); + component.setNormalizedName("normalizedServiceComponentName"); + component.setComponentMetadataDefinition(new ServiceMetadataDefinition()); + component.getComponentMetadataDefinition().getMetadataDataDefinition().setName("NodeTypeName"); + component.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName("NodeTypeName"); + InterfaceDefinition addedInterface = new InterfaceDefinition(); + addedInterface.setType("Local"); + addOperationsToInterface(component, addedInterface, 5, 3, true, false); + final String interfaceType = "normalizedServiceComponentName-interface"; + component.setInterfaces(new HashMap<>()); + component.getInterfaces().put(interfaceType, addedInterface); + final Map interfaceTypeElement = + addInterfaceTypeElement(component, new ArrayList<>()); + + ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, + interfacesOperationsConverter); + ToscaTemplate template = new ToscaTemplate("testService"); + template.setInterface_types(interfaceTypeElement); + final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); + + assertTrue(all( + containsAll("NodeTypeName"), + containsNone("operations") + ).apply(new String(toscaRepresentation.getMainYaml()))); + } + + @Test + void addInterfaceDefinitionElementToResource() { + Component component = new Resource(); + component.setNormalizedName("normalizedComponentName"); + InterfaceDefinition addedInterface = new InterfaceDefinition(); + addedInterface.setType("com.some.resource.or.other.resourceName"); + + 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(); + interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false); + + ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, + interfacesOperationsConverter); + ToscaTemplate template = new ToscaTemplate(NODE_TYPE_NAME); + Map nodeTypes = new HashMap<>(); + nodeTypes.put(NODE_TYPE_NAME, nodeType); + template.setNode_types(nodeTypes); + final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); + + String mainYaml = new String(toscaRepresentation.getMainYaml()); + assertTrue(all( + containsAll("resourceName:", "inputs:", "has description", MAPPED_PROPERTY_NAME, "com.some.resource.or.other.resourceName"), + containsNone("operations", "defaultp") + ).apply(mainYaml)); + + validateOperationInputs(mainYaml, 2, null); + } + + @Test + void addInterfaceDefinitionElementToService() { + Component component = new Service(); + component.setNormalizedName("normalizedServiceComponentName"); + InterfaceDefinition addedInterface = new InterfaceDefinition(); + addedInterface.setType("com.some.service.or.other.serviceName"); + 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(); + interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false); + + ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, + interfacesOperationsConverter); + ToscaTemplate template = new ToscaTemplate("testService"); + Map nodeTypes = new HashMap<>(); + nodeTypes.put(NODE_TYPE_NAME, nodeType); + template.setNode_types(nodeTypes); + final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); + String mainYaml = new String(toscaRepresentation.getMainYaml()); + assertTrue(all( + containsAll("serviceName", "inputs:", "has description", MAPPED_PROPERTY_NAME, "com.some.service.or.other.serviceName"), + containsNone("operations", "defaultp") + ).apply(mainYaml)); + validateOperationInputs(mainYaml, 2, null); + } + + + @Test + void testGetInterfaceAsMapServiceProxy() { + Component component = new Resource(); + component.setNormalizedName("normalizedComponentName"); + InterfaceDefinition addedInterface = new InterfaceDefinition(); + addedInterface.setToscaResourceName("com.some.resource.or.other.resourceName"); + addedInterface.setType("com.some.resource.or.other.resourceName"); + addOperationsToInterface(component, addedInterface, 3, 2, true, false); + final String interfaceType = "normalizedComponentName-interface"; + component.setInterfaces(new HashMap<>()); + component.getInterfaces().put(interfaceType, addedInterface); + Map interfacesMap = interfacesOperationsConverter + .getInterfacesMap(component, null, component.getInterfaces(), null, false, true); + ToscaNodeType nodeType = new ToscaNodeType(); + nodeType.setInterfaces(interfacesMap); + ToscaExportHandler handler = new ToscaExportHandler(); + ToscaTemplate template = new ToscaTemplate(NODE_TYPE_NAME); + Map nodeTypes = new HashMap<>(); + nodeTypes.put(NODE_TYPE_NAME, nodeType); + template.setNode_types(nodeTypes); + final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); + + String mainYaml = new String(toscaRepresentation.getMainYaml()); + assertTrue(all( + containsAll("resourceName:", "inputs:", "has description", MAPPED_PROPERTY_NAME, "com.some.resource.or.other.resourceName"), + containsNone("operations", "defaultp") + ).apply(mainYaml)); + validateServiceProxyOperationInputs(mainYaml); + } + + @Test + void addInterfaceDefinitionElement_noInputs() { + Component component = new Resource(); + component.setNormalizedName("normalizedComponentName"); + InterfaceDefinition addedInterface = new InterfaceDefinition(); + addedInterface.setType("com.some.resource.or.other.resourceNameNoInputs"); + 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(); + interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, null, false); + + ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, + interfacesOperationsConverter); + ToscaTemplate template = new ToscaTemplate("test"); + Map nodeTypes = new HashMap<>(); + nodeTypes.put("test", nodeType); + template.setNode_types(nodeTypes); + final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); + + assertTrue(all( + containsAll("resourceNameNoInputs", "has description", "com.some.resource.or.other.resourceName"), + containsNone("operations", INPUT_NAME_PREFIX, "defaultp") + ).apply(new String(toscaRepresentation.getMainYaml()))); + } + + @Test + 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(); + interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false); + + ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, + interfacesOperationsConverter); + ToscaTemplate template = new ToscaTemplate("test"); + Map nodeTypes = new HashMap<>(); + nodeTypes.put("test", nodeType); + template.setNode_types(nodeTypes); + final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); + String mainYaml = new String(toscaRepresentation.getMainYaml()); + assertTrue(all( + containsAll("resourceNameInputMappedToOutput:", "inputs:"), + containsNone("operations") + ).apply(mainYaml)); + validateOperationInputs(mainYaml, 2, "name_for_op_1"); + } + + @Test + void addInterfaceDefinitionElementInputMappedToOtherOperationOutputFromOtherInterface() { + 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(opInputDef -> opInputDef.getName().contains("integer")) + .forEach(opInputDef -> opInputDef.setInputId( + addedInterfaceType +".name_for_op_1.output_integer_1"))); + //Mapping to operation from another interface + String secondInterfaceType = "org.test.lifecycle.standard.interfaceType.second"; + InterfaceDefinition secondInterface = new InterfaceDefinition(); + secondInterface.setType(secondInterfaceType); + addOperationsToInterface(component, secondInterface, 2, 2, true, true); + secondInterface.getOperationsMap().values().stream() + .filter(operationInputDefinition -> operationInputDefinition.getName().equalsIgnoreCase( + "name_for_op_0")) + .forEach(operation -> operation.getInputs().getListToscaDataDefinition().stream() + .filter(opInputDef -> opInputDef.getName().contains("integer")) + .forEach(opInputDef -> opInputDef.setInputId( + addedInterfaceType +".name_for_op_1.output_integer_1"))); + component.setInterfaces(new HashMap<>()); + component.getInterfaces().put(addedInterfaceType, addedInterface); + component.getInterfaces().put(secondInterfaceType, secondInterface); + + ToscaNodeType nodeType = new ToscaNodeType(); + interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false); + + ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, + interfacesOperationsConverter); + ToscaTemplate template = new ToscaTemplate("test"); + Map nodeTypes = new HashMap<>(); + nodeTypes.put("test", nodeType); + template.setNode_types(nodeTypes); + final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); + + String mainYaml = new String(toscaRepresentation.getMainYaml()); + assertTrue(all( + containsAll("resourceNameInputMappedToOutput:", "inputs:"), + containsNone("operations") + ).apply(mainYaml)); + validateOperationInputs(mainYaml, 2, "name_for_op_1"); + } + + @Test + void interfaceWithInputsToscaExportTest() { + final Component component = new Service(); + final InterfaceDefinition aInterfaceWithInput = new InterfaceDefinition(); + final String interfaceName = "myInterfaceName"; + final String interfaceType = "my.type." + interfaceName; + aInterfaceWithInput.setType(interfaceType); + final String input1Name = "input1"; + final InputDataDefinition input1 = createInput("string", "input1 description", false, "input1 value"); + final String input2Name = "input2"; + final InputDataDefinition input2 = createInput("string", "input2 description", true, "input2 value"); + final Map inputMap = new HashMap<>(); + inputMap.put(input1Name, input1); + inputMap.put(input2Name, input2); + aInterfaceWithInput.setInputs(inputMap); + component.setInterfaces(new HashMap<>()); + component.getInterfaces().put(interfaceName, aInterfaceWithInput); + final ToscaNodeType nodeType = new ToscaNodeType(); + interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false); + final ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null, + interfacesOperationsConverter); + final ToscaTemplate template = new ToscaTemplate("testService"); + final Map nodeTypes = new HashMap<>(); + nodeTypes.put(NODE_TYPE_NAME, nodeType); + template.setNode_types(nodeTypes); + final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); + final String toscaTemplateYaml = new String(toscaRepresentation.getMainYaml()); + assertThat(toscaTemplateYaml, allOf(containsString(INPUTS.getElementName() + ":"), containsString(input1Name), containsString(interfaceName))); + validateInterfaceInputs(toscaTemplateYaml, interfaceName, inputMap); + } + + private void validateInterfaceInputs(final String yaml, final String interfaceName, final Map expectedInputMap) { + String fixedMainYaml = yaml; + final String nullString = "null"; + if (fixedMainYaml.startsWith(nullString)) { + fixedMainYaml = yaml.substring(nullString.length()); + } + if (fixedMainYaml.endsWith(nullString)) { + fixedMainYaml = fixedMainYaml.substring(0, fixedMainYaml.length() - nullString.length()); + } + final Map yamlMap = (Map) new Yaml().load(fixedMainYaml); + final Map nodeTypesMap = (Map) yamlMap.get(NODE_TYPES.getElementName()); + final Map node = (Map) nodeTypesMap.get(NODE_TYPE_NAME); + final Map interfacesMap = (Map) node.get(INTERFACES.getElementName()); + final Map interface1 = (Map) interfacesMap.get(interfaceName); + final Map actualInputsMap = (Map) interface1.get(INPUTS.getElementName()); + assertThat(actualInputsMap.keySet(), containsInAnyOrder(expectedInputMap.keySet().toArray())); + expectedInputMap.forEach((inputName, inputDataDefinition) -> { + final Map actualInput = (Map) actualInputsMap.get(inputName); + compareInputYaml(inputName, actualInput, inputDataDefinition); + }); + } + + private void compareInputYaml(final String inputName, final Map actualInput, + final InputDataDefinition expectedInput) { + final String msgFormat = "%s should be equal in input %s"; + String field = TYPE.getElementName(); + assertThat(String.format(msgFormat, field, inputName), + actualInput.get(field), equalTo(expectedInput.getType())); + field = DESCRIPTION.getElementName(); + assertThat(String.format(msgFormat, field, inputName), + actualInput.get(field), equalTo(expectedInput.getDescription())); + field = REQUIRED.getElementName(); + assertThat(String.format(msgFormat, field, inputName), + actualInput.get(field), equalTo(expectedInput.getRequired())); + field = DEFAULT.getElementName(); + assertThat(String.format(msgFormat, field, inputName), + actualInput.get(field), equalTo(expectedInput.getDefaultValue())); + } + + @FunctionalInterface + interface MainYamlAssertion extends Function {} + + private static Function all(MainYamlAssertion...fs) { + return s -> io.vavr.collection.List.of(fs).map(f -> f.apply(s)).fold(true, (l, r) -> l && r); + } + + private static MainYamlAssertion containsNone(String...expected) { + return s -> io.vavr.collection.List.of(expected).map(e -> !s.contains(e)).fold(true, (l, r) -> l && r); + } + + private static MainYamlAssertion containsAll(String...expected) { + return s -> io.vavr.collection.List.of(expected).map(s::contains).fold(true, (l, r) -> l && r); + } + + 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++) { + final OperationDataDefinition operation = new OperationDataDefinition(); + operation.setName("name_for_op_" + i); + operation.setDescription("op " + i + " has description"); + final ArtifactDataDefinition implementation = new ArtifactDataDefinition(); + implementation.setArtifactName(i + "_createBPMN.bpmn"); + operation.setImplementation(implementation); + if (hasInputs) { + operation.setInputs(createInputs(component, numOfInputsPerOp)); + } + if (hasOutputs) { + operation.setOutputs(createOutputs(addedInterface.getToscaResourceName(), + operation.getName(), numOfInputsPerOp)); + } + addedInterface.getOperations().put(operation.getName(), operation); + } + } + + private InputDataDefinition createInput(final String type, final String description, final Boolean isRequired, + final String defaultValue) { + final PropertyDataDefinition propertyDataDefinition = new PropertyDataDefinition(); + if (type != null) { + propertyDataDefinition.setType(type); + } + if (description != null) { + propertyDataDefinition.setDescription(description); + } + if (defaultValue != null) { + propertyDataDefinition.setDefaultValue(defaultValue); + } + if (isRequired != null) { + propertyDataDefinition.setRequired(isRequired); + } + return new InputDataDefinition(propertyDataDefinition); + } + + private ListDataDefinition createInputs(Component component, int numOfInputs) { + ListDataDefinition 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, 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 createOutputs(String interfaceName, + String operationName, + int numOfOutputs) { + ListDataDefinition operationOutputDefinitionList = new ListDataDefinition<>(); + for (int i = 0; i < numOfOutputs; i++) { + operationOutputDefinitionList.add(createMockOperationOutputDefinition(interfaceName, operationName, + OUTPUT_NAME_PREFIX + inputTypes[i] + "_" + i, i)); + } + return operationOutputDefinitionList; + } + + private OperationInputDefinition createMockOperationInputDefinition(String name, String id, int index) { + OperationInputDefinition operationInputDefinition = new OperationInputDefinition(); + operationInputDefinition.setName(name); + operationInputDefinition.setInputId(id); + operationInputDefinition.setType(inputTypes[index]); + operationInputDefinition.setRequired(index % 2 == 0); + Map> toscaDefaultValueMap = new HashMap<>(); + List toscaDefaultValues = new ArrayList<>(); + toscaDefaultValues.add(SELF); + toscaDefaultValues.add(id.substring(id.lastIndexOf('.') + 1)); + toscaDefaultValueMap.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), toscaDefaultValues); + operationInputDefinition.setToscaDefaultValue(new Gson().toJson(toscaDefaultValueMap)); + operationInputDefinition.setSource("ServiceInput"); + return operationInputDefinition; + } + + private OperationOutputDefinition createMockOperationOutputDefinition(String interfaceName, String operationName, + String outputName, int index) { + OperationOutputDefinition operationInputDefinition = new OperationOutputDefinition(); + operationInputDefinition.setName(outputName); + operationInputDefinition.setType(inputTypes[index]); + operationInputDefinition.setRequired(index % 2 == 0); + List toscaDefaultValues = new ArrayList<>(); + toscaDefaultValues.add(SELF); + toscaDefaultValues.add(interfaceName); + toscaDefaultValues.add(operationName); + toscaDefaultValues.add(outputName); + Map> toscaDefaultValueMap = new HashMap<>(); + toscaDefaultValueMap.put(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName(), toscaDefaultValues); + return operationInputDefinition; + } + + private void validateOperationInputs(final 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() + + String.valueOf(numOfInputsPerOp).length()); + YamlToObjectConverter objectConverter = new YamlToObjectConverter(); + ToscaNodeType toscaNodeType = objectConverter.convert(nodeTypesRepresentation.getBytes(), ToscaNodeType.class); + Map interfaces = toscaNodeType.getInterfaces(); + for (Map.Entry interfaceEntry : interfaces.entrySet()) { + Map interfaceDefinition = mapper.convertValue(interfaceEntry.getValue(), Map.class); + final Map operationsMap = interfaceDefinition.entrySet().stream() + .filter(entry -> !INPUTS.getElementName().equals(entry.getKey()) && + !TYPE.getElementName().equals(entry.getKey())) + .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); + for (Map.Entry operationEntry : operationsMap.entrySet()) { + Object operationVal = operationEntry.getValue(); + if (operationVal instanceof Map) { + //Since the inputs are mapped to output operations from only first interface so using that name + validateOperationInputDefinition(interfaces.keySet().iterator().next(), mappedOperationName, + operationVal); + } + } + } + } + + private void validateOperationInputDefinition(String interfaceType, String operationName, Object operationVal) { + Map operation = mapper.convertValue(operationVal, Map.class); + Map inputs = (Map) operation.get("inputs"); + for (Map.Entry inputEntry : inputs.entrySet()) { + String[] inputNameSplit = inputEntry.getKey().split("_"); + Map inputValueObject = (Map) inputEntry.getValue(); + assertEquals(inputNameSplit[1], inputValueObject.get("type")); + Boolean expectedIsRequired = Integer.parseInt(inputNameSplit[2]) % 2 == 0; + 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 inputValueObject) { + Map mappedInputValue = (Map) inputValueObject.get("default"); + if(mappedInputValue.containsKey(ToscaFunctions.GET_PROPERTY.getFunctionName())) { + String mappedPropertyValue = MAPPED_PROPERTY_NAME + index; + List mappedPropertyDefaultValue = (List) mappedInputValue.get(ToscaFunctions.GET_PROPERTY.getFunctionName()); + assertEquals(2, mappedPropertyDefaultValue.size()); + assertTrue(mappedPropertyDefaultValue.contains(SELF)); + assertTrue(mappedPropertyDefaultValue.contains(mappedPropertyValue)); + } else if(mappedInputValue.containsKey(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName())) { + List mappedPropertyDefaultValue = (List) mappedInputValue.get(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName()); + assertEquals(4, mappedPropertyDefaultValue.size()); + String mappedPropertyValue = OUTPUT_NAME_PREFIX + inputType + "_" + index; + assertTrue(mappedPropertyDefaultValue.contains(SELF)); + assertTrue(mappedPropertyDefaultValue.contains(interfaceType)); + assertTrue(mappedPropertyDefaultValue.contains(operationName)); + assertTrue(mappedPropertyDefaultValue.contains(mappedPropertyValue)); + } else { + fail("Invalid Tosca function in default value. Allowed values: "+ ToscaFunctions.GET_PROPERTY.getFunctionName() + + "/"+ ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName()); + } + } + + private void validateServiceProxyOperationInputs(String mainYaml) { + String nodeTypeKey = NODE_TYPE_NAME + ":"; + String nodeTypesRepresentation = mainYaml.substring(mainYaml.indexOf(nodeTypeKey) + nodeTypeKey.length(), + mainYaml.lastIndexOf(MAPPED_PROPERTY_NAME) + MAPPED_PROPERTY_NAME.length()); + YamlUtil yamlUtil = new YamlUtil(); + ToscaNodeType toscaNodeType = yamlUtil.yamlToObject(nodeTypesRepresentation, ToscaNodeType.class); + for (Object interfaceVal : toscaNodeType.getInterfaces().values()) { + Map interfaceDefinition = mapper.convertValue(interfaceVal, Map.class); + for (Object operationVal : interfaceDefinition.values()) { + if (operationVal instanceof Map) { + Map operation = (Map) mapper.convertValue(operationVal, Map.class); + Map operationInputs = (Map) operation.get("inputs"); + for (Object inputValue : operationInputs.values()) { + Map inputValueAsMap = (Map) inputValue; + assertFalse(inputValueAsMap.keySet().contains("type")); + assertFalse(inputValueAsMap.keySet().contains("required")); + assertFalse(inputValueAsMap.keySet().contains("default")); + } + } + } + } + } + + @Test + void testAddInterfaceTypeElementGetCorrectLocalInterfaceName() { + Service service = new Service(); + service.setComponentMetadataDefinition(new ServiceMetadataDefinition()); + service.getComponentMetadataDefinition().getMetadataDataDefinition().setName("LocalInterface"); + service.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName("LocalInterface"); + service.setInterfaces(Collections.singletonMap("Local", new InterfaceDefinition("Local", null, new HashMap<>()))); + + Map resultMap = InterfacesOperationsConverter.addInterfaceTypeElement(service, + Collections.singletonList("org.openecomp.interfaces.node.lifecycle.Standard")); + + assertTrue(MapUtils.isNotEmpty(resultMap) + && resultMap.containsKey("org.openecomp.interfaces.node.lifecycle.LocalInterface")); + } + + @Test + void testAddInterfaceTypeElementNoTypeChangeIfNotLocal() { + Service service = new Service(); + service.setComponentMetadataDefinition(new ServiceMetadataDefinition()); + service.getComponentMetadataDefinition().getMetadataDataDefinition().setName("LocalInterface"); + service.setInterfaces(Collections.singletonMap("NotLocal", new InterfaceDefinition("NotLocal", null, + new HashMap<>()))); + + Map resultMap = interfacesOperationsConverter.getInterfacesMap(service, null, + service.getInterfaces(), null, false, false); + + assertTrue(MapUtils.isNotEmpty(resultMap) + && resultMap.containsKey("NotLocal")); + } +} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaInterfaceDefinitionTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaInterfaceDefinitionTest.java deleted file mode 100644 index b922d0d60d..0000000000 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaInterfaceDefinitionTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ - -package org.openecomp.sdc.be.tosca.model; - -import org.junit.Test; - -import java.util.Map; - -public class ToscaInterfaceDefinitionTest { - - private ToscaInterfaceDefinition createTestSubject() { - return new ToscaInterfaceDefinition(); - } - - @Test - public void testGetType() throws Exception { - ToscaInterfaceDefinition testSubject; - String result; - - // default test - testSubject = createTestSubject(); - result = testSubject.getType(); - } - - @Test - public void testSetType() throws Exception { - ToscaInterfaceDefinition testSubject; - String type = ""; - - // default test - testSubject = createTestSubject(); - testSubject.setType(type); - } - - @Test - public void testGetOperations() throws Exception { - ToscaInterfaceDefinition testSubject; - Map result; - - // default test - testSubject = createTestSubject(); - result = testSubject.getOperations(); - } - - @Test - public void testSetOperations() throws Exception { - ToscaInterfaceDefinition testSubject; - Map toscaOperations = null; - - // default test - testSubject = createTestSubject(); - testSubject.setOperations(toscaOperations); - } -} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsConverterTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsConverterTest.java deleted file mode 100644 index 93a45ad20f..0000000000 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsConverterTest.java +++ /dev/null @@ -1,563 +0,0 @@ -/* - * Copyright © 2016-2018 European Support Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.openecomp.sdc.be.tosca.utils; - -import static org.mockito.Mockito.mock; -import static org.openecomp.sdc.be.tosca.InterfacesOperationsConverter.SELF; -import static org.openecomp.sdc.be.tosca.InterfacesOperationsConverter.addInterfaceTypeElement; - -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.gson.Gson; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.function.Function; -import org.apache.commons.collections4.MapUtils; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; -import org.onap.sdc.tosca.services.YamlUtil; -import org.openecomp.sdc.be.DummyConfigurationManager; -import org.openecomp.sdc.be.config.Configuration; -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.DataTypeDefinition; -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.model.ServiceMetadataDefinition; -import org.openecomp.sdc.be.tosca.InterfacesOperationsConverter; -import org.openecomp.sdc.be.tosca.PropertyConvertor; -import org.openecomp.sdc.be.tosca.ToscaExportHandler; -import org.openecomp.sdc.be.tosca.ToscaRepresentation; -import org.openecomp.sdc.be.tosca.model.ToscaNodeType; -import org.openecomp.sdc.be.tosca.model.ToscaTemplate; -import org.openecomp.sdc.common.util.YamlToObjectConverter; -import org.openecomp.sdc.tosca.datatypes.ToscaFunctions; - -@RunWith(MockitoJUnitRunner.class) -public class InterfacesOperationsConverterTest { - - 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; - private Configuration.EnvironmentContext environmentContext = mock(Configuration.EnvironmentContext.class); - DummyConfigurationManager dummyConfigurationManager = new DummyConfigurationManager(); - private static final Map dataTypes = new HashMap<>(); - - private InterfacesOperationsConverter interfacesOperationsConverter; - - @BeforeClass - public static void setUp() { - mapper = new ObjectMapper(); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - } - - @Before - public void setUpBeforeTest() { - interfacesOperationsConverter = - new InterfacesOperationsConverter(new PropertyConvertor()); - } - - @Test - public void addInterfaceTypeElementToResource() { - Component component = new Resource(); - component.setNormalizedName("normalizedComponentName"); - component.setComponentMetadataDefinition(new ServiceMetadataDefinition()); - component.getComponentMetadataDefinition().getMetadataDataDefinition().setName("NodeTypeName"); - component.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName("NodeTypeName"); - InterfaceDefinition addedInterface = new InterfaceDefinition(); - addedInterface.setType("Local"); - addOperationsToInterface(component, addedInterface, 5, 3, true, false); - final String interfaceType = "normalizedComponentName-interface"; - component.setInterfaces(new HashMap<>()); - component.getInterfaces().put(interfaceType, addedInterface); - final Map interfaceTypeElement = - addInterfaceTypeElement(component, new ArrayList<>()); - - ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, - interfacesOperationsConverter); - ToscaTemplate template = new ToscaTemplate("test"); - template.setInterface_types(interfaceTypeElement); - final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); - - Assert.assertTrue(all( - containsAll("NodeTypeName"), - containsNone("operations") - ).apply(new String(toscaRepresentation.getMainYaml()))); - } - - @Test - public void addInterfaceTypeElementToService() { - Component component = new Service(); - component.setNormalizedName("normalizedServiceComponentName"); - component.setComponentMetadataDefinition(new ServiceMetadataDefinition()); - component.getComponentMetadataDefinition().getMetadataDataDefinition().setName("NodeTypeName"); - component.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName("NodeTypeName"); - InterfaceDefinition addedInterface = new InterfaceDefinition(); - addedInterface.setType("Local"); - addOperationsToInterface(component, addedInterface, 5, 3, true, false); - final String interfaceType = "normalizedServiceComponentName-interface"; - component.setInterfaces(new HashMap<>()); - component.getInterfaces().put(interfaceType, addedInterface); - final Map interfaceTypeElement = - addInterfaceTypeElement(component, new ArrayList<>()); - - ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, - interfacesOperationsConverter); - ToscaTemplate template = new ToscaTemplate("testService"); - template.setInterface_types(interfaceTypeElement); - final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); - - Assert.assertTrue(all( - containsAll("NodeTypeName"), - containsNone("operations") - ).apply(new String(toscaRepresentation.getMainYaml()))); - } - - @Test - public void addInterfaceDefinitionElementToResource() { - Component component = new Resource(); - component.setNormalizedName("normalizedComponentName"); - InterfaceDefinition addedInterface = new InterfaceDefinition(); - addedInterface.setType("com.some.resource.or.other.resourceName"); - - 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(); - interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false); - - ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, - interfacesOperationsConverter); - ToscaTemplate template = new ToscaTemplate(NODE_TYPE_NAME); - Map nodeTypes = new HashMap<>(); - nodeTypes.put(NODE_TYPE_NAME, nodeType); - template.setNode_types(nodeTypes); - final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); - - String mainYaml = new String(toscaRepresentation.getMainYaml()); - Assert.assertTrue(all( - containsAll("resourceName:", "inputs:", "has description", MAPPED_PROPERTY_NAME, "com.some.resource.or.other.resourceName"), - containsNone("operations", "defaultp") - ).apply(mainYaml)); - - validateOperationInputs(mainYaml, 2, null); - } - - @Test - public void addInterfaceDefinitionElementToService() { - Component component = new Service(); - component.setNormalizedName("normalizedServiceComponentName"); - InterfaceDefinition addedInterface = new InterfaceDefinition(); - addedInterface.setType("com.some.service.or.other.serviceName"); - 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(); - interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false); - - ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, - interfacesOperationsConverter); - ToscaTemplate template = new ToscaTemplate("testService"); - Map nodeTypes = new HashMap<>(); - nodeTypes.put(NODE_TYPE_NAME, nodeType); - template.setNode_types(nodeTypes); - final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); - String mainYaml = new String(toscaRepresentation.getMainYaml()); - Assert.assertTrue(all( - containsAll("serviceName", "inputs:", "has description", MAPPED_PROPERTY_NAME, "com.some.service.or.other.serviceName"), - containsNone("operations", "defaultp") - ).apply(mainYaml)); - validateOperationInputs(mainYaml, 2, null); - } - - - @Test - public void testGetInterfaceAsMapServiceProxy() { - Component component = new Resource(); - component.setNormalizedName("normalizedComponentName"); - InterfaceDefinition addedInterface = new InterfaceDefinition(); - addedInterface.setToscaResourceName("com.some.resource.or.other.resourceName"); - addedInterface.setType("com.some.resource.or.other.resourceName"); - addOperationsToInterface(component, addedInterface, 3, 2, true, false); - final String interfaceType = "normalizedComponentName-interface"; - component.setInterfaces(new HashMap<>()); - component.getInterfaces().put(interfaceType, addedInterface); - Map interfacesMap = interfacesOperationsConverter - .getInterfacesMap(component, null, component.getInterfaces(), null, false, true); - ToscaNodeType nodeType = new ToscaNodeType(); - nodeType.setInterfaces(interfacesMap); - ToscaExportHandler handler = new ToscaExportHandler(); - ToscaTemplate template = new ToscaTemplate(NODE_TYPE_NAME); - Map nodeTypes = new HashMap<>(); - nodeTypes.put(NODE_TYPE_NAME, nodeType); - template.setNode_types(nodeTypes); - final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); - - String mainYaml = new String(toscaRepresentation.getMainYaml()); - Assert.assertTrue(all( - containsAll("resourceName:", "inputs:", "has description", MAPPED_PROPERTY_NAME, "com.some.resource.or.other.resourceName"), - containsNone("operations", "defaultp") - ).apply(mainYaml)); - validateServiceProxyOperationInputs(mainYaml); - } - - @Test - public void addInterfaceDefinitionElement_noInputs() { - Component component = new Resource(); - component.setNormalizedName("normalizedComponentName"); - InterfaceDefinition addedInterface = new InterfaceDefinition(); - addedInterface.setType("com.some.resource.or.other.resourceNameNoInputs"); - 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(); - interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, null, false); - - ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, - interfacesOperationsConverter); - ToscaTemplate template = new ToscaTemplate("test"); - Map nodeTypes = new HashMap<>(); - nodeTypes.put("test", nodeType); - template.setNode_types(nodeTypes); - final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); - - Assert.assertTrue(all( - containsAll("resourceNameNoInputs", "has description", "com.some.resource.or.other.resourceName"), - containsNone("operations", INPUT_NAME_PREFIX, "defaultp") - ).apply(new String(toscaRepresentation.getMainYaml()))); - } - - @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(); - interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false); - - ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, - interfacesOperationsConverter); - ToscaTemplate template = new ToscaTemplate("test"); - Map nodeTypes = new HashMap<>(); - nodeTypes.put("test", nodeType); - template.setNode_types(nodeTypes); - final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); - String mainYaml = new String(toscaRepresentation.getMainYaml()); - Assert.assertTrue(all( - containsAll("resourceNameInputMappedToOutput:", "inputs:"), - containsNone("operations") - ).apply(mainYaml)); - validateOperationInputs(mainYaml, 2, "name_for_op_1"); - } - - @Test - public void addInterfaceDefinitionElementInputMappedToOtherOperationOutputFromOtherInterface() { - 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(opInputDef -> opInputDef.getName().contains("integer")) - .forEach(opInputDef -> opInputDef.setInputId( - addedInterfaceType +".name_for_op_1.output_integer_1"))); - //Mapping to operation from another interface - String secondInterfaceType = "org.test.lifecycle.standard.interfaceType.second"; - InterfaceDefinition secondInterface = new InterfaceDefinition(); - secondInterface.setType(secondInterfaceType); - addOperationsToInterface(component, secondInterface, 2, 2, true, true); - secondInterface.getOperationsMap().values().stream() - .filter(operationInputDefinition -> operationInputDefinition.getName().equalsIgnoreCase( - "name_for_op_0")) - .forEach(operation -> operation.getInputs().getListToscaDataDefinition().stream() - .filter(opInputDef -> opInputDef.getName().contains("integer")) - .forEach(opInputDef -> opInputDef.setInputId( - addedInterfaceType +".name_for_op_1.output_integer_1"))); - component.setInterfaces(new HashMap<>()); - component.getInterfaces().put(addedInterfaceType, addedInterface); - component.getInterfaces().put(secondInterfaceType, secondInterface); - - ToscaNodeType nodeType = new ToscaNodeType(); - interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false); - - ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, - interfacesOperationsConverter); - ToscaTemplate template = new ToscaTemplate("test"); - Map nodeTypes = new HashMap<>(); - nodeTypes.put("test", nodeType); - template.setNode_types(nodeTypes); - final ToscaRepresentation toscaRepresentation = handler.createToscaRepresentation(template); - - String mainYaml = new String(toscaRepresentation.getMainYaml()); - Assert.assertTrue(all( - containsAll("resourceNameInputMappedToOutput:", "inputs:"), - containsNone("operations") - ).apply(mainYaml)); - validateOperationInputs(mainYaml, 2, "name_for_op_1"); - } - - @FunctionalInterface - interface MainYamlAssertion extends Function {} - - private static Function all(MainYamlAssertion...fs) { - return s -> io.vavr.collection.List.of(fs).map(f -> f.apply(s)).fold(true, (l, r) -> l && r); - } - - private static MainYamlAssertion containsNone(String...expected) { - return s -> io.vavr.collection.List.of(expected).map(e -> !s.contains(e)).fold(true, (l, r) -> l && r); - } - - private static MainYamlAssertion containsAll(String...expected) { - return s -> io.vavr.collection.List.of(expected).map(s::contains).fold(true, (l, r) -> l && r); - } - - 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++) { - final OperationDataDefinition operation = new OperationDataDefinition(); - operation.setName("name_for_op_" + i); - operation.setDescription("op " + i + " has description"); - final ArtifactDataDefinition implementation = new ArtifactDataDefinition(); - implementation.setArtifactName(i + "_createBPMN.bpmn"); - operation.setImplementation(implementation); - if (hasInputs) { - operation.setInputs(createInputs(component, numOfInputsPerOp)); - } - if (hasOutputs) { - operation.setOutputs(createOutputs(addedInterface.getToscaResourceName(), - operation.getName(), numOfInputsPerOp)); - } - addedInterface.getOperations().put(operation.getName(), operation); - } - } - - private ListDataDefinition createInputs(Component component, int numOfInputs) { - ListDataDefinition 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, 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 createOutputs(String interfaceName, - String operationName, - int numOfOutputs) { - ListDataDefinition operationOutputDefinitionList = new ListDataDefinition<>(); - for (int i = 0; i < numOfOutputs; i++) { - operationOutputDefinitionList.add(createMockOperationOutputDefinition(interfaceName, operationName, - OUTPUT_NAME_PREFIX + inputTypes[i] + "_" + i, i)); - } - return operationOutputDefinitionList; - } - - private OperationInputDefinition createMockOperationInputDefinition(String name, String id, int index) { - OperationInputDefinition operationInputDefinition = new OperationInputDefinition(); - operationInputDefinition.setName(name); - operationInputDefinition.setInputId(id); - operationInputDefinition.setType(inputTypes[index]); - operationInputDefinition.setRequired(index % 2 == 0); - Map> toscaDefaultValueMap = new HashMap<>(); - List toscaDefaultValues = new ArrayList<>(); - toscaDefaultValues.add(SELF); - toscaDefaultValues.add(id.substring(id.lastIndexOf('.') + 1)); - toscaDefaultValueMap.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), toscaDefaultValues); - operationInputDefinition.setToscaDefaultValue(new Gson().toJson(toscaDefaultValueMap)); - operationInputDefinition.setSource("ServiceInput"); - return operationInputDefinition; - } - - private OperationOutputDefinition createMockOperationOutputDefinition(String interfaceName, String operationName, - String outputName, int index) { - OperationOutputDefinition operationInputDefinition = new OperationOutputDefinition(); - operationInputDefinition.setName(outputName); - operationInputDefinition.setType(inputTypes[index]); - operationInputDefinition.setRequired(index % 2 == 0); - List toscaDefaultValues = new ArrayList<>(); - toscaDefaultValues.add(SELF); - toscaDefaultValues.add(interfaceName); - toscaDefaultValues.add(operationName); - toscaDefaultValues.add(outputName); - Map> toscaDefaultValueMap = new HashMap<>(); - toscaDefaultValueMap.put(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName(), toscaDefaultValues); - return operationInputDefinition; - } - - private void validateOperationInputs(final 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() - + String.valueOf(numOfInputsPerOp).length()); - YamlToObjectConverter objectConverter = new YamlToObjectConverter(); - ToscaNodeType toscaNodeType = objectConverter.convert(nodeTypesRepresentation.getBytes(), ToscaNodeType.class); - Map interfaces = toscaNodeType.getInterfaces(); - for (Map.Entry interfaceEntry : interfaces.entrySet()) { - Map interfaceDefinition = mapper.convertValue(interfaceEntry.getValue(), Map.class); - for (Map.Entry operationEntry : interfaceDefinition.entrySet()) { - Object operationVal = operationEntry.getValue(); - if (operationVal instanceof Map) { - //Since the inputs are mapped to output operations from only first interface so using that name - validateOperationInputDefinition(interfaces.keySet().iterator().next(), mappedOperationName, - operationVal); - } - } - } - } - - private void validateOperationInputDefinition(String interfaceType, String operationName, Object operationVal) { - Map operation = mapper.convertValue(operationVal, Map.class); - Map inputs = (Map) operation.get("inputs"); - for (Map.Entry inputEntry : inputs.entrySet()) { - String[] inputNameSplit = inputEntry.getKey().split("_"); - Map inputValueObject = (Map) 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 inputValueObject) { - Map mappedInputValue = (Map) inputValueObject.get("default"); - if(mappedInputValue.containsKey(ToscaFunctions.GET_PROPERTY.getFunctionName())) { - String mappedPropertyValue = MAPPED_PROPERTY_NAME + index; - List mappedPropertyDefaultValue = (List) mappedInputValue.get(ToscaFunctions.GET_PROPERTY.getFunctionName()); - Assert.assertEquals(2, mappedPropertyDefaultValue.size()); - Assert.assertTrue(mappedPropertyDefaultValue.contains(SELF)); - Assert.assertTrue(mappedPropertyDefaultValue.contains(mappedPropertyValue)); - } else if(mappedInputValue.containsKey(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName())) { - List mappedPropertyDefaultValue = (List) mappedInputValue.get(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName()); - 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: "+ ToscaFunctions.GET_PROPERTY.getFunctionName() + - "/"+ ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName()); - } - } - - private void validateServiceProxyOperationInputs(String mainYaml) { - String nodeTypeKey = NODE_TYPE_NAME + ":"; - String nodeTypesRepresentation = mainYaml.substring(mainYaml.indexOf(nodeTypeKey) + nodeTypeKey.length(), - mainYaml.lastIndexOf(MAPPED_PROPERTY_NAME) + MAPPED_PROPERTY_NAME.length()); - YamlUtil yamlUtil = new YamlUtil(); - ToscaNodeType toscaNodeType = yamlUtil.yamlToObject(nodeTypesRepresentation, ToscaNodeType.class); - for (Object interfaceVal : toscaNodeType.getInterfaces().values()) { - Map interfaceDefinition = mapper.convertValue(interfaceVal, Map.class); - for (Object operationVal : interfaceDefinition.values()) { - if (operationVal instanceof Map) { - Map operation = (Map) mapper.convertValue(operationVal, Map.class); - Map operationInputs = (Map) operation.get("inputs"); - for (Object inputValue : operationInputs.values()) { - Map inputValueAsMap = (Map) inputValue; - Assert.assertFalse(inputValueAsMap.keySet().contains("type")); - Assert.assertFalse(inputValueAsMap.keySet().contains("required")); - Assert.assertFalse(inputValueAsMap.keySet().contains("default")); - } - } - } - } - } - - @Test - public void testAddInterfaceTypeElementGetCorrectLocalInterfaceName() { - Service service = new Service(); - service.setComponentMetadataDefinition(new ServiceMetadataDefinition()); - service.getComponentMetadataDefinition().getMetadataDataDefinition().setName("LocalInterface"); - service.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName("LocalInterface"); - service.setInterfaces(Collections.singletonMap("Local", new InterfaceDefinition("Local", null, new HashMap<>()))); - - Map resultMap = InterfacesOperationsConverter.addInterfaceTypeElement(service, - Collections.singletonList("org.openecomp.interfaces.node.lifecycle.Standard")); - - Assert.assertTrue(MapUtils.isNotEmpty(resultMap) - && resultMap.containsKey("org.openecomp.interfaces.node.lifecycle.LocalInterface")); - } - - @Test - public void testAddInterfaceTypeElementNoTypeChangeIfNotLocal() { - Service service = new Service(); - service.setComponentMetadataDefinition(new ServiceMetadataDefinition()); - service.getComponentMetadataDefinition().getMetadataDataDefinition().setName("LocalInterface"); - service.setInterfaces(Collections.singletonMap("NotLocal", new InterfaceDefinition("NotLocal", null, - new HashMap<>()))); - - Map resultMap = interfacesOperationsConverter.getInterfacesMap(service, null, - service.getInterfaces(), null, false, false); - - Assert.assertTrue(MapUtils.isNotEmpty(resultMap) - && resultMap.containsKey("NotLocal")); - } -} diff --git a/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml b/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml index a28f31b1b0..50906d2624 100644 --- a/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml +++ b/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml @@ -2038,6 +2038,18 @@ errors: message: "Error: Failed to delete interface operation.", messageId: "SVC4702" } + #SVC4732 + INTERFACE_UNKNOWN: { + code: 400, + message: "Error: The interface '%1' does not exists in the database.", + messageId: "SVC4732" + } + #SVC4733 + INTERFACE_OPERATION_NOT_DEFINED: { + code: 400, + message: "Error: The operation '%1' does not exists in the interface '%2'.", + messageId: "SVC4733" + } #-----------SVC4692--------------------------- RESOURCE_LIFECYCLE_STATE_NOT_VALID: { code: 400, diff --git a/catalog-be/src/test/resources/interfaceDefinition/interfaceDefinition-legacy.yaml b/catalog-be/src/test/resources/interfaceDefinition/interfaceDefinition-legacy.yaml new file mode 100644 index 0000000000..d12664be9d --- /dev/null +++ b/catalog-be/src/test/resources/interfaceDefinition/interfaceDefinition-legacy.yaml @@ -0,0 +1,24 @@ +inputs: + stringInput: + type: string + description: stringInput description + required: true + default: defaultValue + status: aStatus + actionInput: + type: org.openecomp.resource.datatypes.Action +type: tosca.interfaces.node.lifecycle.Standard +create: + implementation: "camunda/serviceSelect" +start: + implementation: "camunda/executeAction" + inputs: + action: + type: org.openecomp.resource.datatypes.Action +stop: + implementation: "camunda/executeAction" + inputs: + action: + type: org.openecomp.resource.datatypes.Action +delete: + implementation: "camunda/serviceDeselect" \ No newline at end of file diff --git a/catalog-be/src/test/resources/interfaceDefinition/interfaceDefinition-tosca1.3.yaml b/catalog-be/src/test/resources/interfaceDefinition/interfaceDefinition-tosca1.3.yaml new file mode 100644 index 0000000000..13dfb9a1fb --- /dev/null +++ b/catalog-be/src/test/resources/interfaceDefinition/interfaceDefinition-tosca1.3.yaml @@ -0,0 +1,25 @@ +inputs: + stringInput: + type: string + description: stringInput description + required: true + default: defaultValue + status: aStatus + actionInput: + type: org.openecomp.resource.datatypes.Action +type: tosca.interfaces.node.lifecycle.Standard +operations: + create: + implementation: "camunda/serviceSelect" + start: + implementation: "camunda/executeAction" + inputs: + action: + type: org.openecomp.resource.datatypes.Action + stop: + implementation: "camunda/executeAction" + inputs: + action: + type: org.openecomp.resource.datatypes.Action + delete: + implementation: "camunda/serviceDeselect" \ No newline at end of file -- cgit 1.2.3-korg