diff options
Diffstat (limited to 'catalog-be/src/main')
7 files changed, 393 insertions, 243 deletions
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<PropertyConstraint> getPropertyConstraints(Map<String, Object> propertyValue, - String propertyType) { - List<Object> propertyFieldConstraints = findCurrentLevelConstraintsElement(propertyValue); - if (CollectionUtils.isNotEmpty(propertyFieldConstraints)) { - List<PropertyConstraint> constraintList = new ArrayList<>(); - Type constraintType = new TypeToken<PropertyConstraint>() { - }.getType(); - Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()) - .create(); + private static List<PropertyConstraint> getPropertyConstraints(final Map<String, Object> propertyValue, + final String propertyType) { + final List<Object> propertyFieldConstraints = findCurrentLevelConstraintsElement(propertyValue); + if (CollectionUtils.isEmpty(propertyFieldConstraints)) { + return Collections.emptyList(); + } + final List<PropertyConstraint> constraintList = new ArrayList<>(); + final Type constraintType = new TypeToken<PropertyConstraint>() { + }.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<Object> findCurrentLevelConstraintsElement(Map<String, Object> toscaJson) { @@ -485,10 +486,13 @@ public final class ImportUtils { return result; } - public static InputDefinition createModuleInput(Map<String, Object> inputValue, - AnnotationTypeOperations annotationTypeOperations) { + public static InputDefinition createModuleInput(final Map<String, Object> inputValue, + final AnnotationTypeOperations annotationTypeOperations) { + return parseAnnotationsAndAddItToInput(createModuleInput(inputValue), inputValue, annotationTypeOperations); + } - InputDefinition inputDef = new InputDefinition(); + public static InputDefinition createModuleInput(final Map<String, Object> 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<Map<String, InputDefinition>, ResultStatusEnum> getInputs(final Map<String, Object> toscaJson) { + return getElements(toscaJson, TypeUtils.ToscaTagNamesEnum.INPUTS, ImportUtils::createInputs, + ImportUtils::createModuleInput); + } + public static <T> Either<Map<String, T>, ResultStatusEnum> getElements(Map<String, Object> toscaJson, TypeUtils.ToscaTagNamesEnum elementTagName, Function<String, T> 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<String, Object> 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<String, InputDefinition> inputDefinitionMap = handleInputs(interfaceDefinitionToscaMap); + if (!inputDefinitionMap.isEmpty()) { + final Map<String, InputDataDefinition> collect = inputDefinitionMap.entrySet().stream(). + collect(Collectors.toMap(Entry::getKey, value -> new InputDataDefinition(value.getValue()))); + interfaceDefinition.setInputs(collect); + } + final Map<String, OperationDataDefinition> 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<String, OperationDataDefinition> operationMap) { + if (MapUtils.isEmpty(operationMap)) { + return; + } + Either<Map<String, InterfaceDefinition>, ResponseFormat> interfaceDefinitionMapEither = + interfaceOperationBusinessLogic.getAllInterfaceLifecycleTypes(); + if (interfaceDefinitionMapEither.isRight() || MapUtils.isEmpty(interfaceDefinitionMapEither.left().value())) { + throw new ByActionStatusComponentException(ActionStatus.INTERFACE_UNKNOWN, interfaceType); + } + + final Map<String, InterfaceDefinition> interfaceDefinitionMap = interfaceDefinitionMapEither.left().value(); + final Optional<InterfaceDefinition> 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<String, OperationDataDefinition> handleOperations( + final Map<String, Object> interfaceDefinitionToscaMap) { + if (!interfaceDefinitionToscaMap.containsKey(OPERATIONS.getElementName())) { + return Collections.emptyMap(); + } + final Map<String, Object> operationMap = + (Map<String, Object>) interfaceDefinitionToscaMap.get(OPERATIONS.getElementName()); + return operationMap.entrySet().stream() + .map(interfaceEntry -> createOperation(interfaceEntry.getKey(), + (Map<String, Object>) interfaceEntry.getValue())) + .collect( + Collectors.toMap(OperationDataDefinition::getName, operationDataDefinition -> operationDataDefinition)); + } + + private Map<String, OperationDataDefinition> handleLegacyOperations( + final Map<String, Object> interfaceDefinitionToscaMap) { + final List<String> 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<String, Object>) interfaceEntry.getValue())) + .collect( + Collectors.toMap(OperationDataDefinition::getName, operationDataDefinition -> operationDataDefinition)); + } + + + private OperationDataDefinition createOperation(final String operationName, + final Map<String, Object> operationDefinitionMap) { + final OperationDataDefinition operation = new OperationDataDefinition(); + operation.setName(operationName); + + handleOperationImplementation(operationDefinitionMap).ifPresent(operation::setImplementation); + if (operationDefinitionMap.containsKey(INPUTS.getElementName())) { + final Map<String, Object> interfaceInputs = + (Map<String, Object>) operationDefinitionMap.get(INPUTS.getElementName()); + operation.setInputs(handleInterfaceOperationInputs(interfaceInputs)); + } + + return operation; + } + + private ListDataDefinition<OperationInputDefinition> handleInterfaceOperationInputs( + final Map<String, Object> interfaceInputs) { + final ListDataDefinition<OperationInputDefinition> inputs = new ListDataDefinition<>(); + for (final Entry<String, Object> interfaceInput : interfaceInputs.entrySet()) { + final OperationInputDefinition operationInput = new OperationInputDefinition(); + operationInput.setName(interfaceInput.getKey()); + if (interfaceInput.getValue() instanceof Map) { + final LinkedHashMap<String, Object> inputPropertyValue = + (LinkedHashMap<String, Object>) 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<ArtifactDataDefinition> handleOperationImplementation( + final Map<String, Object> 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<String, InputDefinition> handleInputs(final Map<String, Object> interfaceDefinitionToscaMap) { + if (!interfaceDefinitionToscaMap.containsKey(INPUTS.getElementName())) { + return Collections.emptyMap(); + } + + final Either<Map<String, InputDefinition>, 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<String, Object> jsonInterfaces = toscaInterfaces.left().value(); Map<String, InterfaceDefinition> moduleInterfaces = new HashMap<>(); - Iterator<Entry<String, Object>> interfacesNameValue = jsonInterfaces.entrySet().iterator(); - while (interfacesNameValue.hasNext()) { - Entry<String, Object> interfaceNameValue = interfacesNameValue.next(); - Either<InterfaceDefinition, ResultStatusEnum> eitherInterface = createModuleInterface(interfaceNameValue - .getValue(), resource); + for (final Entry<String, Object> interfaceNameValue : jsonInterfaces.entrySet()) { + final Either<InterfaceDefinition, ResultStatusEnum> 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<InterfaceDefinition, ResultStatusEnum> createModuleInterface(Object interfaceJson, - Resource resource) { - final InterfaceDefinition interf = new InterfaceDefinition(); - Either<InterfaceDefinition, ResultStatusEnum> result = Either.left(interf); - + private Either<InterfaceDefinition, ResultStatusEnum> 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<String, Object> requirementJsonMap = (Map<String, Object>) interfaceJson; - final Map<String, OperationDataDefinition> operations = new HashMap<>(); - - for (final Entry<String, Object> 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<String, Object> interfaceInputs = (Map<String, Object>) 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<String, Object> entry) { - final ArtifactDataDefinition implementation = new ArtifactDataDefinition(); - final String artifactName = ((Map<String, String>) entry.getValue()).get(IMPLEMENTATION); - if (OperationArtifactUtil.artifactNameIsALiteralValue(artifactName)) { - implementation.setArtifactName(artifactName); - } else { - implementation.setArtifactName(QUOTE + artifactName + QUOTE); - } - return implementation; - } - - private ListDataDefinition<OperationInputDefinition> handleInterfaceInput( - final Map<String, Object> interfaceInputs) { - final ListDataDefinition<OperationInputDefinition> inputs = new ListDataDefinition<>(); - for (final Entry<String, Object> interfaceInput : interfaceInputs.entrySet()) { - final OperationInputDefinition operationInput = new OperationInputDefinition(); - operationInput.setName(interfaceInput.getKey()); - if (interfaceInput.getValue() instanceof Map) { - final LinkedHashMap<String, Object> inputPropertyValue = - (LinkedHashMap<String, Object>) 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<String, Object> entry) { - if(entry.getKey().equals(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName())) { - if (entry.getValue() instanceof String) { - return true; + if (interfaceJson instanceof Map) { + final Map<String, Object> interfaceJsonMap = (Map<String, Object>) interfaceJson; + final InterfaceDefinition interfaceDefinition = interfaceDefinitionHandler.create(interfaceJsonMap); + return Either.left(interfaceDefinition); } - throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML); - } - return false; - } - - private boolean entryContainsImplementationForAKnownOperation(final Entry<String, Object> 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<Map<String, InterfaceDefinition>, ResponseFormat> interfaceLifecycleTypes = interfaceOperationBusinessLogic - .getAllInterfaceLifecycleTypes(); - if (interfaceLifecycleTypes.isRight() || interfaceLifecycleTypes.left().value() == null) { - return false; - } - for (Entry<String, InterfaceDefinition> interfaceLifecycleType : interfaceLifecycleTypes.left().value() - .entrySet()) { - if (interfaceTypeAndOperationMatches(interfaceLifecycleType, interfaceType, operation)) { - return true; - } - } - return false; - } - - private boolean interfaceTypeAndOperationMatches(Entry<String, InterfaceDefinition> 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<String, Object> 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<String, Object> interfacesAsMap = getObjectAsMap(toscaInterfaceType); - Map<String, Object> operationsMap = (Map<String, Object>) interfacesAsMap.remove(OPERATIONS_KEY); + Map<String, Object> operationsMap = (Map<String, Object>) 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<String, Object> getInterfacesMap(Component component, - ComponentInstance componentInstance, - Map<String, InterfaceDefinition> interfaces, - Map<String, DataTypeDefinition> dataTypes, - boolean isAssociatedComponent, - boolean isServiceProxyInterface) { + public Map<String, Object> getInterfacesMap(final Component component, + final ComponentInstance componentInstance, + final Map<String, InterfaceDefinition> interfaces, + final Map<String, DataTypeDefinition> 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<String, OperationDataDefinition> operations = interfaceDefinition.getOperations(); - Map<String, Object> toscaOperations = new HashMap<>(); + Map<String, Object> toscaOperationMap = new HashMap<>(); String operationArtifactPath; for (Map.Entry<String, OperationDataDefinition> 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<String, Object> interfaceInputMap = createInterfaceInputMap(interfaceDefinition, dataTypes); + if (!interfaceInputMap.isEmpty()) { + toscaInterfaceDefinition.setInputs(interfaceInputMap); } - toscaInterfaceDefinition.setOperations(toscaOperations); Map<String, Object> interfaceDefAsMap = getObjectAsMap(toscaInterfaceDefinition); - Map<String, Object> operationsMap = (Map<String, Object>) interfaceDefAsMap.remove(OPERATIONS_KEY); + if (interfaceDefAsMap.containsKey(INPUTS.getElementName())) { + handleDefaults((Map<String, Object>) interfaceDefAsMap.get(INPUTS.getElementName())); + } + Map<String, Object> operationsMap = (Map<String, Object>) 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<String, Object> createInterfaceInputMap(final InterfaceDefinition interfaceDefinition, + final Map<String, DataTypeDefinition> allDataTypeMap) { + final Map<String, InputDataDefinition> inputMap = interfaceDefinition.getInputs(); + if (MapUtils.isEmpty(inputMap)) { + return Collections.emptyMap(); + } + final Map<String, Object> toscaInterfaceInputMap = new HashMap<>(); + for (final Entry<String, InputDataDefinition> 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<String, Object> operationsMap, String parentKey) { for (Map.Entry<String, Object> 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<String, Object> operationsMap) { + private void handleDefaults(Map<String, Object> operationsMap) { for (Map.Entry<String, Object> 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<String, Object> objectAsMap = obj instanceof Map ? (Map<String, Object>) 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<String, Object> operations; // ToscaLifecycleOperationDefinition <-> Object - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public Map<String, Object> getOperations() { - return operations; - } - -// public void setOperations(Map<String, Object> operations) { -// this.operations = operations; -// } + private Map<String, Object> operations; + private Map<String, Object> inputs; - public void setOperations(Map<String,Object> 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, |