diff options
author | vasraz <vasyl.razinkov@est.tech> | 2021-02-05 19:24:06 +0000 |
---|---|---|
committer | Christophe Closset <christophe.closset@intl.att.com> | 2021-02-24 08:03:45 +0000 |
commit | b6d953c506c08a5369c0be7242ef3ce3ec888452 (patch) | |
tree | dbe45662f4252e88df9161c917664ba578bcc7a3 | |
parent | b485c37b36ddb3ab5e8085c009b26e97c8e62d74 (diff) |
Implement Attributes/Outputs BE (part 2)
This commit includes support for:
- declare Attribute as Output
- undeclare Attribute as Output
- export 'Tosca Artifacts' with Attributes/Outputs
Change-Id: Iedfbf936e439fd2f7d252b660fe2c42b8d9b9113
Signed-off-by: Vasyl Razinkov <vasyl.razinkov@est.tech>
Issue-ID: SDC-3448
58 files changed, 2782 insertions, 718 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/AttributeDeclarationOrchestrator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/AttributeDeclarationOrchestrator.java new file mode 100644 index 0000000000..e023be4dec --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/AttributeDeclarationOrchestrator.java @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2021, Nordix Foundation. 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.components.attribute; + +import static org.apache.commons.collections.MapUtils.isNotEmpty; + +import fj.data.Either; +import java.util.Arrays; +import java.util.List; +import org.apache.commons.lang3.tuple.Pair; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstOutputsMap; +import org.openecomp.sdc.be.model.ComponentInstanceAttribOutput; +import org.openecomp.sdc.be.model.OutputDefinition; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.common.log.wrappers.Logger; + +@org.springframework.stereotype.Component("attributeDeclarationOrchestrator") +public class AttributeDeclarationOrchestrator { + + private static final Logger log = Logger.getLogger(AttributeDeclarationOrchestrator.class); + private final ComponentInstanceOutputAttributeDeclarator componentInstanceOutputAttributeDeclarator; + private final ComponentInstanceAttributeDeclarator componentInstanceAttributeDeclarator; + private final List<AttributeDeclarator> attributeDeclaratorsToOutput; + + public AttributeDeclarationOrchestrator(final ComponentInstanceOutputAttributeDeclarator componentInstanceOutputAttributeDeclarator, + final ComponentInstanceAttributeDeclarator componentInstanceAttributeDeclarator) { + this.componentInstanceOutputAttributeDeclarator = componentInstanceOutputAttributeDeclarator; + this.componentInstanceAttributeDeclarator = componentInstanceAttributeDeclarator; + attributeDeclaratorsToOutput = Arrays.asList(componentInstanceOutputAttributeDeclarator, componentInstanceAttributeDeclarator); + } + + public Either<List<OutputDefinition>, StorageOperationStatus> declareAttributesToOutputs(final Component component, + final ComponentInstOutputsMap componentInstOutputsMap) { + AttributeDeclarator attributeDeclarator = getAttributeDeclarator(componentInstOutputsMap); + Pair<String, List<ComponentInstanceAttribOutput>> attributesToDeclare = componentInstOutputsMap.resolveAttributesToDeclare(); + return attributeDeclarator.declareAttributesAsOutputs(component, attributesToDeclare.getLeft(), attributesToDeclare.getRight()); + } + + public StorageOperationStatus unDeclareAttributesAsOutputs(final Component component, + final OutputDefinition outputToDelete) { + log.debug("#unDeclareAttributesAsOutputs - removing output declaration for output {} on component {}", outputToDelete.getName(), + component.getUniqueId()); + for (final AttributeDeclarator attributeDeclarator : attributeDeclaratorsToOutput) { + final StorageOperationStatus storageOperationStatus = attributeDeclarator.unDeclareAttributesAsOutputs(component, outputToDelete); + if (StorageOperationStatus.OK != storageOperationStatus) { + log.debug("#unDeclareAttributesAsOutputs - failed to remove output declaration for output {} on component {}. reason {}", + outputToDelete.getName(), component.getUniqueId(), storageOperationStatus); + return storageOperationStatus; + } + } + return StorageOperationStatus.OK; + + } + + private AttributeDeclarator getAttributeDeclarator(final ComponentInstOutputsMap componentInstOutputsMap) { + if (isNotEmpty(componentInstOutputsMap.getComponentInstanceOutputsMap())) { + return componentInstanceOutputAttributeDeclarator; + } + if (isNotEmpty(componentInstOutputsMap.getComponentInstanceAttributes())) { + return componentInstanceAttributeDeclarator; + } + throw new IllegalStateException("there are no properties selected for declaration"); + + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/AttributeDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/AttributeDeclarator.java new file mode 100644 index 0000000000..3fa68fa00c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/AttributeDeclarator.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2021, Nordix Foundation. 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.components.attribute; + +import fj.data.Either; +import java.util.List; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstanceAttribOutput; +import org.openecomp.sdc.be.model.OutputDefinition; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; + +public interface AttributeDeclarator { + + /** + * creates a list of outputs from the given list of attributes and updates the attributes accordingly + * + * @param component the container + * @param propertiesOwnerId the id of the owner of the attributes to declare (e.g ComponentInstance, Policy, Group + * etc) + * @param attribsToDeclare the list of attributes that are being declared as outputs + * @return the list of outputs that were created from the given attributes + */ + Either<List<OutputDefinition>, StorageOperationStatus> declareAttributesAsOutputs(final Component component, + final String propertiesOwnerId, + final List<ComponentInstanceAttribOutput> attribsToDeclare); + + /** + * returns the values of declared attributes to each original state before it was declared as an input. this + * function is to be called when an input, that was created by declaring a property, is deleted. + * + * @param component the container of the input to be deleted + * @param output the input to be deleted + */ + StorageOperationStatus unDeclareAttributesAsOutputs(final Component component, final OutputDefinition output); +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/ComponentAttributeDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/ComponentAttributeDeclarator.java new file mode 100644 index 0000000000..56dec5d93a --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/ComponentAttributeDeclarator.java @@ -0,0 +1,140 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2021, Nordix Foundation. 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.components.attribute; + +import fj.data.Either; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import org.apache.commons.collections.CollectionUtils; +import org.openecomp.sdc.be.components.impl.AttributeBusinessLogic; +import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.GetOutputValueDataDefinition; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.AttributeDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.OutputDefinition; +import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.AttributeOperation; + +@org.springframework.stereotype.Component +public class ComponentAttributeDeclarator extends DefaultAttributeDeclarator<Component, AttributeDataDefinition> { + + private final ToscaOperationFacade toscaOperationFacade; + private final AttributeBusinessLogic attributeBusinessLogic; + + public ComponentAttributeDeclarator(final ComponentsUtils componentsUtils, + final AttributeOperation attributeOperation, + final ToscaOperationFacade toscaOperationFacade, + final AttributeBusinessLogic attributeBusinessLogic) { +// super(componentsUtils, attributeOperation); + this.toscaOperationFacade = toscaOperationFacade; + this.attributeBusinessLogic = attributeBusinessLogic; + } + + @Override + public AttributeDataDefinition createDeclaredAttribute(final AttributeDataDefinition attributeDataDefinition) { + return new AttributeDataDefinition(attributeDataDefinition); + } + + @Override + public Either<?, StorageOperationStatus> updateAttributesValues(final Component component, + final String propertiesOwnerId, + final List<AttributeDataDefinition> attributetypeList) { + if (CollectionUtils.isNotEmpty(attributetypeList)) { + for (AttributeDataDefinition attribute : attributetypeList) { + Either<AttributeDefinition, StorageOperationStatus> + storageStatus = toscaOperationFacade + .updateAttributeOfComponent(component, new AttributeDefinition(attribute)); + if (storageStatus.isRight()) { + return Either.right(storageStatus.right().value()); + } + } + } + return Either.left(attributetypeList); + } + + @Override + public Optional<Component> resolvePropertiesOwner(final Component component, final String propertiesOwnerId) { + return Optional.of(component); + } + + @Override + public StorageOperationStatus unDeclareAttributesAsOutputs(final Component component, + final OutputDefinition output) { + AttributeDefinition attributeDefinition = new AttributeDefinition(output); + + // TODO - do we need this one + if (attributeBusinessLogic.isAttributeUsedByOperation(component, attributeDefinition)) { + return StorageOperationStatus.DECLARED_INPUT_USED_BY_OPERATION; + } + + Optional<AttributeDefinition> attributeToUpdateCandidate = + getDeclaredAttributeByOutputId(component, output.getUniqueId()); + + if (attributeToUpdateCandidate.isPresent()) { + AttributeDefinition attributeToUpdate = attributeToUpdateCandidate.get(); + return unDeclareOutput(component, output, attributeToUpdate); + } + + return StorageOperationStatus.OK; + } + + private StorageOperationStatus unDeclareOutput(final Component component, + final OutputDefinition output, + final AttributeDefinition attributeToUpdate) { + prepareValueBeforeDelete(output, attributeToUpdate, Collections.emptyList()); + attributeToUpdate.setValue(output.getDefaultValue()); + Either<AttributeDefinition, StorageOperationStatus> status = toscaOperationFacade + .updateAttributeOfComponent(component, attributeToUpdate); + if (status.isRight()) { + return status.right().value(); + } + + return StorageOperationStatus.OK; + } + + private Optional<AttributeDefinition> getDeclaredAttributeByOutputId(final Component component, final String outputId) { + List<AttributeDefinition> attributes = component.getAttributes(); + + if (CollectionUtils.isEmpty(attributes)) { + return Optional.empty(); + } + + for (AttributeDefinition attributeDefinition : attributes) { + List<GetOutputValueDataDefinition> getOutputValues = attributeDefinition.getGetOutputValues(); + if (CollectionUtils.isEmpty(getOutputValues)) { + continue; + } + + Optional<GetOutputValueDataDefinition> getOutputCandidate = + getOutputValues.stream().filter(getOutput -> getOutput.getOutputId().equals(outputId)).findAny(); + + if (getOutputCandidate.isPresent()) { + return Optional.of(attributeDefinition); + } + } + + return Optional.empty(); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/ComponentInstanceAttributeDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/ComponentInstanceAttributeDeclarator.java new file mode 100644 index 0000000000..8981515ea4 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/ComponentInstanceAttributeDeclarator.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2021, Nordix Foundation. 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.components.attribute; + +import fj.data.Either; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.apache.commons.collections4.CollectionUtils; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; +import org.openecomp.sdc.be.model.OutputDefinition; +import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.AttributeOperation; +import org.openecomp.sdc.common.log.wrappers.Logger; + +@org.springframework.stereotype.Component +public class ComponentInstanceAttributeDeclarator extends + DefaultAttributeDeclarator<ComponentInstance, ComponentInstanceAttribute> { + + private static final Logger log = Logger.getLogger(ComponentInstanceAttributeDeclarator.class); + private ToscaOperationFacade toscaOperationFacade; + private ComponentInstanceBusinessLogic componentInstanceBusinessLogic; + + public ComponentInstanceAttributeDeclarator(final ComponentsUtils componentsUtils, + final AttributeOperation attributeOperation, + final ToscaOperationFacade toscaOperationFacade, + final ComponentInstanceBusinessLogic componentInstanceBusinessLogic) { +// super(componentsUtils, attributeOperation); + this.toscaOperationFacade = toscaOperationFacade; + this.componentInstanceBusinessLogic = componentInstanceBusinessLogic; + } + + @Override + public ComponentInstanceAttribute createDeclaredAttribute(AttributeDataDefinition attributeDataDefinition) { + return new ComponentInstanceAttribute(attributeDataDefinition); + } + + @Override + public Either<?, StorageOperationStatus> updateAttributesValues(final Component component, + final String cmptInstanceId, + final List<ComponentInstanceAttribute> attributetypeList) { + log.debug("#updateAttributesValues - updating component instance attributes for instance {} on component {}", cmptInstanceId, + component.getUniqueId()); + Map<String, List<ComponentInstanceAttribute>> instAttributes = Collections.singletonMap(cmptInstanceId, attributetypeList); + return toscaOperationFacade.addComponentInstanceAttributesToComponent(component, instAttributes); + } + + @Override + public Optional<ComponentInstance> resolvePropertiesOwner(final Component component, final String propertiesOwnerId) { + log.debug("#resolvePropertiesOwner - fetching component instance {} of component {}", propertiesOwnerId, component.getUniqueId()); + return component.getComponentInstanceById(propertiesOwnerId); + } + + @Override + public StorageOperationStatus unDeclareAttributesAsOutputs(final Component component, final OutputDefinition output) { + + final List<ComponentInstanceAttribute> componentInstancePropertiesDeclaredAsInput + = componentInstanceBusinessLogic.getComponentInstanceAttributesByOutputId(component, output.getUniqueId()); + if (CollectionUtils.isEmpty(componentInstancePropertiesDeclaredAsInput)) { + return StorageOperationStatus.OK; + } + componentInstancePropertiesDeclaredAsInput.forEach(cmptInstanceProperty -> prepareValueBeforeDelete(output, + cmptInstanceProperty, cmptInstanceProperty.getPath())); + return toscaOperationFacade.updateComponentInstanceAttributes(component, + componentInstancePropertiesDeclaredAsInput.get(0).getComponentInstanceId(), + componentInstancePropertiesDeclaredAsInput); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/ComponentInstanceOutputAttributeDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/ComponentInstanceOutputAttributeDeclarator.java new file mode 100644 index 0000000000..7ded7c1209 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/ComponentInstanceOutputAttributeDeclarator.java @@ -0,0 +1,92 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2021, Nordix Foundation. 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.components.attribute; + +import static org.apache.commons.collections4.CollectionUtils.isEmpty; + +import fj.data.Either; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceOutput; +import org.openecomp.sdc.be.model.OutputDefinition; +import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.AttributeOperation; +import org.openecomp.sdc.common.log.wrappers.Logger; + +@org.springframework.stereotype.Component +public class ComponentInstanceOutputAttributeDeclarator extends DefaultAttributeDeclarator<ComponentInstance, ComponentInstanceOutput> { + + private static final Logger log = Logger.getLogger(ComponentInstanceOutputAttributeDeclarator.class); + private final ToscaOperationFacade toscaOperationFacade; + private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic; + + public ComponentInstanceOutputAttributeDeclarator(final ComponentsUtils componentsUtils, + final AttributeOperation attributeOperation, + final ToscaOperationFacade toscaOperationFacade, + final ComponentInstanceBusinessLogic componentInstanceBusinessLogic) { +// super(componentsUtils, attributeOperation); + this.toscaOperationFacade = toscaOperationFacade; + this.componentInstanceBusinessLogic = componentInstanceBusinessLogic; + } + + @Override + public ComponentInstanceOutput createDeclaredAttribute(final AttributeDataDefinition attributeDataDefinition) { + return new ComponentInstanceOutput(attributeDataDefinition); + } + + @Override + public Either<?, StorageOperationStatus> updateAttributesValues(final Component component, + final String cmptInstanceId, + final List<ComponentInstanceOutput> attributetypeList) { + log.debug("#updateAttributesValues - updating component instance outputs for instance {} on component {}", cmptInstanceId, + component.getUniqueId()); + Map<String, List<ComponentInstanceOutput>> instAttributes = Collections.singletonMap(cmptInstanceId, attributetypeList); + return toscaOperationFacade.addComponentInstanceOutputsToComponent(component, instAttributes); + } + + @Override + public Optional<ComponentInstance> resolvePropertiesOwner(final Component component, final String propertiesOwnerId) { + log.debug("#resolvePropertiesOwner - fetching component instance {} of component {}", propertiesOwnerId, component.getUniqueId()); + return component.getComponentInstanceById(propertiesOwnerId); + } + + public StorageOperationStatus unDeclareAttributesAsOutputs(final Component component, final OutputDefinition output) { + List<ComponentInstanceOutput> componentInstanceInputsByInputId = componentInstanceBusinessLogic + .getComponentInstanceOutputsByOutputId(component, output + .getUniqueId()); + if (isEmpty(componentInstanceInputsByInputId)) { + return StorageOperationStatus.OK; + } + componentInstanceInputsByInputId + .forEach(cmptInstanceInput -> prepareValueBeforeDelete(output, cmptInstanceInput, cmptInstanceInput.getPath())); + return toscaOperationFacade.updateComponentInstanceOutputs(component, componentInstanceInputsByInputId.get(0).getComponentInstanceId(), + componentInstanceInputsByInputId); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/DefaultAttributeDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/DefaultAttributeDeclarator.java new file mode 100644 index 0000000000..e53a362508 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/DefaultAttributeDeclarator.java @@ -0,0 +1,483 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2021, Nordix Foundation. 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.components.attribute; + +import static org.openecomp.sdc.common.api.Constants.GET_ATTRIBUTE; + +import com.google.gson.Gson; +import fj.data.Either; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONObject; +import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.GetOutputValueDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertiesOwner; +import org.openecomp.sdc.be.model.AttributeDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstanceAttribOutput; +import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement; +import org.openecomp.sdc.be.model.OutputDefinition; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; +import org.yaml.snakeyaml.Yaml; + +public abstract class DefaultAttributeDeclarator<PROPERTYOWNER extends PropertiesOwner, ATTRIBUTETYPE extends AttributeDataDefinition> + implements AttributeDeclarator { + + private static final Logger log = Logger.getLogger(DefaultAttributeDeclarator.class); + private static final short LOOP_PROTECTION_LEVEL = 10; + private static final String UNDERSCORE = "_"; + private final Gson gson = new Gson(); + + protected DefaultAttributeDeclarator() { + } + + @Override + public Either<List<OutputDefinition>, StorageOperationStatus> declareAttributesAsOutputs(final Component component, + final String propertiesOwnerId, + final List<ComponentInstanceAttribOutput> attribsToDeclare) { + log.debug( + "#declarePropertiesAsInputs - declaring properties as inputs for component {} from properties owner {}", + component.getUniqueId(), propertiesOwnerId); + return resolvePropertiesOwner(component, propertiesOwnerId) + .map(propertyOwner -> declareAttributesAsOutputs(component, propertyOwner, attribsToDeclare)) + .orElse(Either.right(onPropertiesOwnerNotFound(component.getUniqueId(), propertiesOwnerId))); + } + + protected abstract ATTRIBUTETYPE createDeclaredAttribute(final AttributeDataDefinition attributeDataDefinition); + + protected abstract Either<?, StorageOperationStatus> updateAttributesValues(final Component component, + final String propertiesOwnerId, + final List<ATTRIBUTETYPE> attributetypeList); + + protected abstract Optional<PROPERTYOWNER> resolvePropertiesOwner(final Component component, final String propertiesOwnerId); + + private StorageOperationStatus onPropertiesOwnerNotFound(final String componentId, final String propertiesOwnerId) { + log.debug("#declarePropertiesAsInputs - properties owner {} was not found on component {}", propertiesOwnerId, + componentId); + return StorageOperationStatus.NOT_FOUND; + } + + private Either<List<OutputDefinition>, StorageOperationStatus> declareAttributesAsOutputs(final Component component, + final PROPERTYOWNER propertiesOwner, + final List<ComponentInstanceAttribOutput> attributesToDeclare) { + final AttributesDeclarationData attributesDeclarationData + = createOutputsAndOverrideAttributesValues(component, propertiesOwner, attributesToDeclare); + return updateAttributesValues(component, propertiesOwner.getUniqueId(), + attributesDeclarationData.getAttributesToUpdate()) + .left() + .map(updatePropsRes -> attributesDeclarationData.getOutputsToCreate()); + } + + private AttributesDeclarationData createOutputsAndOverrideAttributesValues(final Component component, + final PROPERTYOWNER propertiesOwner, + final List<ComponentInstanceAttribOutput> attributesToDeclare) { + final List<ATTRIBUTETYPE> declaredAttributes = new ArrayList<>(); + final List<OutputDefinition> createdInputs = attributesToDeclare.stream() + .map(attributeOutput -> declareAttributeOutput(component, propertiesOwner, declaredAttributes, attributeOutput)) + .collect(Collectors.toList()); + return new AttributesDeclarationData(createdInputs, declaredAttributes); + } + + private OutputDefinition declareAttributeOutput(final Component component, + final PROPERTYOWNER propertiesOwner, + final List<ATTRIBUTETYPE> declaredAttributes, + final ComponentInstanceAttribOutput attribOutput) { + final AttributeDataDefinition attribute = resolveAttribute(declaredAttributes, attribOutput); + final OutputDefinition outputDefinition = createOutput(component, propertiesOwner, attribOutput, attribute); + final ATTRIBUTETYPE declaredAttribute = createDeclaredAttribute(attribute); + if (!declaredAttributes.contains(declaredAttribute)) { + declaredAttributes.add(declaredAttribute); + } + return outputDefinition; + } + + private OutputDefinition createOutput(final Component component, + final PROPERTYOWNER propertiesOwner, + final ComponentInstanceAttribOutput attribOutput, + final AttributeDataDefinition attributeDataDefinition) { + String generatedInputPrefix = propertiesOwner.getNormalizedName(); + if (propertiesOwner.getUniqueId().equals(attribOutput.getParentUniqueId())) { + //Creating input from property create on self using add property..Do not add the prefix + generatedInputPrefix = null; + } + + final String generatedOutputName = generateOutputName(generatedInputPrefix, attribOutput); + log.debug("createInput: propOwner.uniqueId={}, attribOutput.parentUniqueId={}", + propertiesOwner.getUniqueId(), attribOutput.getParentUniqueId()); + return createOutputFromAttribute(component.getUniqueId(), propertiesOwner, generatedOutputName, attribOutput, attributeDataDefinition); + } + + private String generateOutputName(final String outputName, final ComponentInstanceAttribOutput attribOutput) { + final String declaredInputName; + final String[] parsedPropNames = attribOutput.getParsedAttribNames(); + + if (parsedPropNames != null) { + declaredInputName = handleInputName(outputName, parsedPropNames); + } else { + final String[] propName = {attribOutput.getName()}; + declaredInputName = handleInputName(outputName, propName); + } + + return declaredInputName; + } + + private String handleInputName(final String outputName, final String[] parsedPropNames) { + final StringBuilder prefix = new StringBuilder(); + int startingIndex; + + if (Objects.isNull(outputName)) { + prefix.append(parsedPropNames[0]); + startingIndex = 1; + } else { + prefix.append(outputName); + startingIndex = 0; + } + + while (startingIndex < parsedPropNames.length) { + prefix.append(UNDERSCORE); + prefix.append(parsedPropNames[startingIndex]); + startingIndex++; + } + + return prefix.toString(); + } + + private AttributeDataDefinition resolveAttribute(final List<ATTRIBUTETYPE> attributesToCreate, + final ComponentInstanceAttribOutput attribOutput) { + final Optional<ATTRIBUTETYPE> resolvedAttribute = attributesToCreate.stream() + .filter(p -> p.getName().equals(attribOutput.getName())) + .findFirst(); + return resolvedAttribute.isPresent() ? resolvedAttribute.get() : attribOutput; + } + + OutputDefinition createOutputFromAttribute(final String componentId, + final PROPERTYOWNER propertiesOwner, + final String outputName, + final ComponentInstanceAttribOutput attributeOutput, + final AttributeDataDefinition attribute) { + final String attributesName = attributeOutput.getAttributesName(); + final AttributeDefinition selectedAttrib = attributeOutput.getOutput(); + final String[] parsedAttribNames = attributeOutput.getParsedAttribNames(); + OutputDefinition outputDefinition; + boolean complexProperty = false; + if (attributesName != null && !attributesName.isEmpty() && selectedAttrib != null) { + complexProperty = true; + outputDefinition = new OutputDefinition(selectedAttrib); + outputDefinition.setDefaultValue(selectedAttrib.getValue()); + } else { + outputDefinition = new OutputDefinition(attribute); + outputDefinition.setDefaultValue(attribute.getValue()); + } + outputDefinition.setName(outputName); + outputDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(componentId, outputDefinition.getName())); + outputDefinition.setOutputPath(attributesName); + outputDefinition.setInstanceUniqueId(propertiesOwner.getUniqueId()); + outputDefinition.setAttributeId(attributeOutput.getUniqueId()); + outputDefinition.setAttributes(Arrays.asList(attributeOutput)); + + if (attribute instanceof IComponentInstanceConnectedElement) { + ((IComponentInstanceConnectedElement) attribute).setComponentInstanceId(propertiesOwner.getUniqueId()); + ((IComponentInstanceConnectedElement) attribute).setComponentInstanceName(propertiesOwner.getName()); + } + changeOutputValueToGetAttributeValue(outputName, parsedAttribNames, outputDefinition, attribute, complexProperty); + return outputDefinition; + } + + private void changeOutputValueToGetAttributeValue(final String outputName, + final String[] parsedPropNames, + final OutputDefinition output, + final AttributeDataDefinition attributeDataDefinition, + final boolean complexProperty) { + JSONObject jsonObject = new JSONObject(); + final String value = attributeDataDefinition.getValue(); + if (StringUtils.isEmpty(value)) { + if (complexProperty) { + jsonObject = createJSONValueForProperty(parsedPropNames.length - 1, parsedPropNames, jsonObject, outputName); + attributeDataDefinition.setValue(jsonObject.toJSONString()); + } else { + jsonObject.put( + GET_ATTRIBUTE, Arrays.asList(output.getAttributes().get(0).getComponentInstanceName(), attributeDataDefinition.getName())); + output.setValue(jsonObject.toJSONString()); + } + } else { + final Object objValue = new Yaml().load(value); + if (objValue instanceof Map || objValue instanceof List) { + if (!complexProperty) { + jsonObject.put( + GET_ATTRIBUTE, Arrays.asList(output.getAttributes().get(0).getComponentInstanceName(), attributeDataDefinition.getName())); + output.setValue(jsonObject.toJSONString()); + } else { + final Map<String, Object> mappedToscaTemplate = (Map<String, Object>) objValue; + createOutputValue(mappedToscaTemplate, 1, parsedPropNames, outputName); + + output.setValue(gson.toJson(mappedToscaTemplate)); + } + + } else { + jsonObject.put( + GET_ATTRIBUTE, Arrays.asList(output.getAttributes().get(0).getComponentInstanceName(), attributeDataDefinition.getName())); + output.setValue(jsonObject.toJSONString()); + } + } + + if (CollectionUtils.isEmpty(attributeDataDefinition.getGetOutputValues())) { + attributeDataDefinition.setGetOutputValues(new ArrayList<>()); + } + final List<GetOutputValueDataDefinition> getOutputValues = attributeDataDefinition.getGetOutputValues(); + + final GetOutputValueDataDefinition getOutputValueDataDefinition = new GetOutputValueDataDefinition(); + getOutputValueDataDefinition.setOutputId(output.getUniqueId()); + getOutputValueDataDefinition.setOutputName(output.getName()); + getOutputValues.add(getOutputValueDataDefinition); + } + + private JSONObject createJSONValueForProperty(int i, final String[] parsedPropNames, final JSONObject ooj, final String outputName) { + + while (i >= 1) { + if (i == parsedPropNames.length - 1) { + final JSONObject jobProp = new JSONObject(); + jobProp.put(GET_ATTRIBUTE, outputName); + ooj.put(parsedPropNames[i], jobProp); + i--; + return createJSONValueForProperty(i, parsedPropNames, ooj, outputName); + } else { + final JSONObject res = new JSONObject(); + res.put(parsedPropNames[i], ooj); + i--; + return createJSONValueForProperty(i, parsedPropNames, res, outputName); + } + } + + return ooj; + } + + private Map<String, Object> createOutputValue(final Map<String, Object> lhm1, int index, final String[] outputNames, final String outputName) { + while (index < outputNames.length) { + if (lhm1.containsKey(outputNames[index])) { + final Object value = lhm1.get(outputNames[index]); + if (value instanceof Map) { + if (index == outputNames.length - 1) { + return (Map<String, Object>) ((Map) value).put(GET_ATTRIBUTE, outputName); + } else { + return createOutputValue((Map) value, ++index, outputNames, outputName); + } + } else { + final Map<String, Object> jobProp = new HashMap<>(); + if (index == outputNames.length - 1) { + jobProp.put(GET_ATTRIBUTE, outputName); + lhm1.put(outputNames[index], jobProp); + return lhm1; + } else { + lhm1.put(outputNames[index], jobProp); + return createOutputValue(jobProp, ++index, outputNames, outputName); + } + } + } else { + final Map<String, Object> jobProp = new HashMap<>(); + lhm1.put(outputNames[index], jobProp); + if (index == outputNames.length - 1) { + jobProp.put(GET_ATTRIBUTE, outputName); + return jobProp; + } else { + return createOutputValue(jobProp, ++index, outputNames, outputName); + } + } + } + return lhm1; + } + + private class AttributesDeclarationData { + + private final List<OutputDefinition> outputsToCreate; + private final List<ATTRIBUTETYPE> attributesToUpdate; + + AttributesDeclarationData(final List<OutputDefinition> outputsToCreate, + final List<ATTRIBUTETYPE> attributesToUpdate) { + this.outputsToCreate = outputsToCreate; + this.attributesToUpdate = attributesToUpdate; + } + + List<OutputDefinition> getOutputsToCreate() { + return outputsToCreate; + } + + List<ATTRIBUTETYPE> getAttributesToUpdate() { + return attributesToUpdate; + } + } + + Either<OutputDefinition, ResponseFormat> prepareValueBeforeDelete(final OutputDefinition inputForDelete, + final AttributeDataDefinition inputValue, + final List<String> pathOfComponentInstances) { + final Either<OutputDefinition, ResponseFormat> deleteEither = prepareValueBeforeDelete(inputForDelete, inputValue); + +// Either<String, JanusGraphOperationStatus> findDefaultValue = propertyOperation +// .findDefaultValueFromSecondPosition(pathOfComponentInstances, inputValue.getUniqueId(), +// (String) inputValue.get_default()); +// if (findDefaultValue.isRight()) { +// deleteEither = Either.right(componentsUtils.getResponseFormat(componentsUtils +// .convertFromStorageResponse( +// DaoStatusConverter.convertJanusGraphStatusToStorageStatus(findDefaultValue.right().value())))); +// return deleteEither; +// +// } +// String defaultValue = findDefaultValue.left().value(); +// inputValue.set_default(defaultValue); +// log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue); + return deleteEither; + } + + private Either<OutputDefinition, ResponseFormat> prepareValueBeforeDelete(final OutputDefinition outputForDelete, + final AttributeDataDefinition outputValue) { + final Either<OutputDefinition, ResponseFormat> deleteEither = Either.left(outputForDelete); + String value = outputValue.getValue(); + final Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(value); + + resetOutputName(mappedToscaTemplate, outputForDelete.getName()); + + value = ""; + if (MapUtils.isNotEmpty(mappedToscaTemplate)) { + final Either result = cleanNestedMap(mappedToscaTemplate, true); + Map modifiedMappedToscaTemplate = mappedToscaTemplate; + if (result.isLeft()) { + modifiedMappedToscaTemplate = (Map) result.left().value(); + } else { + log.warn("Map cleanup failed -> {}", result.right().value()); //continue, don't break operation + } + value = gson.toJson(modifiedMappedToscaTemplate); + } + outputValue.setValue(value); + + final List<GetOutputValueDataDefinition> getInputsValues = outputValue.getGetOutputValues(); + if (getInputsValues != null && !getInputsValues.isEmpty()) { + final Optional<GetOutputValueDataDefinition> op = + getInputsValues.stream().filter(gi -> gi.getOutputId().equals(outputForDelete.getUniqueId())).findAny(); + op.ifPresent(getInputsValues::remove); + } + outputValue.setGetOutputValues(getInputsValues); + return deleteEither; + } + + private void resetOutputName(final Map<String, Object> lhm1, final String outputName) { + for (final Map.Entry<String, Object> entry : lhm1.entrySet()) { + final String key = entry.getKey(); + final Object value = entry.getValue(); + if (value instanceof String && ((String) value).equalsIgnoreCase(outputName) && GET_ATTRIBUTE.equals(key)) { + lhm1.remove(key); + } else if (value instanceof Map) { + final Map<String, Object> subMap = (Map<String, Object>) value; + resetOutputName(subMap, outputName); + } else if (value instanceof List && ((List) value).contains(outputName) && GET_ATTRIBUTE.equals(key)) { + lhm1.remove(key); + } + } + } + + private Either cleanNestedMap(Map mappedToscaTemplate, final boolean deepClone) { + if (MapUtils.isNotEmpty(mappedToscaTemplate)) { + if (deepClone) { + if (!(mappedToscaTemplate instanceof HashMap)) { + return Either.right( + "expecting mappedToscaTemplate as HashMap ,recieved " + mappedToscaTemplate.getClass() + .getSimpleName()); + } else { + mappedToscaTemplate = (HashMap) ((HashMap) mappedToscaTemplate).clone(); + } + } + return Either.left((Map) cleanEmptyNestedValuesInMap(mappedToscaTemplate, LOOP_PROTECTION_LEVEL)); + } else { + log.debug("mappedToscaTemplate is empty "); + return Either.right("mappedToscaTemplate is empty "); + } + } + + /* Mutates the object + * Tail recurse -> traverse the tosca elements and remove nested empty map properties + * this only handles nested maps, other objects are left untouched (even a Set containing a map) since behaviour is unexpected + * + * @param toscaElement - expected map of tosca values + * @return mutated @param toscaElement , where empty maps are deleted , return null for empty map. + **/ + private Object cleanEmptyNestedValuesInMap(final Object toscaElement, short loopProtectionLevel) { + if (loopProtectionLevel <= 0 || toscaElement == null || !(toscaElement instanceof Map)) { + return toscaElement; + } + if (MapUtils.isNotEmpty((Map) toscaElement)) { + Object ret; + final Set<Object> keysToRemove = new HashSet<>(); // use different set to avoid ConcurrentModificationException + for (final Object key : ((Map) toscaElement).keySet()) { + final Object value = ((Map) toscaElement).get(key); + ret = cleanEmptyNestedValuesInMap(value, --loopProtectionLevel); + if (ret == null) { + keysToRemove.add(key); + } + } + final Collection set = ((Map) toscaElement).keySet(); + if (CollectionUtils.isNotEmpty(set)) { + set.removeAll(keysToRemove); + } + + if (isEmptyNestedMap(toscaElement)) { + return null; + } + } else { + return null; + } + return toscaElement; + } + + /** + * @param element + * @return true if map nested maps are all empty, ignores other collection objects + */ + private boolean isEmptyNestedMap(final Object element) { + boolean isEmpty = true; + if (element != null) { + if (element instanceof Map) { + if (MapUtils.isNotEmpty((Map) element)) { + for (final Object key : ((Map) (element)).keySet()) { + Object value = ((Map) (element)).get(key); + isEmpty &= isEmptyNestedMap(value); + } + } + } else { + isEmpty = false; + } + } + return isEmpty; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/GetOutputUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/GetOutputUtils.java new file mode 100644 index 0000000000..0565bc6c8f --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/attribute/GetOutputUtils.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2021, Nordix Foundation. 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.components.attribute; + +import org.openecomp.sdc.be.datatypes.elements.GetOutputValueDataDefinition; + +public class GetOutputUtils { + + private GetOutputUtils() { + } + + public static boolean isGetOutputValueForOutput(GetOutputValueDataDefinition outputData, String outputId) { + return outputData.getOutputId().equals(outputId) + || (outputData.getGetOutputIndex() != null && outputData.getGetOutputIndex().getOutputId().equals(outputId)); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/AttributeBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/AttributeBusinessLogic.java index 81e06a2138..a44ed3c8c7 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/AttributeBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/AttributeBusinessLogic.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; @@ -35,6 +36,7 @@ import org.openecomp.sdc.be.model.AttributeDefinition; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentParametersView; import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation; @@ -406,5 +408,38 @@ public class AttributeBusinessLogic extends BaseBusinessLogic { return Either.left(status.left().value().getAttributes()); } + public boolean isAttributeUsedByOperation(Component component, + AttributeDefinition propertyDefinitionEntry) { + // TODO - do we need this one + return false; + +// // Component's own interfaces +// Map<String, InterfaceDefinition> interfaces = component.getInterfaces(); +// if(MapUtils.isNotEmpty(interfaces)){ +// for(Map.Entry<String, InterfaceDefinition> interfaceEntry : interfaces.entrySet()) { +// if (isPropertyExistInOperationInterface(propertyDefinitionEntry, interfaceEntry.getValue())) { +// return true; +// } +// } +// } +// +// // Component's child's component interfaces +// if(isPropertyUsedInCIInterfaces(component.getComponentInstancesInterfaces(), propertyDefinitionEntry)){ +// return true; +// } +// +// // Component's parent's component interfaces +// Either<List<Component>, StorageOperationStatus> componentList = toscaOperationFacade.getParentComponents(component.getUniqueId()); +// if(componentList.isLeft()){ +// for (Component parentComponent : componentList.left().value()) { +// if(isPropertyUsedInCIInterfaces(parentComponent.getComponentInstancesInterfaces(), propertyDefinitionEntry)){ +// return true; +// } +// } +// } +// +// return false; + } + } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java index d1df40c091..c7da584fe8 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java @@ -57,6 +57,7 @@ import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.model.ArtifactDefinition; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstInputsMap; +import org.openecomp.sdc.be.model.ComponentInstOutputsMap; import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.ComponentParametersView; @@ -130,7 +131,7 @@ public abstract class BaseBusinessLogic { DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance(); - public BaseBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, + protected BaseBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation, IGroupTypeOperation groupTypeOperation, InterfaceOperation interfaceOperation, InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactsOperations artifactToscaOperation) { this.elementDao = elementDao; @@ -350,7 +351,7 @@ public abstract class BaseBusinessLogic { String innerType = getInnerType(property); // Specific Update Logic Either<Object, Boolean> isValid = - propertyOperation.validateAndUpdatePropertyValue(propertyType, (String) property.getValue(), true, + propertyOperation.validateAndUpdatePropertyValue(propertyType, property.getValue(), true, innerType, allDataTypes); String newValue = property.getValue(); if (isValid.isRight()) { @@ -389,7 +390,7 @@ public abstract class BaseBusinessLogic { public void validateCanWorkOnComponent(Component component, String userId) { ActionStatus actionStatus = ActionStatus.RESTRICTED_OPERATION; // verify resource is not archived - if (component.isArchived() == true){ + if (Boolean.TRUE.equals(component.isArchived())){ actionStatus = ActionStatus.COMPONENT_IS_ARCHIVED; throw new ByActionStatusComponentException(actionStatus, component.getName()); } @@ -420,7 +421,6 @@ public abstract class BaseBusinessLogic { } - ComponentTypeEnum getComponentTypeByParentComponentType(ComponentTypeEnum parentComponentType) { switch (parentComponentType) { case SERVICE: @@ -434,8 +434,6 @@ public abstract class BaseBusinessLogic { return null; } - - protected Map<String, DataTypeDefinition> getAllDataTypes(ApplicationDataTypeCache applicationDataTypeCache) { Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); if (allDataTypes.isRight()) { @@ -463,7 +461,7 @@ public abstract class BaseBusinessLogic { if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) { ImmutablePair<String, Boolean> propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, dataTypes); innerType = propertyInnerTypeValid.getLeft(); - if (!propertyInnerTypeValid.getRight()) { + if (Boolean.FALSE.equals(propertyInnerTypeValid.getRight())) { log.info("Invalid inner type for property '{}' type '{}', dataTypeCount '{}'", property.getName(), property.getType(), dataTypes.size()); ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName()); return Either.right(responseFormat); @@ -699,9 +697,17 @@ public abstract class BaseBusinessLogic { throw new ByActionStatusComponentException(actionStatus, params); } - public <T extends ToscaDataDefinition> Either<List<T>, ResponseFormat> declareProperties(String userId, String componentId, - ComponentTypeEnum componentTypeEnum, ComponentInstInputsMap componentInstInputsMap) { + public <T extends ToscaDataDefinition> Either<List<T>, ResponseFormat> declareProperties(final String userId, + final String componentId, + final ComponentTypeEnum componentTypeEnum, + final ComponentInstInputsMap componentInstInputsMap) { + return Either.left(new ArrayList<>()); + } + public <T extends ToscaDataDefinition> Either<List<T>, ResponseFormat> declareAttributes(final String userId, + final String componentId, + final ComponentTypeEnum componentTypeEnum, + final ComponentInstOutputsMap componentInstOutputsMap) { return Either.left(new ArrayList<>()); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java index d603c8fc78..5729d246cf 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java @@ -20,6 +20,7 @@ package org.openecomp.sdc.be.components.impl; +import static org.openecomp.sdc.be.components.attribute.GetOutputUtils.isGetOutputValueForOutput; import static org.openecomp.sdc.be.components.property.GetInputUtils.isGetInputValueForInput; import static org.openecomp.sdc.be.components.utils.PropertiesUtils.getPropertyCapabilityOfChildInstance; @@ -38,7 +39,6 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; -import java.util.function.BiConsumer; import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; @@ -61,11 +61,11 @@ import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; -import org.openecomp.sdc.be.model.jsonjanusgraph.config.ContainerInstanceTypesData; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition; import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.GetOutputValueDataDefinition; import org.openecomp.sdc.be.datatypes.elements.GetPolicyValueDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition; @@ -84,6 +84,7 @@ import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.ComponentInstanceAttribute; import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceOutput; import org.openecomp.sdc.be.model.ComponentInstancePropInput; import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.ComponentParametersView; @@ -100,6 +101,7 @@ import org.openecomp.sdc.be.model.RequirementDefinition; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.Service; import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.jsonjanusgraph.config.ContainerInstanceTypesData; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ForwardingPathOperation; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation; @@ -148,6 +150,9 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { private static final String CREATE_OR_UPDATE_PROPERTY_VALUE = "CreateOrUpdatePropertyValue"; private static final String FAILED_TO_COPY_COMP_INSTANCE_TO_CANVAS = "Failed to copy the component instance to the canvas"; private static final String COPY_COMPONENT_INSTANCE_OK = "Copy component instance OK"; + private static final String CANNOT_ATTACH_RESOURCE_INSTANCES_TO_CONTAINER_RESOURCE_OF_TYPE = "Cannot attach resource instances to container resource of type {}"; + private static final String SERVICE_PROXY = "serviceProxy"; + private static final String ASSOCIATE_RI_TO_RI = "associateRIToRI"; private ComponentInstanceOperation componentInstanceOperation; private ArtifactsBusinessLogic artifactBusinessLogic; @@ -184,26 +189,50 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { @Autowired private ContainerInstanceTypesData containerInstanceTypesData; - public ComponentInstance createComponentInstance(String containerComponentParam, String containerComponentId, String userId, ComponentInstance resourceInstance) { + public ComponentInstance createComponentInstance(String containerComponentParam, String containerComponentId, String userId, + ComponentInstance resourceInstance) { return createComponentInstance(containerComponentParam, containerComponentId, userId, resourceInstance, true); } - public List<ComponentInstanceProperty> getComponentInstancePropertiesByInputId(org.openecomp.sdc.be.model.Component component, String inputId){ + public List<ComponentInstanceProperty> getComponentInstancePropertiesByInputId(org.openecomp.sdc.be.model.Component component, + String inputId) { List<ComponentInstanceProperty> resList = new ArrayList<>(); Map<String, List<ComponentInstanceProperty>> ciPropertiesMap = component.getComponentInstancesProperties(); - if(ciPropertiesMap != null && !ciPropertiesMap.isEmpty()){ - ciPropertiesMap.forEach(new BiConsumer<String, List<ComponentInstanceProperty>>() { - @Override - public void accept(String s, List<ComponentInstanceProperty> ciPropList) { - String ciName = ""; - Optional<ComponentInstance> ciOp = component.getComponentInstances().stream().filter(ci ->ci.getUniqueId().equals(s)).findAny(); - if(ciOp.isPresent()) - ciName = ciOp.get().getName(); - if (ciPropList != null && !ciPropList.isEmpty()) { - for(ComponentInstanceProperty prop: ciPropList){ - List<GetInputValueDataDefinition> inputsValues = prop.getGetInputValues(); - addCompInstanceProperty(s, ciName, prop, inputsValues, inputId, resList); - } + if (ciPropertiesMap != null && !ciPropertiesMap.isEmpty()) { + ciPropertiesMap.forEach((s, ciPropList) -> { + String ciName = ""; + Optional<ComponentInstance> ciOp = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(s)) + .findAny(); + if (ciOp.isPresent()) { + ciName = ciOp.get().getName(); + } + if (ciPropList != null && !ciPropList.isEmpty()) { + for (ComponentInstanceProperty prop : ciPropList) { + List<GetInputValueDataDefinition> inputsValues = prop.getGetInputValues(); + addCompInstanceProperty(s, ciName, prop, inputsValues, inputId, resList); + } + } + }); + } + return resList; + + } + + public List<ComponentInstanceAttribute> getComponentInstanceAttributesByOutputId(final org.openecomp.sdc.be.model.Component component, + final String outputId) { + final List<ComponentInstanceAttribute> resList = new ArrayList<>(); + final Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes = component.getComponentInstancesAttributes(); + if (org.apache.commons.collections4.MapUtils.isNotEmpty(componentInstancesAttributes)) { + componentInstancesAttributes.forEach((s, componentInstanceAttributeList) -> { + String ciName = ""; + final Optional<ComponentInstance> ciOp = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(s)).findAny(); + if (ciOp.isPresent()) { + ciName = ciOp.get().getName(); + } + if (componentInstanceAttributeList != null && !componentInstanceAttributeList.isEmpty()) { + for (final ComponentInstanceAttribute compInstanceAttribute : componentInstanceAttributeList) { + List<GetOutputValueDataDefinition> outputValues = compInstanceAttribute.getGetOutputValues(); + addCompInstanceAttribute(s, ciName, compInstanceAttribute, outputValues, outputId, resList); } } }); @@ -212,10 +241,11 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } - private void addCompInstanceProperty(String s, String ciName, ComponentInstanceProperty prop, List<GetInputValueDataDefinition> inputsValues, String inputId, List<ComponentInstanceProperty> resList) { - if(inputsValues != null && !inputsValues.isEmpty()){ - for(GetInputValueDataDefinition inputData: inputsValues){ - if(isGetInputValueForInput(inputData, inputId)){ + private void addCompInstanceProperty(String s, String ciName, ComponentInstanceProperty prop, List<GetInputValueDataDefinition> inputsValues, + String inputId, List<ComponentInstanceProperty> resList) { + if (inputsValues != null && !inputsValues.isEmpty()) { + for (GetInputValueDataDefinition inputData : inputsValues) { + if (isGetInputValueForInput(inputData, inputId)) { prop.setComponentInstanceId(s); prop.setComponentInstanceName(ciName); resList.add(prop); @@ -225,15 +255,33 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } } + private void addCompInstanceAttribute(final String s, + final String ciName, + final ComponentInstanceAttribute attribute, + final List<GetOutputValueDataDefinition> outputsValues, + final String outputId, + final List<ComponentInstanceAttribute> resList) { + if (outputsValues != null && !outputsValues.isEmpty()) { + for (final GetOutputValueDataDefinition outputData : outputsValues) { + if (isGetOutputValueForOutput(outputData, outputId)) { + attribute.setComponentInstanceId(s); + attribute.setComponentInstanceName(ciName); + resList.add(attribute); + break; + } + } + } + } + public Optional<ComponentInstanceProperty> getComponentInstancePropertyByPolicyId(Component component, PolicyDefinition policy) { Optional<ComponentInstanceProperty> propertyCandidate = getComponentInstancePropertyByPolicy(component, policy); - if(propertyCandidate.isPresent()) { + if (propertyCandidate.isPresent()) { ComponentInstanceProperty componentInstanceProperty = propertyCandidate.get(); Optional<GetPolicyValueDataDefinition> getPolicyCandidate = - getGetPolicyValueDataDefinition(policy, componentInstanceProperty); + getGetPolicyValueDataDefinition(policy, componentInstanceProperty); getPolicyCandidate.ifPresent(getPolicyValue -> updateComponentInstancePropertyAfterUndeclaration(componentInstanceProperty, getPolicyValue, policy)); @@ -290,20 +338,43 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { org.openecomp.sdc.be.model.Component component, String inputId) { List<ComponentInstanceInput> resList = new ArrayList<>(); Map<String, List<ComponentInstanceInput>> ciInputsMap = component.getComponentInstancesInputs(); - if(ciInputsMap != null && !ciInputsMap.isEmpty()){ - ciInputsMap.forEach(new BiConsumer<String, List<ComponentInstanceInput>>() { - @Override - public void accept(String s, List<ComponentInstanceInput> ciPropList) { - String ciName = ""; - Optional<ComponentInstance> ciOp = component.getComponentInstances().stream().filter(ci ->ci.getUniqueId().equals(s)).findAny(); - if(ciOp.isPresent()) - ciName = ciOp.get().getName(); - if (ciPropList != null && !ciPropList.isEmpty()) { - for(ComponentInstanceInput prop: ciPropList){ - List<GetInputValueDataDefinition> inputsValues = prop.getGetInputValues(); - addCompInstanceInput(s, ciName, prop, inputsValues, inputId, resList); + if (ciInputsMap != null && !ciInputsMap.isEmpty()) { + ciInputsMap.forEach((s, ciPropList) -> { + String ciName = ""; + Optional<ComponentInstance> ciOp = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(s)) + .findAny(); + if (ciOp.isPresent()) { + ciName = ciOp.get().getName(); + } + if (ciPropList != null && !ciPropList.isEmpty()) { + for (ComponentInstanceInput prop : ciPropList) { + List<GetInputValueDataDefinition> inputsValues = prop.getGetInputValues(); + addCompInstanceInput(s, ciName, prop, inputsValues, inputId, resList); + + } + } + }); + } + return resList; + + } + + public List<ComponentInstanceOutput> getComponentInstanceOutputsByOutputId(final org.openecomp.sdc.be.model.Component component, + final String outputId) { + final List<ComponentInstanceOutput> resList = new ArrayList<>(); + final Map<String, List<ComponentInstanceOutput>> ciInputsMap = component.getComponentInstancesOutputs(); + if (ciInputsMap != null && !ciInputsMap.isEmpty()) { + ciInputsMap.forEach((s, ciPropList) -> { + String ciName = ""; + final Optional<ComponentInstance> ciOp = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(s)).findAny(); + if (ciOp.isPresent()) { + ciName = ciOp.get().getName(); + } + if (ciPropList != null && !ciPropList.isEmpty()) { + for (final ComponentInstanceOutput prop : ciPropList) { + final List<GetOutputValueDataDefinition> outputValues = prop.getGetOutputValues(); + addCompInstanceOutput(s, ciName, prop, outputValues, outputId, resList); - } } } }); @@ -312,10 +383,29 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } - private void addCompInstanceInput(String s, String ciName, ComponentInstanceInput prop, List<GetInputValueDataDefinition> inputsValues, String inputId, List<ComponentInstanceInput> resList) { - if(inputsValues != null && !inputsValues.isEmpty()){ - for(GetInputValueDataDefinition inputData: inputsValues){ - if(isGetInputValueForInput(inputData, inputId)){ + private void addCompInstanceInput(String s, String ciName, ComponentInstanceInput prop, List<GetInputValueDataDefinition> inputsValues, + String inputId, List<ComponentInstanceInput> resList) { + if (inputsValues != null && !inputsValues.isEmpty()) { + for (GetInputValueDataDefinition inputData : inputsValues) { + if (isGetInputValueForInput(inputData, inputId)) { + prop.setComponentInstanceId(s); + prop.setComponentInstanceName(ciName); + resList.add(prop); + break; + } + } + } + } + + private void addCompInstanceOutput(final String s, + final String ciName, + final ComponentInstanceOutput prop, + final List<GetOutputValueDataDefinition> outputsValues, + final String outputId, + final List<ComponentInstanceOutput> resList) { + if (outputsValues != null && !outputsValues.isEmpty()) { + for (final GetOutputValueDataDefinition outputData : outputsValues) { + if (isGetOutputValueForOutput(outputData, outputId)) { prop.setComponentInstanceId(s); prop.setComponentInstanceName(ciName); resList.add(prop); @@ -337,7 +427,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { if (ModelConverter.isAtomicComponent(containerComponent)) { if (log.isDebugEnabled()) { - log.debug("Cannot attach resource instances to container resource of type {}", containerComponent.assetType()); + log.debug(CANNOT_ATTACH_RESOURCE_INSTANCES_TO_CONTAINER_RESOURCE_OF_TYPE, containerComponent.assetType()); } throw new ByActionStatusComponentException(ActionStatus.RESOURCE_CANNOT_CONTAIN_RESOURCE_INSTANCES, containerComponent.assetType()); } @@ -365,7 +455,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } private Component getOrigComponentForServiceProxy(org.openecomp.sdc.be.model.Component containerComponent, ComponentInstance resourceInstance) { - Either<Component, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade.getLatestByName("serviceProxy"); + Either<Component, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade.getLatestByName(SERVICE_PROXY); if (isServiceProxyOrigin(serviceProxyOrigin)) { throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(serviceProxyOrigin.right().value())); } @@ -406,10 +496,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { boolean failed = false; try { - ComponentInstance lockComponent = isNeedLock(needLock, containerComponent); - if (lockComponent != null) { - return lockComponent; - } + lockIfNeed(needLock, containerComponent); + log.debug(TRY_TO_CREATE_ENTRY_ON_GRAPH); return createComponentInstanceOnGraph(containerComponent, origComponent, resourceInstance, user); }catch (ComponentException e){ @@ -432,12 +520,12 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { public Either<ComponentInstance, ResponseFormat> createRealComponentInstance(String containerComponentParam, String containerComponentId, String userId, ComponentInstance resourceInstance) { log.debug("enter createRealComponentInstance"); - return createRealComponentInstance(containerComponentParam, containerComponentId, userId, resourceInstance, false, true); + return createRealComponentInstance(containerComponentParam, containerComponentId, userId, resourceInstance, true); } + /** * Try using either to make a judgment * - * @param inTransaction * @param needLock * @param containerComponentParam * @param containerComponentId @@ -445,7 +533,10 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { * @param resourceInstance * @return */ - public Either<ComponentInstance, ResponseFormat> createRealComponentInstance(String containerComponentParam, String containerComponentId, String userId, ComponentInstance resourceInstance, boolean inTransaction, boolean needLock) { + public Either<ComponentInstance, ResponseFormat> createRealComponentInstance(String containerComponentParam, + String containerComponentId, String userId, + ComponentInstance resourceInstance, + boolean needLock) { log.debug("enter createRealComponentInstance"); Component origComponent = null; @@ -461,7 +552,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { log.debug("enter createRealComponentInstance,validate user json success"); if (ModelConverter.isAtomicComponent(containerComponent)) { - log.debug("Cannot attach resource instances to container resource of type {}", containerComponent.assetType()); + log.debug(CANNOT_ATTACH_RESOURCE_INSTANCES_TO_CONTAINER_RESOURCE_OF_TYPE, containerComponent.assetType()); throw new ByActionStatusComponentException(ActionStatus.RESOURCE_CANNOT_CONTAIN_RESOURCE_INSTANCES, containerComponent.assetType()); } @@ -475,7 +566,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { if (originType == OriginTypeEnum.ServiceProxy) { log.debug("enter createRealComponentInstance,originType equals ServiceProxy"); - Either<Component, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade.getLatestByName("serviceProxy"); + Either<Component, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade.getLatestByName(SERVICE_PROXY); if (isServiceProxyOrigin(serviceProxyOrigin)) { throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(serviceProxyOrigin.right().value())); } @@ -509,10 +600,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { boolean failed = false; try { - ComponentInstance lockComponent = isNeedLock(needLock, containerComponent); - if (lockComponent != null) { - return Either.left(lockComponent); - } + lockIfNeed(needLock, containerComponent); + log.debug(TRY_TO_CREATE_ENTRY_ON_GRAPH); return createRealComponentInstanceOnGraph(containerComponent, origComponent, resourceInstance, user); } catch (ComponentException e) { @@ -525,7 +614,6 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } private Either<ComponentInstance, ResponseFormat> createRealComponentInstanceOnGraph(org.openecomp.sdc.be.model.Component containerComponent, Component originComponent, ComponentInstance componentInstance, User user) { - Either<ComponentInstance, ResponseFormat> resultOp; log.debug("enter createRealComponentInstanceOnGraph"); Either<ImmutablePair<Component, String>, StorageOperationStatus> result = toscaOperationFacade.addComponentInstanceToTopologyTemplate(containerComponent, originComponent, componentInstance, false, user); @@ -635,11 +723,10 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } } - private ComponentInstance isNeedLock(boolean needLock, Component containerComponent) { + private void lockIfNeed(boolean needLock, Component containerComponent) { if (needLock) { lockComponent(containerComponent, "createComponentInstance"); } - return null; } private boolean isServiceProxyOrigin(Either<Component, StorageOperationStatus> serviceProxyOrigin) { @@ -732,7 +819,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists(containerComponentId, containerComponentType, null); if (ModelConverter.isAtomicComponent(containerComponent)) { - log.debug("Cannot attach resource instances to container resource of type {}", containerComponent.assetType()); + log.debug(CANNOT_ATTACH_RESOURCE_INSTANCES_TO_CONTAINER_RESOURCE_OF_TYPE, containerComponent.assetType()); return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_CANNOT_CONTAIN_RESOURCE_INSTANCES, containerComponent.assetType())); } @@ -792,7 +879,6 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } private ComponentInstance createComponentInstanceOnGraph(org.openecomp.sdc.be.model.Component containerComponent, Component originComponent, ComponentInstance componentInstance, User user) { - Either<ComponentInstance, ResponseFormat> resultOp; Either<ImmutablePair<Component, String>, StorageOperationStatus> result = toscaOperationFacade.addComponentInstanceToTopologyTemplate(containerComponent, originComponent, componentInstance, false, user); @@ -818,7 +904,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { public boolean isCloudSpecificArtifact(String artifact) { if (artifact.contains(CLOUD_SPECIFIC_FIXED_KEY_WORD)) { for (int i = 0; i < CLOUD_SPECIFIC_KEY_WORDS.length; i++) { - if (Arrays.stream(CLOUD_SPECIFIC_KEY_WORDS[i]).noneMatch(str -> artifact.contains(str))) { + if (Arrays.stream(CLOUD_SPECIFIC_KEY_WORDS[i]).noneMatch(artifact::contains)) { return false; } } @@ -828,7 +914,6 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } } - /** * addResourceInstanceArtifacts - add artifacts (HEAT_ENV) to resource instance The instance artifacts are generated from the resource's artifacts * @param containerComponent @@ -891,7 +976,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } } groupInstancesArtifacts.forEach((k,v) -> v.addAll(listOfCloudSpecificArts)); - filteredGroups.forEach(g -> listOfCloudSpecificArts.forEach((e) -> { + filteredGroups.forEach(g -> listOfCloudSpecificArts.forEach(e -> { g.getArtifactsUuid().add(e.getArtifactUUID()); g.getArtifacts().add(e.getUniqueId()); })); @@ -960,7 +1045,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } public Either<ComponentInstance, ResponseFormat> updateComponentInstanceMetadata(String containerComponentParam, String containerComponentId, String componentInstanceId, String userId, ComponentInstance componentInstance) { - return updateComponentInstanceMetadata(containerComponentParam, containerComponentId, componentInstanceId, userId, componentInstance, false, true); + return updateComponentInstanceMetadata(containerComponentParam, containerComponentId, componentInstanceId, userId, componentInstance, true); } public Either<ComponentInstance, ResponseFormat> updateComponentInstanceMetadata( @@ -969,7 +1054,6 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { final String componentInstanceId, final String userId, ComponentInstance componentInstance, - final boolean inTransaction, boolean needLock) { validateUserExists(userId); @@ -1191,8 +1275,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { final String oldInstanceName) { Map<String, CINodeFilterDataDefinition> renamedNodesFilter = - ServiceFilterUtils.getRenamedNodesFilter((Service) containerComponent, - oldInstanceName, newInstanceName); + ServiceFilterUtils.getRenamedNodesFilter(containerComponent, oldInstanceName, newInstanceName); for( Entry<String, CINodeFilterDataDefinition> entry : renamedNodesFilter.entrySet()){ Either<CINodeFilterDataDefinition, StorageOperationStatus> renameEither = nodeFilterOperation.updateNodeFilter( @@ -1313,22 +1396,25 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { ComponentInstance deletedRelatedInst; try { if (containerComponent instanceof Service) { - ComponentInstance componentInstance = containerComponent.getComponentInstanceById(componentInstanceId).get(); - Either<String, StorageOperationStatus> deleteServiceFilterEither = - nodeFilterOperation.deleteNodeFilter((Service) containerComponent, componentInstanceId); - if (deleteServiceFilterEither.isRight()) { - log.debug("enter deleteAbstractComponentInstance:deleteServiceFilterEither is right, filed"); - ActionStatus status = componentsUtils.convertFromStorageResponse(deleteServiceFilterEither.right().value(), + final Optional<ComponentInstance> componentInstanceById = containerComponent.getComponentInstanceById(componentInstanceId); + if (componentInstanceById.isPresent()) { + ComponentInstance componentInstance = componentInstanceById.get(); + Either<String, StorageOperationStatus> deleteServiceFilterEither = + nodeFilterOperation.deleteNodeFilter(containerComponent, componentInstanceId); + if (deleteServiceFilterEither.isRight()) { + log.debug("enter deleteAbstractComponentInstance:deleteServiceFilterEither is right, filed"); + ActionStatus status = componentsUtils.convertFromStorageResponse(deleteServiceFilterEither.right().value(), containerComponentType); - janusGraphDao.rollback(); - return Either.right(componentsUtils.getResponseFormat(status, componentInstance.getName())); - } - Either<ComponentInstance, ResponseFormat> resultOp = deleteNodeFiltersFromComponentInstance((Service) containerComponent, + janusGraphDao.rollback(); + return Either.right(componentsUtils.getResponseFormat(status, componentInstance.getName())); + } + Either<ComponentInstance, ResponseFormat> resultOp = deleteNodeFiltersFromComponentInstance(containerComponent, componentInstance, ComponentTypeEnum.SERVICE, userId); - if (resultOp.isRight()) { - log.debug("enter deleteAbstractComponentInstance:resultOp is right, filed"); - janusGraphDao.rollback(); - return resultOp; + if (resultOp.isRight()) { + log.debug("enter deleteAbstractComponentInstance:resultOp is right, filed"); + janusGraphDao.rollback(); + return resultOp; + } } } log.debug("enter deleteAbstractComponentInstance:"); @@ -1378,11 +1464,11 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); } final ComponentInstance componentInstanceToBeUpdated = componentInstanceById.get(); - final List<String> directives = componentInstanceToBeUpdated.getDirectives(); + componentInstanceToBeUpdated.setDirectives(Collections.emptyList()); final Either<ComponentInstance, ResponseFormat> componentInstanceResponseFormatEither = updateComponentInstanceMetadata(containerComponentType.getValue(), component.getUniqueId(), - componentInstanceToBeUpdated.getUniqueId(), userId, componentInstanceToBeUpdated, true, false); + componentInstanceToBeUpdated.getUniqueId(), userId, componentInstanceToBeUpdated, false); if (componentInstanceResponseFormatEither.isRight()) { return componentInstanceResponseFormatEither; } @@ -1391,8 +1477,6 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { return Either.left(componentInstance); } - - private Set<String> getComponentFiltersRelatedToComponentInstance(String containerComponentId, ComponentInstance componentInstance) { ComponentParametersView filter = new ComponentParametersView(true); @@ -1400,12 +1484,9 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { Either<Component, StorageOperationStatus> componentFilterOrigin = toscaOperationFacade.getToscaElement(containerComponentId, filter); final Component component = componentFilterOrigin.left().value(); - final Set<String> nodesFiltersToBeDeleted = ComponentsUtils.getNodesFiltersToBeDeleted(component, - componentInstance); - return nodesFiltersToBeDeleted; + return ComponentsUtils.getNodesFiltersToBeDeleted(component, componentInstance); } - ComponentInstance deleteForwardingPathsRelatedTobeDeletedComponentInstance(String containerComponentId, ComponentTypeEnum containerComponentType, ComponentInstance componentInstance) { if(containerComponentType == ComponentTypeEnum.SERVICE){ @@ -1457,7 +1538,6 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { .equalsIgnoreCase(componentInstanceId)); } - private ComponentInstance deleteComponentInstance(Component containerComponent, String componentInstanceId, ComponentTypeEnum containerComponentType) { Either<ImmutablePair<Component, String>, StorageOperationStatus> deleteRes = toscaOperationFacade.deleteComponentInstanceFromTopologyTemplate(containerComponent, componentInstanceId); if (deleteRes.isRight()) { @@ -1506,14 +1586,15 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } public RequirementCapabilityRelDef associateRIToRI(String componentId, String userId, RequirementCapabilityRelDef requirementDef, ComponentTypeEnum componentTypeEnum) { - return associateRIToRI(componentId, userId, requirementDef, componentTypeEnum, false, true); + return associateRIToRI(componentId, userId, requirementDef, componentTypeEnum, true); } - public RequirementCapabilityRelDef associateRIToRI(String componentId, String userId, RequirementCapabilityRelDef requirementDef, ComponentTypeEnum componentTypeEnum, boolean inTransaction, boolean needLock) { + public RequirementCapabilityRelDef associateRIToRI(String componentId, String userId, RequirementCapabilityRelDef requirementDef, + ComponentTypeEnum componentTypeEnum, boolean needLock) { validateUserExists(userId); - RequirementCapabilityRelDef requirementCapabilityRelDef = null; + RequirementCapabilityRelDef requirementCapabilityRelDef; org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists(componentId, componentTypeEnum, null); @@ -1521,7 +1602,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { boolean failed = false; try { if (needLock) { - lockComponent(containerComponent, "associateRIToRI"); + lockComponent(containerComponent, ASSOCIATE_RI_TO_RI); } requirementCapabilityRelDef = associateRIToRIOnGraph(containerComponent, requirementDef); }catch (ComponentException e){ @@ -1542,9 +1623,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { if (result.isLeft()) { log.debug(ENTITY_ON_GRAPH_IS_CREATED); - RequirementCapabilityRelDef requirementCapabilityRelDef = result.left().value(); - return requirementCapabilityRelDef; - + return result.left().value(); } else { log.debug("Failed to associate node: {} with node {}", requirementDef.getFromNode(), requirementDef.getToNode()); String fromNameOrId = ""; @@ -1587,7 +1666,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { boolean failed = false; List<RequirementCapabilityRelDef> delOkResult = new ArrayList<>(); try { - lockComponent(containerComponent, "associateRIToRI"); + lockComponent(containerComponent, ASSOCIATE_RI_TO_RI); for (RequirementCapabilityRelDef requirementDef : requirementDefList) { RequirementCapabilityRelDef requirementCapabilityRelDef = dissociateRIFromRI( componentId, userId, requirementDef, containerComponent.getComponentType()); @@ -1602,17 +1681,15 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { return delOkResult; } - public RequirementCapabilityRelDef dissociateRIFromRI(String componentId, String userId, RequirementCapabilityRelDef requirementDef, ComponentTypeEnum componentTypeEnum) { validateUserExists(userId); - Either<RequirementCapabilityRelDef, ResponseFormat> resultOp = null; org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists(componentId, componentTypeEnum, null); validateCanWorkOnComponent(containerComponent, userId); boolean failed = false; try { - lockComponent(containerComponent, "associateRIToRI"); + lockComponent(containerComponent, ASSOCIATE_RI_TO_RI); log.debug(TRY_TO_CREATE_ENTRY_ON_GRAPH); Either<RequirementCapabilityRelDef, StorageOperationStatus> result = toscaOperationFacade.dissociateResourceInstances(componentId, requirementDef); if (result.isLeft()) { @@ -1685,7 +1762,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { private RequirementCapabilityRelDef findRelation(String relationId, List<RequirementCapabilityRelDef> requirementCapabilityRelations) { for(RequirementCapabilityRelDef relationship : requirementCapabilityRelations){ - if(relationship.getRelationships().stream().filter(r -> r.getRelation().getId().equals(relationId)).findFirst().isPresent()){ + if (relationship.getRelationships().stream().anyMatch(r -> r.getRelation().getId().equals(relationId))) { return relationship; } } @@ -1697,32 +1774,41 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { RelationshipInfo relationshipInfo = foundRelation.resolveSingleRelationship().getRelation(); String instanceId = foundRelation.getFromNode(); Optional<RequirementDefinition> foundRequirement; - Optional<ComponentInstance> instance = containerComponent.getComponentInstances().stream().filter(i -> i.getUniqueId().equals(instanceId)).findFirst(); - if(!instance.isPresent()){ - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, instanceId, "instance", containerComponent.getComponentType().getValue(), containerComponent.getName()); + Optional<ComponentInstance> instance = containerComponent.getComponentInstances().stream() + .filter(i -> i.getUniqueId().equals(instanceId)).findFirst(); + if (!instance.isPresent()) { + ResponseFormat responseFormat = componentsUtils + .getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, instanceId, "instance", + containerComponent.getComponentType().getValue(), containerComponent.getName()); log.debug("Component instance with id {} was not found on the component", instanceId, containerComponent.getUniqueId()); result = Either.right(responseFormat); } - if(result == null){ - for(List<RequirementDefinition> requirements : instance.get().getRequirements().values()){ - foundRequirement = requirements.stream().filter(r -> isBelongingCalcRequirement(relationshipInfo, r, containerComponent.getLifecycleState())).findFirst(); - if(foundRequirement.isPresent()){ + if (result == null && instance.isPresent()) { + for (List<RequirementDefinition> requirements : instance.get().getRequirements().values()) { + foundRequirement = requirements.stream() + .filter(r -> isBelongingCalcRequirement(relationshipInfo, r, containerComponent.getLifecycleState())).findFirst(); + if (foundRequirement.isPresent()) { foundRelation.resolveSingleRelationship().setRequirement(foundRequirement.get()); result = Either.left(foundRelation); } } } - if(result == null){ - Either<RequirementDataDefinition, StorageOperationStatus> getfulfilledRequirementRes = toscaOperationFacade.getFulfilledRequirementByRelation(containerComponent.getUniqueId(), instanceId, foundRelation, this::isBelongingFullRequirement); - if(getfulfilledRequirementRes.isRight()){ - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.REQUIREMENT_OF_INSTANCE_NOT_FOUND_ON_CONTAINER, relationshipInfo.getRequirement(), instanceId, containerComponent.getUniqueId()); - log.debug("Requirement {} of instance {} was not found on the container {}. ", relationshipInfo.getCapability(), instanceId, containerComponent.getUniqueId()); + if (result == null) { + Either<RequirementDataDefinition, StorageOperationStatus> getfulfilledRequirementRes = toscaOperationFacade + .getFulfilledRequirementByRelation(containerComponent.getUniqueId(), instanceId, foundRelation, + this::isBelongingFullRequirement); + if (getfulfilledRequirementRes.isRight()) { + ResponseFormat responseFormat = componentsUtils + .getResponseFormat(ActionStatus.REQUIREMENT_OF_INSTANCE_NOT_FOUND_ON_CONTAINER, relationshipInfo.getRequirement(), + instanceId, containerComponent.getUniqueId()); + log.debug("Requirement {} of instance {} was not found on the container {}. ", relationshipInfo.getCapability(), instanceId, + containerComponent.getUniqueId()); result = Either.right(responseFormat); } else { foundRelation.resolveSingleRelationship().setRequirement(getfulfilledRequirementRes.left().value()); } } - if(result == null){ + if (result == null) { result = Either.left(foundRelation); } return result; @@ -1745,27 +1831,35 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { RelationshipInfo relationshipInfo = foundRelation.resolveSingleRelationship().getRelation(); String instanceId = foundRelation.getToNode(); Optional<CapabilityDefinition> foundCapability; - Optional<ComponentInstance> instance = containerComponent.getComponentInstances().stream().filter(i -> i.getUniqueId().equals(instanceId)).findFirst(); - if(!instance.isPresent()){ - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, instanceId, "instance", containerComponent.getComponentType().getValue(), containerComponent.getName()); + Optional<ComponentInstance> instance = containerComponent.getComponentInstances().stream() + .filter(i -> i.getUniqueId().equals(instanceId)).findFirst(); + if (!instance.isPresent()) { + ResponseFormat responseFormat = componentsUtils + .getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, instanceId, "instance", + containerComponent.getComponentType().getValue(), containerComponent.getName()); log.debug("Component instance with id {} was not found on the component", instanceId, containerComponent.getUniqueId()); result = Either.right(responseFormat); } - if(result == null){ - for(List<CapabilityDefinition> capabilities : instance.get().getCapabilities().values()){ - foundCapability = capabilities.stream().filter(c -> isBelongingCalcCapability(relationshipInfo, c, containerComponent.getLifecycleState())).findFirst(); - if(foundCapability.isPresent()){ + if (result == null && instance.isPresent()) { + for (List<CapabilityDefinition> capabilities : instance.get().getCapabilities().values()) { + foundCapability = capabilities.stream() + .filter(c -> isBelongingCalcCapability(relationshipInfo, c, containerComponent.getLifecycleState())).findFirst(); + if (foundCapability.isPresent()) { foundRelation.resolveSingleRelationship().setCapability(foundCapability.get()); result = Either.left(foundRelation); } } } - if(result == null){ + if (result == null) { Either<CapabilityDataDefinition, StorageOperationStatus> getfulfilledRequirementRes = - toscaOperationFacade.getFulfilledCapabilityByRelation(containerComponent.getUniqueId(), instanceId, foundRelation, this::isBelongingFullCapability); - if(getfulfilledRequirementRes.isRight()){ - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_OF_INSTANCE_NOT_FOUND_ON_CONTAINER, relationshipInfo.getCapability(), instanceId, containerComponent.getUniqueId()); - log.debug("Capability {} of instance {} was not found on the container {}. ", relationshipInfo.getCapability(), instanceId, containerComponent.getUniqueId()); + toscaOperationFacade.getFulfilledCapabilityByRelation(containerComponent.getUniqueId(), instanceId, foundRelation, + this::isBelongingFullCapability); + if (getfulfilledRequirementRes.isRight()) { + ResponseFormat responseFormat = componentsUtils + .getResponseFormat(ActionStatus.CAPABILITY_OF_INSTANCE_NOT_FOUND_ON_CONTAINER, relationshipInfo.getCapability(), + instanceId, containerComponent.getUniqueId()); + log.debug("Capability {} of instance {} was not found on the container {}. ", relationshipInfo.getCapability(), instanceId, + containerComponent.getUniqueId()); result = Either.right(responseFormat); } else { foundRelation.resolveSingleRelationship().setCapability(getfulfilledRequirementRes.left().value()); @@ -2001,8 +2095,6 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { return instanceProperty.get(); } - - private ResponseFormat updateCapabilityPropertyOnContainerComponent(ComponentInstanceProperty property, String newValue, Component containerComponent, ComponentInstance foundResourceInstance, String capabilityType, String capabilityName) { @@ -2042,11 +2134,11 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { String capabilityType, String capabilityName, String componentInstanceUniqueId) { Map<String, List<CapabilityDefinition>> capabilities = - Optional.ofNullable(foundResourceInstance.getCapabilities()).orElse(Collections.emptyMap()); + Optional.ofNullable(foundResourceInstance.getCapabilities()).orElse(Collections.emptyMap()); List<CapabilityDefinition> capPerType = - Optional.ofNullable(capabilities.get(capabilityType)).orElse(Collections.EMPTY_LIST); + Optional.ofNullable(capabilities.get(capabilityType)).orElse(Collections.emptyList()); Optional<CapabilityDefinition> cap = - capPerType.stream().filter(c -> c.getName().equals(capabilityName)).findAny(); + capPerType.stream().filter(c -> c.getName().equals(capabilityName)).findAny(); if (cap.isPresent()) { List<ComponentInstanceProperty> capProperties = cap.get().getProperties(); if (capProperties != null) { @@ -2582,7 +2674,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { newComponentInstance.setOriginType(originType); if (originType == OriginTypeEnum.ServiceProxy) { Either<Component, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade - .getLatestByName("serviceProxy"); + .getLatestByName(SERVICE_PROXY); if (isServiceProxyOrigin(serviceProxyOrigin)) { throw new ByActionStatusComponentException( componentsUtils.convertFromStorageResponse(serviceProxyOrigin.right().value())); @@ -2624,12 +2716,11 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { newComponentInstance.setPosY(resResourceInfo.getPosY()); newComponentInstance.setDescription(resResourceInfo.getDescription()); - ComponentInstance updatedComponentInstance = createComponentInstanceOnGraph(containerComponent, - origComponent, newComponentInstance, user); + ComponentInstance updatedComponentInstance = + createComponentInstanceOnGraph(containerComponent, origComponent, newComponentInstance, user); dataHolder.setCurrInstanceNode(origComponent); - Component mergeStatusEither = compInstMergeDataBL - .mergeComponentUserOrigData(user, dataHolder, containerComponent, containerComponentId, - newComponentInstance.getUniqueId()); + compInstMergeDataBL + .mergeComponentUserOrigData(user, dataHolder, containerComponent, containerComponentId, newComponentInstance.getUniqueId()); ActionStatus postChangeVersionResult = onChangeInstanceOperationOrchestrator .doPostChangeVersionOperations(containerComponent, currentResourceInstance, newComponentInstance); @@ -2639,8 +2730,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { ComponentParametersView filter = new ComponentParametersView(true); filter.setIgnoreComponentInstances(false); - Either<Component, StorageOperationStatus> updatedComponentRes = toscaOperationFacade - .getToscaElement(containerComponentId, filter); + Either<Component, StorageOperationStatus> updatedComponentRes = toscaOperationFacade.getToscaElement(containerComponentId, filter); if (updatedComponentRes.isRight()) { StorageOperationStatus storageOperationStatus = updatedComponentRes.right().value(); ActionStatus actionStatus = componentsUtils @@ -2800,20 +2890,19 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { private Either<ComponentInstance, StorageOperationStatus> getResourceInstanceById(Component containerComponent, String instanceId) { - Either<ComponentInstance, StorageOperationStatus> result = null; + Either<ComponentInstance, StorageOperationStatus> result = Either.right(StorageOperationStatus.NOT_FOUND); List<ComponentInstance> instances = containerComponent.getComponentInstances(); - Optional<ComponentInstance> foundInstance = null; - if (CollectionUtils.isEmpty(instances)) { - result = Either.right(StorageOperationStatus.NOT_FOUND); - } - if (result == null) { - foundInstance = instances.stream().filter(i -> i.getUniqueId().equals(instanceId)).findFirst(); - if (!foundInstance.isPresent()) { - result = Either.right(StorageOperationStatus.NOT_FOUND); + Optional<ComponentInstance> foundInstance = Optional.empty(); + if (!CollectionUtils.isEmpty(instances)) { + if (result.isRight()) { + foundInstance = instances.stream().filter(i -> i.getUniqueId().equals(instanceId)).findFirst(); + if (!foundInstance.isPresent()) { + result = Either.right(StorageOperationStatus.NOT_FOUND); + } + } + if (result.isRight() && foundInstance.isPresent()) { + result = Either.left(foundInstance.get()); } - } - if (result == null) { - result = Either.left(foundInstance.get()); } return result; } @@ -2888,13 +2977,13 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { validateUserExists(userId); validateComponentType(containerComponentType); containerComponent = toscaOperationFacade.getToscaFullElement(containerComponentId).left().on(this::componentException); - ComponentInstance resourceInstanceStatus = getResourceInstanceById(containerComponent, componentInstanceUniqueId).left().on(this::componentInstanceException); - resultOp = findCapabilityOfInstance(containerComponentId, componentInstanceUniqueId, capabilityType, capabilityName, ownerId, resourceInstanceStatus.getCapabilities()); - } catch(StorageException e){ - unlockRollbackWithException(containerComponent, e); - } catch (ComponentException e) { + ComponentInstance resourceInstanceStatus = getResourceInstanceById(containerComponent, componentInstanceUniqueId).left() + .on(this::componentInstanceException); + resultOp = findCapabilityOfInstance(containerComponentId, componentInstanceUniqueId, capabilityType, capabilityName, ownerId, + resourceInstanceStatus.getCapabilities()); + } catch (StorageException | ComponentException e) { unlockRollbackWithException(containerComponent, e); - } catch (Exception e){ + } catch (Exception e) { unlockRollbackWithException(containerComponent, new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR)); } unlockWithCommit(containerComponent); @@ -2927,7 +3016,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } } - public Either<RequirementDefinition, ResponseFormat> updateInstanceRequirement(ComponentTypeEnum componentTypeEnum, String containerComponentId, String componentInstanceUniqueId, String capabilityType, String capabilityName, + public Either<RequirementDefinition, ResponseFormat> updateInstanceRequirement(ComponentTypeEnum componentTypeEnum, String containerComponentId, + String componentInstanceUniqueId, RequirementDefinition requirementDef, String userId) { Either<RequirementDefinition, ResponseFormat> resultOp = null; @@ -3081,18 +3171,15 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } catch (ComponentException e) { failed = true; - throw e; + // on failure of the create instance unlock the resource and rollback the transaction. + return Either.right(componentsUtils.getResponseFormat(ActionStatus.USER_DEFINED, FAILED_TO_COPY_COMP_INSTANCE_TO_CANVAS)); } finally { // on failure of the create instance unlock the resource and rollback the transaction. - if (null == actionResponse || failed) { - janusGraphDao.rollback(); - log.error("Failed to copy the component instance to the canvas"); + if (null == actionResponse) { + log.error(FAILED_TO_COPY_COMP_INSTANCE_TO_CANVAS); unlockComponent(failed, origComponent); - - return Either.right(componentsUtils.getResponseFormat( - ActionStatus.USER_DEFINED, "Failed to copy the component instance to the canvas")); } } @@ -3100,11 +3187,9 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { try { ComponentInstance destComponentInstance = actionResponse; - log.debug("destComponentInstance's data is {}", destComponentInstance.toString()); - + log.debug("destComponentInstance's data is {}", destComponentInstance); - resultOp = deepCopyComponentInstance( - origComponent, containerComponentId, componentInstanceId, destComponentInstance, userId); + resultOp = deepCopyComponentInstance(origComponent, containerComponentId, componentInstanceId, destComponentInstance, userId); resultMap.put("componentInstance", destComponentInstance); } finally { @@ -3114,16 +3199,18 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { unlockComponent(true, origComponent); janusGraphDao.rollback(); log.error("Failed to deep copy component instance"); - return Either.right(componentsUtils.getResponseFormat( - ActionStatus.USER_DEFINED, "Failed to deep copy the component instance to the canvas")); } else { unlockComponent(false, origComponent); janusGraphDao.commit(); log.debug("Success trasaction commit"); } } + if (resultOp == null || resultOp.isRight()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.USER_DEFINED, "Failed to deep copy the component instance to the canvas")); + } else { + return Either.left(resultMap); + } - return Either.left(resultMap); } private Either<String, ResponseFormat> deepCopyComponentInstance( @@ -3133,14 +3220,13 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { Either<Component, StorageOperationStatus> getDestComponent = toscaOperationFacade.getToscaElement(containerComponentId); if (getDestComponent.isRight()) { log.error("Failed to get the dest component information"); - return Either.right(componentsUtils.getResponseFormat( - ActionStatus.USER_DEFINED, "Failed to copy the component instance to the canvas")); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.USER_DEFINED, FAILED_TO_COPY_COMP_INSTANCE_TO_CANVAS)); } Component destComponent = getDestComponent.left().value(); Either<String, ResponseFormat> copyComponentInstanceWithPropertiesAndInputs = copyComponentInstanceWithPropertiesAndInputs( - sourceComponent, destComponent, sourceComponentInstanceId, destComponentInstance, userId); + sourceComponent, destComponent, sourceComponentInstanceId, destComponentInstance); if (copyComponentInstanceWithPropertiesAndInputs.isRight()) { log.error("Failed to copy component instance with properties and inputs as part of deep copy"); return Either.right(componentsUtils.getResponseFormat( @@ -3158,13 +3244,13 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } private Either<String, ResponseFormat> copyComponentInstanceWithPropertiesAndInputs( - Component sourceComponent, Component destComponent, String sourceComponentInstanceId, - ComponentInstance destComponentInstance, String userId) { + Component sourceComponent, Component destComponent, String sourceComponentInstanceId, + ComponentInstance destComponentInstance) { log.debug("start to copy ComponentInstance with properties and inputs"); List<ComponentInstanceProperty> sourcePropList = null; if (sourceComponent.getComponentInstancesProperties() != null - && sourceComponent.getComponentInstancesProperties().get(sourceComponentInstanceId) != null) { + && sourceComponent.getComponentInstancesProperties().get(sourceComponentInstanceId) != null) { sourcePropList = sourceComponent.getComponentInstancesProperties().get(sourceComponentInstanceId); log.debug("sourcePropList"); } @@ -3189,32 +3275,33 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { continue; } log.debug("now set property"); - if (sourceProp.getGetInputValues() == null && !StringUtils.isEmpty(sourceProp.getValue()) - && (destProp.getValue() == null || !destProp.getValue().equals(sourceProp.getValue()))) { + final List<GetInputValueDataDefinition> getInputValues = sourceProp.getGetInputValues(); + if (getInputValues == null && !StringUtils.isEmpty(sourceProp.getValue()) + && (destProp.getValue() == null || !destProp.getValue().equals(sourceProp.getValue()))) { log.debug("Now starting to copy the property {} in value {}", destPropertyName, sourceProp.getValue()); destProp.setValue(sourceProp.getValue()); Either<String, ResponseFormat> updatePropertyValueEither = updateComponentInstanceProperty( - destComponent.getUniqueId(), destComponentInstanceId, destProp); + destComponent.getUniqueId(), destComponentInstanceId, destProp); if (updatePropertyValueEither.isRight()) { log.error("Failed to copy the property {}", destPropertyName); return Either.right(componentsUtils.getResponseFormat( - ActionStatus.INVALID_CONTENT_PARAM, "Failed to paste component instance to the canvas, property copy")); + ActionStatus.INVALID_CONTENT_PARAM, "Failed to paste component instance to the canvas, property copy")); } break; } log.debug("Now start to update inputs"); - if (sourceProp.getGetInputValues() != null) { - if (sourceProp.getGetInputValues().size() < 1) { + if (getInputValues != null) { + if (getInputValues.isEmpty()) { log.debug("property is return from input, set by man"); break; } log.debug("Now starting to copy the {} property", destPropertyName); Either<String, ResponseFormat> getSourceInputDefaultValue = getInputListDefaultValue( - sourceComponent, sourceProp.getGetInputValues().get(0).getInputId()); + sourceComponent, getInputValues.get(0).getInputId()); if (getSourceInputDefaultValue.isRight()) { return Either.right(getSourceInputDefaultValue.right().value()); } @@ -3448,7 +3535,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { lockComponent(containerComponent, "batchDeleteComponentInstance"); for (String eachInstanceId : componentInstanceIdList) { Either<ComponentInstance, ResponseFormat> actionResponse = batchDeleteComponentInstance( - containerComponent, containerComponentType, componentId, eachInstanceId); + containerComponent, containerComponentType, eachInstanceId); log.debug("batchDeleteResourceInstances actionResponse is {}", actionResponse); if (actionResponse.isRight()) { log.error("Failed to delete ComponentInstance [{}]", eachInstanceId); @@ -3468,13 +3555,11 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { private Either<ComponentInstance, ResponseFormat> batchDeleteComponentInstance(Component containerComponent, String containerComponentType, - String containerComponentId, String componentInstanceId) { ComponentInstance resultOp; final ComponentTypeEnum containerComponentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); - boolean failed = false; try { resultOp = deleteComponentInstance(containerComponent, componentInstanceId, containerComponentTypeEnum); log.info("Successfully deleted instance with id {}", componentInstanceId); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/OutputsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/OutputsBusinessLogic.java index eecb6eeba2..cfb6004620 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/OutputsBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/OutputsBusinessLogic.java @@ -25,11 +25,19 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; +import org.openecomp.sdc.be.components.attribute.AttributeDeclarationOrchestrator; +import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; +import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException; +import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; import org.openecomp.sdc.be.components.validation.ComponentValidations; import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.utils.MapUtil; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstOutputsMap; import org.openecomp.sdc.be.model.ComponentInstanceOutput; import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.OutputDefinition; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation; import org.openecomp.sdc.be.model.operations.api.IElementOperation; @@ -48,12 +56,18 @@ import org.springframework.beans.factory.annotation.Autowired; @org.springframework.stereotype.Component("outputsBusinessLogic") public class OutputsBusinessLogic extends BaseBusinessLogic { + private static final String CREATE_OUTPUT = "CreateOutput"; + private static final Logger log = Logger.getLogger(OutputsBusinessLogic.class); private static final String FAILED_TO_FOUND_COMPONENT_ERROR = "Failed to found component {}, error: {}"; + private static final String GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP = "Going to execute rollback on create group."; + private static final String GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP = "Going to execute commit on create group."; private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(OutputsBusinessLogic.class); private static final String FAILED_TO_FOUND_COMPONENT_INSTANCE_OUTPUTS_COMPONENT_INSTANCE_ID = "Failed to found component instance outputs componentInstanceId: {}"; private static final String FAILED_TO_FOUND_COMPONENT_INSTANCE_OUTPUTS_ERROR = "Failed to found component instance outputs {}, error: {}"; + private final AttributeDeclarationOrchestrator attributeDeclarationOrchestrator; + @Autowired public OutputsBusinessLogic(final IElementOperation elementDao, final IGroupOperation groupOperation, @@ -61,9 +75,11 @@ public class OutputsBusinessLogic extends BaseBusinessLogic { final IGroupTypeOperation groupTypeOperation, final InterfaceOperation interfaceOperation, final InterfaceLifecycleOperation interfaceLifecycleTypeOperation, + final AttributeDeclarationOrchestrator attributeDeclarationOrchestrator, final ArtifactsOperations artifactToscaOperation) { - super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, - interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation); + super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation, + artifactToscaOperation); + this.attributeDeclarationOrchestrator = attributeDeclarationOrchestrator; } public Either<List<ComponentInstanceOutput>, ResponseFormat> getComponentInstanceOutputs(final String userId, @@ -78,7 +94,7 @@ public class OutputsBusinessLogic extends BaseBusinessLogic { filters.setIgnoreComponentInstancesOutputs(false); final Either<Component, StorageOperationStatus> getComponentEither = toscaOperationFacade.getToscaElement(componentId, filters); - if (getComponentEither.isRight()) { + if(getComponentEither.isRight()){ ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value()); log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus); return Either.right(componentsUtils.getResponseFormat(actionStatus)); @@ -99,4 +115,165 @@ public class OutputsBusinessLogic extends BaseBusinessLogic { return Either.left(ciOutputs.getOrDefault(componentInstanceId, Collections.emptyList())); } + @Override + public Either<List<OutputDefinition>, ResponseFormat> declareAttributes(final String userId, + final String componentId, + final ComponentTypeEnum componentTypeEnum, + final ComponentInstOutputsMap componentInstOutputsMap) { + + return createMultipleOutputs(userId, componentId, componentTypeEnum, componentInstOutputsMap, true, false); + } + + public Either<List<OutputDefinition>, ResponseFormat> createMultipleOutputs(final String userId, + final String componentId, + final ComponentTypeEnum componentType, + final ComponentInstOutputsMap componentInstOutputsMapUi, + final boolean shouldLockComp, + final boolean inTransaction) { + + Either<List<OutputDefinition>, ResponseFormat> result = null; + org.openecomp.sdc.be.model.Component component = null; + + try { + validateUserExists(userId); + + component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp); + + result = attributeDeclarationOrchestrator.declareAttributesToOutputs(component, componentInstOutputsMapUi) + .left() + .bind(outputsToCreate -> prepareOutputsForCreation(userId, componentId, outputsToCreate)) + .right() + .map(componentsUtils::getResponseFormat); + return result; + + } catch (final ByResponseFormatComponentException e) { + log.error("#createMultipleOutputs: Exception thrown: ", e); + result = Either.right(e.getResponseFormat()); + return result; + } finally { + + if (!inTransaction) { + if (result == null || result.isRight()) { + log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP); + janusGraphDao.rollback(); + } else { + log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP); + janusGraphDao.commit(); + } + } + // unlock resource + if (shouldLockComp && component != null) { + graphLockOperation.unlockComponent(componentId, componentType.getNodeType()); + } + + } + } + + private org.openecomp.sdc.be.model.Component getAndValidateComponentForCreate(final String userId, + final String componentId, + final ComponentTypeEnum componentType, + final boolean shouldLockComp) { + final ComponentParametersView componentParametersView = getBaseComponentParametersView(); + final org.openecomp.sdc.be.model.Component component = validateComponentExists(componentId, componentType, componentParametersView); + if (shouldLockComp) { + // lock the component + lockComponent(component, CREATE_OUTPUT); + } + validateCanWorkOnComponent(component, userId); + return component; + } + + private Either<List<OutputDefinition>, StorageOperationStatus> prepareOutputsForCreation(final String userId, + final String cmptId, + final List<OutputDefinition> outputsToCreate) { + final Map<String, OutputDefinition> outputsToPersist = MapUtil.toMap(outputsToCreate, OutputDefinition::getName); + assignOwnerIdToOutputs(userId, outputsToPersist); + + return toscaOperationFacade.addOutputsToComponent(outputsToPersist, cmptId) + .left() + .map(persistedOutputs -> outputsToCreate); + } + + private void assignOwnerIdToOutputs(final String userId, final Map<String, OutputDefinition> outputsToCreate) { + outputsToCreate.values().forEach(outputDefinition -> outputDefinition.setOwnerId(userId)); + } + + private ComponentParametersView getBaseComponentParametersView() { + final ComponentParametersView componentParametersView = new ComponentParametersView(); + componentParametersView.disableAll(); + componentParametersView.setIgnoreOutputs(false); + componentParametersView.setIgnoreAttributes(false); + componentParametersView.setIgnoreComponentInstances(false); + componentParametersView.setIgnoreComponentInstancesOutputs(false); + componentParametersView.setIgnoreComponentInstancesAttributes(false); + componentParametersView.setIgnoreUsers(false); + return componentParametersView; + } + + /** + * Delete output from component + * + * @param componentId + * @param userId + * @param outputId + * @return + */ + public OutputDefinition deleteOutput(final String componentId, final String userId, final String outputId) { + + Either<OutputDefinition, ResponseFormat> deleteEither = null; + if (log.isDebugEnabled()) { + log.debug("Going to delete output id: {}", outputId); + } + + validateUserExists(userId); + + final ComponentParametersView componentParametersView = getBaseComponentParametersView(); + componentParametersView.setIgnoreAttributes(false); + + final Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> componentEither = + toscaOperationFacade.getToscaElement(componentId, componentParametersView); + if (componentEither.isRight()) { + throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(componentEither.right().value())); + } + final org.openecomp.sdc.be.model.Component component = componentEither.left().value(); + + // Validate outputId is child of the component + final Optional<OutputDefinition> optionalOutput = component.getOutputs().stream(). + // filter by ID + filter(output -> output.getUniqueId().equals(outputId)). + // Get the output + findAny(); + if (!optionalOutput.isPresent()) { + throw new ByActionStatusComponentException(ActionStatus.OUTPUT_IS_NOT_CHILD_OF_COMPONENT, outputId, componentId); + } + + final OutputDefinition outputForDelete = optionalOutput.get(); + + // Lock component + lockComponent(componentId, component, "deleteOutput"); + // Delete output operations + boolean failed = false; + try { + final StorageOperationStatus status = + toscaOperationFacade.deleteOutputOfResource(component, outputForDelete.getName()); + if (status != StorageOperationStatus.OK) { + log.debug("Component id: {} delete output id: {} failed", componentId, outputId); + throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status), component.getName()); + } + + final StorageOperationStatus storageOperationStatus = + attributeDeclarationOrchestrator.unDeclareAttributesAsOutputs(component, outputForDelete); + if (storageOperationStatus != StorageOperationStatus.OK) { + log.debug("Component id: {} update attributes declared as output for outputId: {} failed", componentId, outputId); + throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(storageOperationStatus), component.getName()); + } + return outputForDelete; + } catch (final ComponentException e) { + failed = true; + throw e; + } finally { + unlockComponent(failed, component); + } + } + } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java index 01b7451a53..8cfd8c7007 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java @@ -62,8 +62,8 @@ import org.openecomp.sdc.be.components.csar.CsarArtifactsAndGroupsBusinessLogic; import org.openecomp.sdc.be.components.csar.CsarBusinessLogic; import org.openecomp.sdc.be.components.csar.CsarInfo; import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum; -import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo; import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; +import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo; import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException; @@ -197,7 +197,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { private static final String DELETE_RESOURCE = "Delete Resource"; private static final String IN_RESOURCE = " in resource {} "; private static final String PLACE_HOLDER_RESOURCE_TYPES = "validForResourceTypes"; - public static final String INITIAL_VERSION = "0.1"; + private static final String INITIAL_VERSION = "0.1"; private static final Logger log = Logger.getLogger(ResourceBusinessLogic.class); private static final String CERTIFICATION_ON_IMPORT = "certification on import"; private static final String CREATE_RESOURCE = "Create Resource"; @@ -208,59 +208,68 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { private static final String COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE = "component instance with name {} in resource {} "; private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ResourceBusinessLogic.class.getName()); - private IInterfaceLifecycleOperation interfaceTypeOperation; private LifecycleBusinessLogic lifecycleBusinessLogic; private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic; private final ResourceImportManager resourceImportManager; private final InputsBusinessLogic inputsBusinessLogic; + private final OutputsBusinessLogic outputsBusinessLogic; private final CompositionBusinessLogic compositionBusinessLogic; private final ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic; - private final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic; - private final MergeInstanceUtils mergeInstanceUtils; - private final UiComponentDataConverter uiComponentDataConverter; - private final CsarBusinessLogic csarBusinessLogic; - private final PropertyBusinessLogic propertyBusinessLogic; + private final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic; + private final MergeInstanceUtils mergeInstanceUtils; + private final UiComponentDataConverter uiComponentDataConverter; + private final CsarBusinessLogic csarBusinessLogic; + private final PropertyBusinessLogic propertyBusinessLogic; private final PolicyBusinessLogic policyBusinessLogic; @Autowired - public ResourceBusinessLogic(IElementOperation elementDao, - IGroupOperation groupOperation, - IGroupInstanceOperation groupInstanceOperation, - IGroupTypeOperation groupTypeOperation, - GroupBusinessLogic groupBusinessLogic, - InterfaceOperation interfaceOperation, - InterfaceLifecycleOperation interfaceLifecycleTypeOperation, - ArtifactsBusinessLogic artifactsBusinessLogic, - ComponentInstanceBusinessLogic componentInstanceBusinessLogic, @Lazy ResourceImportManager resourceImportManager, - InputsBusinessLogic inputsBusinessLogic, CompositionBusinessLogic compositionBusinessLogic, - ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic, - CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic, MergeInstanceUtils mergeInstanceUtils, - UiComponentDataConverter uiComponentDataConverter, CsarBusinessLogic csarBusinessLogic, - ArtifactsOperations artifactToscaOperation, PropertyBusinessLogic propertyBusinessLogic, - ComponentContactIdValidator componentContactIdValidator, - ComponentNameValidator componentNameValidator, ComponentTagsValidator componentTagsValidator, - ComponentValidator componentValidator, - ComponentIconValidator componentIconValidator, - ComponentProjectCodeValidator componentProjectCodeValidator, - ComponentDescriptionValidator componentDescriptionValidator, PolicyBusinessLogic policyBusinessLogic) { - super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, - interfaceOperation, interfaceLifecycleTypeOperation, artifactsBusinessLogic, artifactToscaOperation, - componentContactIdValidator, componentNameValidator, componentTagsValidator, componentValidator, - componentIconValidator, componentProjectCodeValidator, componentDescriptionValidator); - this.componentInstanceBusinessLogic = componentInstanceBusinessLogic; - this.resourceImportManager = resourceImportManager; - this.inputsBusinessLogic = inputsBusinessLogic; - this.compositionBusinessLogic = compositionBusinessLogic; - this.resourceDataMergeBusinessLogic = resourceDataMergeBusinessLogic; - this.csarArtifactsAndGroupsBusinessLogic = csarArtifactsAndGroupsBusinessLogic; - this.mergeInstanceUtils = mergeInstanceUtils; - this.uiComponentDataConverter = uiComponentDataConverter; - this.csarBusinessLogic = csarBusinessLogic; - this.propertyBusinessLogic = propertyBusinessLogic; + public ResourceBusinessLogic(final IElementOperation elementDao, + final IGroupOperation groupOperation, + final IGroupInstanceOperation groupInstanceOperation, + final IGroupTypeOperation groupTypeOperation, + final GroupBusinessLogic groupBusinessLogic, + final InterfaceOperation interfaceOperation, + final InterfaceLifecycleOperation interfaceLifecycleTypeOperation, + final ArtifactsBusinessLogic artifactsBusinessLogic, + final ComponentInstanceBusinessLogic componentInstanceBusinessLogic, + final @Lazy ResourceImportManager resourceImportManager, + final InputsBusinessLogic inputsBusinessLogic, + final OutputsBusinessLogic outputsBusinessLogic, + final CompositionBusinessLogic compositionBusinessLogic, + final ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic, + final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic, + final MergeInstanceUtils mergeInstanceUtils, + final UiComponentDataConverter uiComponentDataConverter, + final CsarBusinessLogic csarBusinessLogic, + final ArtifactsOperations artifactToscaOperation, + final PropertyBusinessLogic propertyBusinessLogic, + final ComponentContactIdValidator componentContactIdValidator, + final ComponentNameValidator componentNameValidator, + final ComponentTagsValidator componentTagsValidator, + final ComponentValidator componentValidator, + final ComponentIconValidator componentIconValidator, + final ComponentProjectCodeValidator componentProjectCodeValidator, + final ComponentDescriptionValidator componentDescriptionValidator, + final PolicyBusinessLogic policyBusinessLogic) { + super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation, + interfaceLifecycleTypeOperation, artifactsBusinessLogic, artifactToscaOperation, componentContactIdValidator, + componentNameValidator, componentTagsValidator, componentValidator, componentIconValidator, componentProjectCodeValidator, + componentDescriptionValidator); + this.componentInstanceBusinessLogic = componentInstanceBusinessLogic; + this.resourceImportManager = resourceImportManager; + this.inputsBusinessLogic = inputsBusinessLogic; + this.outputsBusinessLogic = outputsBusinessLogic; + this.compositionBusinessLogic = compositionBusinessLogic; + this.resourceDataMergeBusinessLogic = resourceDataMergeBusinessLogic; + this.csarArtifactsAndGroupsBusinessLogic = csarArtifactsAndGroupsBusinessLogic; + this.mergeInstanceUtils = mergeInstanceUtils; + this.uiComponentDataConverter = uiComponentDataConverter; + this.csarBusinessLogic = csarBusinessLogic; + this.propertyBusinessLogic = propertyBusinessLogic; this.policyBusinessLogic = policyBusinessLogic; - } + } @Autowired private ICapabilityTypeOperation capabilityTypeOperation; @@ -304,6 +313,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } @Autowired + @Override public void setUserAdmin(UserBusinessLogic userAdmin) { this.userAdmin = userAdmin; } @@ -313,6 +323,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } @Autowired + @Override public void setComponentsUtils(ComponentsUtils componentsUtils) { this.componentsUtils = componentsUtils; } @@ -330,6 +341,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } @Autowired + @Override public void setApplicationDataTypeCache(ApplicationDataTypeCache applicationDataTypeCache) { this.applicationDataTypeCache = applicationDataTypeCache; } @@ -6026,16 +6038,14 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String resourceId, List<String> dataParamsToReturn) { - ComponentParametersView paramsToRetuen = new ComponentParametersView(dataParamsToReturn); - Either<Resource, StorageOperationStatus> resourceResultEither = - toscaOperationFacade.getToscaElement(resourceId, - paramsToRetuen); + ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn); + Either<Resource, StorageOperationStatus> resourceResultEither = toscaOperationFacade.getToscaElement(resourceId, paramsToReturn); if (resourceResultEither.isRight()) { if (resourceResultEither.right().value() == StorageOperationStatus.NOT_FOUND) { log.debug("Failed to found resource with id {} ", resourceId); Either - .right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceId)); + .right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceId)); } log.debug("failed to get resource by id {} with filters {}", resourceId, dataParamsToReturn); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyDeclarationOrchestrator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyDeclarationOrchestrator.java index c60c8f21c2..a0d499ddfd 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyDeclarationOrchestrator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyDeclarationOrchestrator.java @@ -42,7 +42,7 @@ import java.util.stream.Collectors; import static org.apache.commons.collections.MapUtils.isNotEmpty; -@org.springframework.stereotype.Component +@org.springframework.stereotype.Component("propertyDeclarationOrchestrator") public class PropertyDeclarationOrchestrator { private static final Logger log = Logger.getLogger(PropertyDeclarationOrchestrator.class); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java index 6e23454a62..e4a1187072 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java @@ -25,6 +25,7 @@ import static java.util.stream.Collectors.toList; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -84,6 +85,9 @@ public class UiComponentDataConverter { case INPUTS: setInputs(dataTransfer, component); break; + case OUTPUTS: + setOutputs(dataTransfer, component); + break; case COMPONENT_INSTANCE_RELATION: setComponentInstanceRelation(dataTransfer, component); break; @@ -212,6 +216,10 @@ public class UiComponentDataConverter { } } + private void setOutputs(final UiComponentDataTransfer dataTransfer, final Component component) { + dataTransfer.setOutputs(component.getOutputs() == null ? Collections.emptyList() : component.getOutputs()); + } + private void setComponentInstanceInputs(UiComponentDataTransfer dataTransfer, Component component) { if (component.getComponentInstancesInputs() == null) { dataTransfer.setComponentInstancesInputs(new HashMap<>()); @@ -374,11 +382,6 @@ public class UiComponentDataConverter { case DERIVED_FROM: setDerivedFrom(resource, dataTransfer); break; - - case ATTRIBUTES: - setAttributes(resource, dataTransfer); - break; - case ADDITIONAL_INFORMATION: setAdditionalInfo(resource, dataTransfer); break; @@ -427,14 +430,6 @@ public class UiComponentDataConverter { } } - private void setAttributes(Resource resource, UiResourceDataTransfer dataTransfer) { - if (resource.getAttributes() == null) { - dataTransfer.setAttributes(new ArrayList<>()); - } else { - dataTransfer.setAttributes(resource.getAttributes()); - } - } - private void setAdditionalInfo(Resource resource, UiResourceDataTransfer dataTransfer) { if (resource.getAdditionalInformation() == null) { dataTransfer.setAdditionalInformation(new ArrayList<>()); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java index 382e01c60a..1b8ed5fab6 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java @@ -42,12 +42,11 @@ import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.impl.ElementBusinessLogic; import org.openecomp.sdc.be.components.impl.GenericArtifactBrowserBusinessLogic; -import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; import org.openecomp.sdc.be.components.impl.InputsBusinessLogic; import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic; +import org.openecomp.sdc.be.components.impl.OutputsBusinessLogic; import org.openecomp.sdc.be.components.impl.PolicyBusinessLogic; import org.openecomp.sdc.be.components.impl.ProductBusinessLogic; -import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic; import org.openecomp.sdc.be.components.impl.RelationshipTypeBusinessLogic; import org.openecomp.sdc.be.components.impl.RequirementBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; @@ -242,31 +241,17 @@ public class BeGenericServlet extends BasicServlet { return getClassFromWebAppContext(context, () -> LifecycleBusinessLogic.class); } - <T> T getClassFromWebAppContext(ServletContext context, Supplier<Class<T>> businessLogicClassGen) { - WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); - WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); - return webApplicationContext.getBean(businessLogicClassGen.get()); + <T> T getClassFromWebAppContext(final ServletContext context, final Supplier<Class<T>> businessLogicClassGen) { + return getWebAppContext(context).getBean(businessLogicClassGen.get()); } - GroupBusinessLogic getGroupBL(ServletContext context) { - - WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); - WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); - return webApplicationContext.getBean(GroupBusinessLogic.class); - } - - protected ComponentInstanceBusinessLogic getComponentInstanceBL(ServletContext context) { - WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); - WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); - return webApplicationContext.getBean(ComponentInstanceBusinessLogic.class); + protected ComponentInstanceBusinessLogic getComponentInstanceBL(final ServletContext context) { + return getClassFromWebAppContext(context, () -> ComponentInstanceBusinessLogic.class); } protected ComponentsUtils getComponentsUtils() { - ServletContext context = this.servletRequest.getSession().getServletContext(); - - WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); - WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); - return webApplicationContext.getBean(ComponentsUtils.class); + final ServletContext context = this.servletRequest.getSession().getServletContext(); + return getClassFromWebAppContext(context, () -> ComponentsUtils.class); } /** @@ -289,8 +274,6 @@ public class BeGenericServlet extends BasicServlet { return new StringBuilder().append("attachment; filename=\"").append(artifactFileName).append("\"").toString(); } - - protected ComponentBusinessLogic getComponentBL(ComponentTypeEnum componentTypeEnum, ServletContext context) { ComponentBusinessLogic businessLogic; switch (componentTypeEnum) { @@ -451,10 +434,8 @@ public class BeGenericServlet extends BasicServlet { if (either.isRight()) { return new JSONObject(); } - String value = either.left().value(); try { - JSONObject root = (JSONObject) new JSONParser().parse(value); - return root; + return (JSONObject) new JSONParser().parse(either.left().value()); } catch (ParseException e) { log.info("failed to convert input to json"); log.error("failed to convert to json", e); @@ -506,53 +487,55 @@ public class BeGenericServlet extends BasicServlet { } - protected PropertyBusinessLogic getPropertyBL(ServletContext context) { - WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); - WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); - PropertyBusinessLogic propertytBl = webApplicationContext.getBean(PropertyBusinessLogic.class); - return propertytBl; + private OutputsBusinessLogic getOutputBL(final ServletContext context) { + return getClassFromWebAppContext(context, () -> OutputsBusinessLogic.class); + } + + private InputsBusinessLogic getInputBL(final ServletContext context) { + return getClassFromWebAppContext(context, () -> InputsBusinessLogic.class); } - protected InputsBusinessLogic getInputBL(ServletContext context) { - WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); - WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); - return webApplicationContext.getBean(InputsBusinessLogic.class); + private PolicyBusinessLogic getPolicyBL(final ServletContext context) { + return getClassFromWebAppContext(context, () -> PolicyBusinessLogic.class); } - protected PolicyBusinessLogic getPolicyBL(ServletContext context) { - WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); - WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); - return webApplicationContext.getBean(PolicyBusinessLogic.class); + private WebApplicationContext getWebAppContext(final ServletContext context) { + return ((WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR)).getWebAppContext(context); } - protected Either<ComponentInstInputsMap, ResponseFormat> parseToComponentInstanceMap(String componentJson, User user, ComponentTypeEnum componentType) { - return getComponentsUtils().convertJsonToObjectUsingObjectMapper(componentJson, user, ComponentInstInputsMap.class, AuditingActionEnum.CREATE_RESOURCE, componentType); + protected <T> Either<T, ResponseFormat> parseToComponentInstanceMap(final String componentJson, + final User user, + final ComponentTypeEnum componentType, + final Class<T> clazz) { + return getComponentsUtils() + .convertJsonToObjectUsingObjectMapper(componentJson, user, clazz, AuditingActionEnum.CREATE_RESOURCE, componentType); } protected Response declareProperties(String userId, String componentId, String componentType, - String componentInstInputsMapObj, DeclarationTypeEnum typeEnum, HttpServletRequest request) { + String componentInstInputsMapObj, DeclarationTypeEnum typeEnum, HttpServletRequest request) { ServletContext context = request.getSession().getServletContext(); String url = request.getMethod() + " " + request.getRequestURI(); log.debug("(get) Start handle request of {}", url); try { - BaseBusinessLogic businessLogic = getBlForPropertyDeclaration(typeEnum, context); + BaseBusinessLogic businessLogic = getBlForDeclaration(typeEnum, context); // get modifier id User modifier = new User(); modifier.setUserId(userId); log.debug("modifier id is {}", userId); ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); - Either<ComponentInstInputsMap, ResponseFormat> componentInstInputsMapRes = parseToComponentInstanceMap(componentInstInputsMapObj, modifier, componentTypeEnum); + Either<ComponentInstInputsMap, ResponseFormat> componentInstInputsMapRes = parseToComponentInstanceMap( + componentInstInputsMapObj, modifier, componentTypeEnum, ComponentInstInputsMap.class); if (componentInstInputsMapRes.isRight()) { log.debug("failed to parse componentInstInputsMap"); return buildErrorResponse(componentInstInputsMapRes.right().value()); } Either<List<ToscaDataDefinition>, ResponseFormat> propertiesAfterDeclaration = businessLogic - .declareProperties(userId, componentId, - componentTypeEnum, - componentInstInputsMapRes.left().value()); + .declareProperties(userId, componentId, + componentTypeEnum, + componentInstInputsMapRes.left().value()); if (propertiesAfterDeclaration.isRight()) { log.debug("failed to create inputs for service: {}", componentId); return buildErrorResponse(propertiesAfterDeclaration.right().value()); @@ -567,13 +550,18 @@ public class BeGenericServlet extends BasicServlet { } } - public BaseBusinessLogic getBlForPropertyDeclaration(DeclarationTypeEnum typeEnum, - ServletContext context) { - if(typeEnum.equals(DeclarationTypeEnum.POLICY)) { - return getPolicyBL(context); + public BaseBusinessLogic getBlForDeclaration(final DeclarationTypeEnum typeEnum, + final ServletContext context) { + switch (typeEnum) { + case OUTPUT: + return getOutputBL(context); + case POLICY: + return getPolicyBL(context); + case INPUT: + return getInputBL(context); + default: + throw new IllegalArgumentException("Invalid DeclarationTypeEnum"); } - - return getInputBL(context); } protected Either<Map<String, InputDefinition>, ActionStatus> getInputModel(String componentId, String data) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java index 245ebc1bb8..8e54cc9d51 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java @@ -133,6 +133,7 @@ public class ComponentInstanceServlet extends AbstractValidationsServlet { private static final Type PROPERTY_CONSTRAINT_TYPE = new TypeToken<PropertyConstraint>() {}.getType(); private static final Gson gsonDeserializer = new GsonBuilder().registerTypeAdapter(PROPERTY_CONSTRAINT_TYPE, new PropertyConstraintDeserialiser()).create(); private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(ComponentInstanceServlet.class.getName()); + private static final String SERVICES = "services"; private final GroupBusinessLogic groupBL; private final ComponentNodeFilterBusinessLogic nodeFilterBusinessLogic; @@ -1136,13 +1137,13 @@ public class ComponentInstanceServlet extends AbstractValidationsServlet { @ApiResponse(responseCode = "404", description = "Component/Component Instance/Requirement - not found")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response updateInstanceRequirement( - @PathParam("containerComponentType") final String containerComponentType, - @PathParam("containerComponentId") final String containerComponentId, - @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId, + @PathParam("containerComponentType") final String containerComponentType, + @PathParam("containerComponentId") final String containerComponentId, + @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId, @PathParam("capabilityType") final String capabilityType, - @PathParam("requirementName") final String requirementName, - @Parameter(description = "Instance capabilty requirement to update", required = true) String data, - @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + @PathParam("requirementName") final String requirementName, + @Parameter(description = "Instance capabilty requirement to update", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { String url = request.getMethod() + " " + request.getRequestURI(); log.debug(START_HANDLE_REQUEST_OF, url); loggerSupportability.log(LoggerSupportabilityActions.UPDATE_INSTANCE_REQUIREMENT, StatusCode.STARTED,"Starting to update requirement {} in component instance {} by {}", requirementName, componentInstanceUniqueId, userId ); @@ -1163,7 +1164,8 @@ public class ComponentInstanceServlet extends AbstractValidationsServlet { } RequirementDefinition requirementDef = mappedRequirementDataEither.left().value(); - Either<RequirementDefinition, ResponseFormat> response = componentInstanceBusinessLogic.updateInstanceRequirement(componentTypeEnum, containerComponentId, componentInstanceUniqueId, capabilityType, requirementName, requirementDef, userId); + Either<RequirementDefinition, ResponseFormat> response = componentInstanceBusinessLogic.updateInstanceRequirement(componentTypeEnum, containerComponentId, componentInstanceUniqueId, + requirementDef, userId); if (response.isRight()) { return buildErrorResponse(response.right().value()); @@ -1495,7 +1497,7 @@ public class ComponentInstanceServlet extends AbstractValidationsServlet { log.info("Start to copy component instance"); String userId = request.getHeader(Constants.USER_ID_HEADER); - final String CNTAINER_CMPT_TYPE = "services"; + final String CNTAINER_CMPT_TYPE = SERVICES; try { ComponentInstance inputComponentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class); @@ -1503,7 +1505,7 @@ public class ComponentInstanceServlet extends AbstractValidationsServlet { ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(CNTAINER_CMPT_TYPE); if (componentInstanceBusinessLogic == null) { log.debug(UNSUPPORTED_COMPONENT_TYPE, componentTypeEnum); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, "services")); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, SERVICES)); } Either<Map<String, ComponentInstance>, ResponseFormat> copyComponentInstance = componentInstanceBusinessLogic.copyComponentInstance( inputComponentInstance, containerComponentId, componentInstanceId, userId); @@ -1695,7 +1697,7 @@ public class ComponentInstanceServlet extends AbstractValidationsServlet { log.debug("replaceVNF:get ReplaceVNFInfo success"); - String containerComponentType = "services"; + String containerComponentType = SERVICES; ReplaceVNFInfo replaceVNFInfo = convertResponse.left().value(); String serviceUniqueId = replaceVNFInfo.getServiceUniqueId(); String abstractResourceUniqueId = replaceVNFInfo.getAbstractResourceUniqueId(); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java index ea63218e5e..0d073b559a 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java @@ -31,9 +31,7 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.servers.Server; -import io.swagger.v3.oas.annotations.servers.Servers; import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.tags.Tags; import org.apache.commons.lang3.builder.ReflectionToStringBuilder; import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.impl.DataTypeBusinessLogic; @@ -48,7 +46,6 @@ import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.DeclarationTypeEnum; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.ServletUtils; -import org.openecomp.sdc.be.model.ComponentInstInputsMap; import org.openecomp.sdc.be.model.ComponentInstListInput; import org.openecomp.sdc.be.model.ComponentInstanceInput; import org.openecomp.sdc.be.model.ComponentInstanceProperty; @@ -69,7 +66,6 @@ import org.openecomp.sdc.exception.ResponseFormat; import org.springframework.stereotype.Controller; import javax.inject.Inject; -import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -88,8 +84,8 @@ import java.util.List; import java.util.Map; @Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Tags({@Tag(name = "SDC Internal APIs")}) -@Servers({@Server(url = "/sdc2/rest")}) +@Tag(name = "SDC Internal APIs") +@Server(url = "/sdc2/rest") @Path("/v1/catalog") @Controller @Consumes(MediaType.APPLICATION_JSON) @@ -151,7 +147,6 @@ public class InputsServlet extends AbstractValidationsServlet { log.debug("Start handle request of updateComponentInputs. Received inputs are {}", inputsToUpdate); - ServletContext context = request.getSession().getServletContext(); ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(containerComponentType); if (businessLogic == null) { @@ -177,7 +172,6 @@ public class InputsServlet extends AbstractValidationsServlet { } } - @GET @Path("/{componentType}/{componentId}/componentInstances/{instanceId}/{originComponentUid}/inputs") @Operation(description = "Get Inputs only", method = "GET", summary = "Returns Inputs list", responses = { @@ -190,10 +184,8 @@ public class InputsServlet extends AbstractValidationsServlet { @PathParam("originComponentUid") final String originComponentUid, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException { - ServletContext context = request.getSession().getServletContext(); String url = request.getMethod() + " " + request.getRequestURI(); log.debug(START_HANDLE_REQUEST_OF, url); - Response response; try { Either<List<ComponentInstanceInput>, ResponseFormat> inputsResponse = inputsBusinessLogic.getComponentInstanceInputs(userId, componentId, instanceId); @@ -223,10 +215,8 @@ public class InputsServlet extends AbstractValidationsServlet { @PathParam("inputId") final String inputId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException { - ServletContext context = request.getSession().getServletContext(); String url = request.getMethod() + " " + request.getRequestURI(); log.debug(START_HANDLE_REQUEST_OF, url); - Response response = null; try { Either<List<ComponentInstanceProperty>, ResponseFormat> inputPropertiesRes = inputsBusinessLogic @@ -256,10 +246,8 @@ public class InputsServlet extends AbstractValidationsServlet { @PathParam("componentId") final String componentId, @PathParam("inputId") final String inputId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException { - ServletContext context = request.getSession().getServletContext(); String url = request.getMethod() + " " + request.getRequestURI(); log.debug(START_HANDLE_REQUEST_OF, url); - Response response; try { Either<List<ComponentInstanceInput>, ResponseFormat> inputsRes = inputsBusinessLogic.getInputsForComponentInput(userId, componentId, inputId); @@ -289,10 +277,8 @@ public class InputsServlet extends AbstractValidationsServlet { @PathParam("componentId") final String componentId, @PathParam("inputId") final String inputId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException { - ServletContext context = request.getSession().getServletContext(); String url = request.getMethod() + " " + request.getRequestURI(); log.debug(START_HANDLE_REQUEST_OF, url); - Response response; try { Either<InputDefinition, ResponseFormat> inputsRes = @@ -312,10 +298,6 @@ public class InputsServlet extends AbstractValidationsServlet { } } - private Either<ComponentInstInputsMap, ResponseFormat> parseToComponentInstanceMap(String serviceJson, User user) { - return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, ComponentInstInputsMap.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); - } - private Either<ComponentInstListInput, ResponseFormat> parseToComponentInstListInput(String json, User user) { return getComponentsUtils().convertJsonToObjectUsingObjectMapper(json, user, ComponentInstListInput.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); } @@ -433,7 +415,6 @@ public class InputsServlet extends AbstractValidationsServlet { @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Parameter(description = "Service Input to be deleted", required = true) String componentInstInputsMapObj) { - ServletContext context = request.getSession().getServletContext(); String url = request.getMethod() + " " + request.getRequestURI(); log.debug(START_HANDLE_REQUEST_OF, url); loggerSupportability.log(LoggerSupportabilityActions.DELETE_INPUTS, StatusCode.STARTED,"Starting to delete Inputs for component {} ",componentId + " by " + userId ); @@ -513,7 +494,6 @@ public class InputsServlet extends AbstractValidationsServlet { @PathParam("componentId") final String componentId, @Context final HttpServletRequest request ) { - ServletContext context = request.getSession().getServletContext(); ComponentsUtils componentsUtils = getComponentsUtils(); String url = request.getMethod() + " " + request.getRequestURI(); log.debug("(getDataType) Start handle request of {}", url); @@ -558,10 +538,9 @@ public class InputsServlet extends AbstractValidationsServlet { @PathParam("dataTypeName") final String dataTypeName, @Context final HttpServletRequest request ) { - ServletContext context = request.getSession().getServletContext(); ComponentsUtils componentsUtils = getComponentsUtils(); String url = request.getMethod() + " " + request.getRequestURI(); - log.debug("(get) Start handle request of {}", url); + log.debug(START_HANDLE_REQUEST_OF, url); Response response; try { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/OutputsServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/OutputsServlet.java index 16e6d79879..8f00d17168 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/OutputsServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/OutputsServlet.java @@ -23,34 +23,45 @@ package org.openecomp.sdc.be.servlets; import com.jcabi.aspects.Loggable; import fj.data.Either; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.servers.Server; import io.swagger.v3.oas.annotations.tags.Tag; -import java.io.IOException; import java.util.List; import javax.inject.Inject; +import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import org.openecomp.sdc.be.components.impl.BaseBusinessLogic; import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.impl.OutputsBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.DeclarationTypeEnum; +import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.model.ComponentInstOutputsMap; import org.openecomp.sdc.be.model.ComponentInstanceOutput; +import org.openecomp.sdc.be.model.OutputDefinition; import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.user.UserBusinessLogic; import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.common.log.wrappers.Logger; @@ -94,7 +105,7 @@ public class OutputsServlet extends AbstractValidationsServlet { @PathParam("instanceId") final String instanceId, @PathParam("originComponentUid") final String originComponentUid, @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) final String userId) throws IOException { + @HeaderParam(value = Constants.USER_ID_HEADER) final String userId) { final String url = request.getMethod() + " " + request.getRequestURI(); log.debug(START_HANDLE_REQUEST_OF, url); @@ -112,7 +123,101 @@ public class OutputsServlet extends AbstractValidationsServlet { } catch (final Exception e) { BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Outputs " + componentType); log.debug("getOutputs failed with exception", e); - throw e; + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{componentType}/{componentId}/create/outputs") + @Operation(description = "Create outputs on service", method = "POST", summary = "Return outputs list", responses = { + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))), + @ApiResponse(responseCode = "200", description = "Component found"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Component not found")}) + public Response createMultipleOutputs(@PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) final String userId, + @Parameter(description = "ComponentIns Outputs Object to be created", required = true) final String componentInstOutputsMapObj) { + final String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + try { + return declareAttributes(userId, componentId, componentType, componentInstOutputsMapObj, DeclarationTypeEnum.OUTPUT, request); + + } catch (final Exception e) { + BeEcompErrorManager.getInstance() + .logBeRestApiGeneralError("Create outputs for service with id: " + componentId); + log.debug("Attributes declaration failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private Response declareAttributes(final String userId, + final String componentId, + final String componentType, + final String componentInstOutputsMapObj, + final DeclarationTypeEnum typeEnum, + final HttpServletRequest request) { + final ServletContext context = request.getSession().getServletContext(); + final String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + try { + final BaseBusinessLogic businessLogic = getBlForDeclaration(typeEnum, context); + + // get modifier id + final User modifier = new User(userId); + log.debug("modifier id is {}", userId); + final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + final Either<ComponentInstOutputsMap, ResponseFormat> componentInstOutputsMapRes = parseToComponentInstanceMap( + componentInstOutputsMapObj, modifier, componentTypeEnum, ComponentInstOutputsMap.class); + if (componentInstOutputsMapRes.isRight()) { + log.debug("failed to parse componentInstOutMap"); + return buildErrorResponse(componentInstOutputsMapRes.right().value()); + } + + final Either<List<ToscaDataDefinition>, ResponseFormat> attributesAfterDeclaration = + businessLogic.declareAttributes(userId, componentId, componentTypeEnum, componentInstOutputsMapRes.left().value()); + if (attributesAfterDeclaration.isRight()) { + log.debug("failed to create outputs for service: {}", componentId); + return buildErrorResponse(attributesAfterDeclaration.right().value()); + } + final Object attributes = RepresentationUtils.toRepresentation(attributesAfterDeclaration.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), attributes); + + } catch (final Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create outputs for service with id: " + componentId); + log.debug("Attributes declaration failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @DELETE + @Path("/{componentType}/{componentId}/delete/{outputId}/output") + @Operation(description = "Delete output from service", method = "DELETE", summary = "Delete service output", + responses = {@ApiResponse( + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))), + @ApiResponse(responseCode = "200", description = "Output deleted"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "404", description = "Output not found")}) + public Response deleteOutput(@PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, + @PathParam("outputId") final String outputId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) final String userId, + @Parameter(description = "Service Output to be deleted", required = true) final String componentInstOutputsMapObj) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + + try { + final OutputDefinition deleteOutput = outputsBusinessLogic.deleteOutput(componentId, userId, outputId); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), deleteOutput); + } catch (final ComponentException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete output for service + " + componentId + " + with id: " + outputId); + log.debug("Delete output failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/AttributeConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/AttributeConverter.java new file mode 100644 index 0000000000..085c075add --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/AttributeConverter.java @@ -0,0 +1,155 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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 com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.stream.JsonReader; +import java.io.StringReader; +import java.util.Map; +import org.apache.commons.lang3.StringUtils; +import org.onap.sdc.tosca.datatypes.model.EntrySchema; +import org.openecomp.sdc.be.model.AttributeDefinition; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.converters.DataTypePropertyConverter; +import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter; +import org.openecomp.sdc.be.tosca.model.ToscaAttribute; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.tosca.datatypes.ToscaFunctions; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +/** + * Handles conversions between attribute objects. + */ +@Component +@Scope(BeanDefinition.SCOPE_PROTOTYPE) +public class AttributeConverter { + + private static final Logger LOGGER = Logger.getLogger(AttributeConverter.class); + private final Map<String, DataTypeDefinition> dataTypes; + private final ToscaMapValueConverter toscaMapValueConverter; + + /** + * Creates an {@link AttributeConverter} with all the required data types. + * + * @param dataTypes all the data types required for the conversion + */ + public AttributeConverter(final Map<String, DataTypeDefinition> dataTypes) { + this.dataTypes = dataTypes; + toscaMapValueConverter = ToscaMapValueConverter.getInstance(); + } + + /** + * Converts and {@link AttributeDefinition} to a {@link ToscaAttribute}. + * + * @param attributeDefinition the attribute definition to be converted + * @return the {@link ToscaAttribute} instance based on the the given {@link AttributeDefinition} instance + */ + public ToscaAttribute convert(final AttributeDefinition attributeDefinition) { + final ToscaAttribute toscaAttribute = new ToscaAttribute(); + LOGGER.trace("Converting attribute '{}' from type '{}' with default value '{}'", + attributeDefinition.getName(), attributeDefinition.getType(), attributeDefinition.getDefaultValue()); + toscaAttribute.setType(attributeDefinition.getType()); + toscaAttribute.setDescription(attributeDefinition.getDescription()); + toscaAttribute.setStatus(attributeDefinition.getStatus()); + final Object defaultValue = convertToToscaObject(attributeDefinition.getName(), attributeDefinition.getType(), + attributeDefinition.getDefaultValue(), attributeDefinition.getEntry_schema(), false); + if (defaultValue != null) { + toscaAttribute.setDefault(defaultValue); + } + final Object value = convertToToscaObject(attributeDefinition.getName(), attributeDefinition.getType(), + attributeDefinition.getValue(), attributeDefinition.getEntry_schema(), false); + if (value != null) { + toscaAttribute.setValue(value); + } + + return toscaAttribute; + } + + private Object convertToToscaObject(final String name, final String attributeType, String value, + final EntrySchema schemaDefinition, final boolean preserveEmptyValue) { + final String innerType = schemaDefinition == null ? attributeType : schemaDefinition.getType(); + LOGGER.trace("Converting attribute '{}' of type '{}', value '{}', innerType '{}'", + name, attributeType, value, innerType); + if (StringUtils.isEmpty(value)) { + value = getTypeDefaultValue(attributeType); + if (StringUtils.isEmpty(value)) { + return null; + } + } + + try { + boolean isScalar = true; + + ToscaPropertyType predefinedType = ToscaPropertyType.isValidType(attributeType); + if (predefinedType == null) { + //not predefined, search in existing data types + final DataTypeDefinition dataTypeDefinition = dataTypes.get(attributeType); + predefinedType = toscaMapValueConverter.isScalarType(dataTypeDefinition); + if (predefinedType == null) { + isScalar = false; + } + } else { + isScalar = ToscaPropertyType.getTypeIfScalar(predefinedType.getType()) != null; + } + final JsonElement valueAsJson = parseToJson(value); + if (valueAsJson.isJsonObject()) { + final JsonObject jsonObj = valueAsJson.getAsJsonObject(); + if (jsonObj.entrySet().size() == 1 && jsonObj.has(ToscaFunctions.GET_ATTRIBUTE.getFunctionName())) { + return ToscaMapValueConverter.getInstance().handleComplexJsonValue(valueAsJson); + } + } + //if it has a converter + if (predefinedType != null && predefinedType.getValueConverter() != null) { + LOGGER.trace("It's well defined type. convert it"); + return predefinedType.getValueConverter().convertToToscaValue(value, innerType, dataTypes); + } + //no converter but scalar + if (isScalar) { + return toscaMapValueConverter.handleComplexJsonValue(valueAsJson); + } + + //if it is a data type + return toscaMapValueConverter.convertDataTypeToToscaObject( + innerType, dataTypes, null, false, valueAsJson, preserveEmptyValue); + + } catch (final Exception e) { + LOGGER.debug("convertToToscaValue failed to parse json value :", e); + return null; + } + + } + + private JsonElement parseToJson(final String value) { + final StringReader reader = new StringReader(value); + final JsonReader jsonReader = new JsonReader(reader); + jsonReader.setLenient(true); + return new JsonParser().parse(jsonReader); + } + + private String getTypeDefaultValue(final String attributeType) { + return DataTypePropertyConverter.getInstance().getDataTypePropertiesDefaultValuesRec(attributeType, dataTypes); + } + +}
\ No newline at end of file diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java index 97b113e93e..0459b5d1c6 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java @@ -29,7 +29,6 @@ import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_INPUT; import static org.openecomp.sdc.tosca.datatypes.ToscaFunctions.GET_PROPERTY; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; import fj.data.Either; import java.beans.IntrospectionException; import java.util.ArrayList; @@ -48,6 +47,7 @@ import java.util.Optional; import java.util.Set; import java.util.function.Supplier; import java.util.stream.Collectors; +import lombok.NoArgsConstructor; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.StringUtils; @@ -100,6 +100,7 @@ import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; +import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType; import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder; import org.openecomp.sdc.be.tosca.model.CapabilityFilter; import org.openecomp.sdc.be.tosca.model.NodeFilter; @@ -107,7 +108,6 @@ import org.openecomp.sdc.be.tosca.model.SubstitutionMapping; import org.openecomp.sdc.be.tosca.model.ToscaCapability; import org.openecomp.sdc.be.tosca.model.ToscaDataType; import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate; -import org.openecomp.sdc.be.tosca.model.ToscaMetadata; import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate; import org.openecomp.sdc.be.tosca.model.ToscaNodeType; import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate; @@ -121,8 +121,8 @@ import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement; import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate; import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil; import org.openecomp.sdc.be.tosca.utils.InputConverter; +import org.openecomp.sdc.be.tosca.utils.OutputConverter; import org.openecomp.sdc.common.log.wrappers.Logger; -import org.openecomp.sdc.externalupload.utils.ServiceUtils; import org.springframework.beans.factory.annotation.Autowired; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.DumperOptions.FlowStyle; @@ -137,6 +137,7 @@ import org.yaml.snakeyaml.nodes.Tag; import org.yaml.snakeyaml.representer.Represent; import org.yaml.snakeyaml.representer.Representer; +@NoArgsConstructor @org.springframework.stereotype.Component("tosca-export-handler") public class ToscaExportHandler { @@ -149,17 +150,21 @@ public class ToscaExportHandler { private GroupExportParser groupExportParser; private PropertyConvertor propertyConvertor; private InputConverter inputConverter; + private OutputConverter outputConverter; private InterfaceLifecycleOperation interfaceLifecycleOperation; private InterfacesOperationsConverter interfacesOperationsConverter; @Autowired - public ToscaExportHandler(ApplicationDataTypeCache dataTypeCache, ToscaOperationFacade toscaOperationFacade, - CapabilityRequirementConverter capabilityRequirementConverter, - PolicyExportParser policyExportParser, - GroupExportParser groupExportParser, PropertyConvertor propertyConvertor, - InputConverter inputConverter, - InterfaceLifecycleOperation interfaceLifecycleOperation, - InterfacesOperationsConverter interfacesOperationsConverter) { + public ToscaExportHandler(final ApplicationDataTypeCache dataTypeCache, + final ToscaOperationFacade toscaOperationFacade, + final CapabilityRequirementConverter capabilityRequirementConverter, + final PolicyExportParser policyExportParser, + final GroupExportParser groupExportParser, + final PropertyConvertor propertyConvertor, + final InputConverter inputConverter, + final OutputConverter outputConverter, + final InterfaceLifecycleOperation interfaceLifecycleOperation, + final InterfacesOperationsConverter interfacesOperationsConverter) { this.dataTypeCache = dataTypeCache; this.toscaOperationFacade = toscaOperationFacade; this.capabilityRequirementConverter = capabilityRequirementConverter; @@ -167,6 +172,7 @@ public class ToscaExportHandler { this.groupExportParser = groupExportParser; this.propertyConvertor = propertyConvertor; this.inputConverter = inputConverter; + this.outputConverter = outputConverter; this.interfaceLifecycleOperation = interfaceLifecycleOperation; this.interfacesOperationsConverter = interfacesOperationsConverter; } @@ -181,9 +187,6 @@ public class ToscaExportHandler { private static final String NATIVE_ROOT = "tosca.nodes.Root"; private static final YamlUtil yamlUtil = new YamlUtil(); - public ToscaExportHandler() { - } - public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) { return convertToToscaTemplate(component).left().map(this::createToscaRepresentation); } @@ -321,16 +324,17 @@ public class ToscaExportHandler { topologyTemplate.setInputs(inputs); } + final Map<String, ToscaProperty> outputs = outputConverter.convert(component.getOutputs(), dataTypes); + if (!outputs.isEmpty()) { + topologyTemplate.setOutputs(outputs); + } + final List<ComponentInstance> componentInstances = component.getComponentInstances(); - Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = - component.getComponentInstancesProperties(); - Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = - component.getComponentInstancesInterfaces(); + Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component.getComponentInstancesProperties(); + Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces(); if (CollectionUtils.isNotEmpty(componentInstances)) { - final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates = - convertNodeTemplates(component, componentInstances, - componentInstancesProperties, componentInstanceInterfaces, - componentCache, dataTypes, topologyTemplate); + final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates = convertNodeTemplates(component, componentInstances, + componentInstancesProperties, componentInstanceInterfaces, componentCache, dataTypes, topologyTemplate); if (nodeTemplates.isRight()) { return Either.right(nodeTemplates.right().value()); } @@ -338,8 +342,7 @@ public class ToscaExportHandler { topologyTemplate.setNode_templates(nodeTemplates.left().value()); } final Map<String, ToscaRelationshipTemplate> relationshipTemplatesMap = - new ToscaExportRelationshipTemplatesHandler() - .createFrom(topologyTemplate.getNode_templates()); + new ToscaExportRelationshipTemplatesHandler().createFrom(topologyTemplate.getNode_templates()); if (!relationshipTemplatesMap.isEmpty()) { topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap); } @@ -430,11 +433,12 @@ public class ToscaExportHandler { } private Map<String, String> convertMetadata(Component component, boolean isInstance, - ComponentInstance componentInstance) { + ComponentInstance componentInstance) { Map<String, String> toscaMetadata = new LinkedHashMap<>(); toscaMetadata.put(JsonPresentationFields.INVARIANT_UUID.getPresentation(), component.getInvariantUUID()); toscaMetadata.put(JsonPresentationFields.UUID.getPresentation(), component.getUUID()); - toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); + toscaMetadata + .put(JsonPresentationFields.NAME.getPresentation(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), component.getDescription()); List<CategoryDefinition> categories = component.getCategories(); @@ -442,14 +446,14 @@ public class ToscaExportHandler { toscaMetadata.put(JsonPresentationFields.CATEGORY.getPresentation(), categoryDefinition.getName()); if (isInstance) { - toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(),component.getVersion()); + toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), component.getVersion()); toscaMetadata.put(JsonPresentationFields.CUSTOMIZATION_UUID.getPresentation(), componentInstance.getCustomizationUUID()); if (componentInstance.getSourceModelInvariant() != null && !componentInstance.getSourceModelInvariant().isEmpty()) { - toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(),componentInstance.getComponentVersion()); - toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(),componentInstance.getSourceModelInvariant()); - toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(),componentInstance.getSourceModelUuid()); - toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(),componentInstance.getSourceModelName()); + toscaMetadata.put(JsonPresentationFields.VERSION.getPresentation(), componentInstance.getComponentVersion()); + toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_INVARIANT.getPresentation(), componentInstance.getSourceModelInvariant()); + toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_UUID.getPresentation(), componentInstance.getSourceModelUuid()); + toscaMetadata.put(JsonPresentationFields.CI_SOURCE_MODEL_NAME.getPresentation(), componentInstance.getSourceModelName()); if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) { toscaMetadata.put(JsonPresentationFields.NAME.getPresentation(), componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceProxy.getDisplayValue()); @@ -458,7 +462,7 @@ public class ToscaExportHandler { componentInstance.getSourceModelName() + " " + OriginTypeEnum.ServiceSubstitution .getDisplayValue()); } - toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(),componentInstance.getDescription()); + toscaMetadata.put(JsonPresentationFields.DESCRIPTION.getPresentation(), componentInstance.getDescription()); } } @@ -466,49 +470,43 @@ public class ToscaExportHandler { case RESOURCE: Resource resource = (Resource) component; - if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) { + if (isInstance && (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy + || componentInstance.getOriginType() == OriginTypeEnum.ServiceSubstitution)) { toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), componentInstance.getOriginType().getDisplayValue()); } else { toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), resource.getResourceType().name()); } toscaMetadata.put(JsonPresentationFields.SUB_CATEGORY.getPresentation(), categoryDefinition.getSubcategories().get(0).getName()); toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR.getPresentation(), resource.getVendorName()); - toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(),resource.getVendorRelease()); - toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(),resource.getResourceVendorModelNumber()); + toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_RELEASE.getPresentation(), resource.getVendorRelease()); + toscaMetadata.put(JsonPresentationFields.RESOURCE_VENDOR_MODEL_NUMBER.getPresentation(), resource.getResourceVendorModelNumber()); break; case SERVICE: Service service = (Service) component; - toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(),component.getComponentType().getValue()); - toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(),service.getServiceType()); - toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(),service.getServiceRole()); - toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(),service.getServiceFunction()); - toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(),service.getEnvironmentContext()); - toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(),service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType()); + toscaMetadata.put(JsonPresentationFields.TYPE.getPresentation(), component.getComponentType().getValue()); + toscaMetadata.put(JsonPresentationFields.SERVICE_TYPE.getPresentation(), service.getServiceType()); + toscaMetadata.put(JsonPresentationFields.SERVICE_ROLE.getPresentation(), service.getServiceRole()); + toscaMetadata.put(JsonPresentationFields.SERVICE_FUNCTION.getPresentation(), service.getServiceFunction()); + toscaMetadata.put(JsonPresentationFields.ENVIRONMENT_CONTEXT.getPresentation(), service.getEnvironmentContext()); + toscaMetadata.put(JsonPresentationFields.INSTANTIATION_TYPE.getPresentation(), + service.getEnvironmentContext() == null ? StringUtils.EMPTY : service.getInstantiationType()); if (!isInstance) { // DE268546 - toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(),service.isEcompGeneratedNaming().toString()); - toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(),service.isEcompGeneratedNaming().toString()); - toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(),service.getNamingPolicy()); + toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString()); + toscaMetadata.put(JsonPresentationFields.ECOMP_GENERATED_NAMING.getPresentation(), service.isEcompGeneratedNaming().toString()); + toscaMetadata.put(JsonPresentationFields.NAMING_POLICY.getPresentation(), service.getNamingPolicy()); } break; default: log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType()); } - for (final String key: component.getCategorySpecificMetadata().keySet()) { + for (final String key : component.getCategorySpecificMetadata().keySet()) { toscaMetadata.put(key, component.getCategorySpecificMetadata().get(key)); } return toscaMetadata; } - private void resolveInstantiationTypeAndSetItToToscaMetaData(ToscaMetadata toscaMetadata, Service service) { - if (service.getInstantiationType() != null) { - toscaMetadata.setInstantiationType(service.getInstantiationType()); - } else { - toscaMetadata.setInstantiationType(StringUtils.EMPTY); - } - } - private Either<ImmutablePair<ToscaTemplate, Map<String, Component>>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) { @@ -681,7 +679,7 @@ public class ToscaExportHandler { keyNameBuilder.append(component.getName()); addImports(imports, keyNameBuilder, files); dependencies - .add(new ImmutableTriple<String, String, Component>(artifactName, artifactDefinition.getEsId(), component)); + .add(new ImmutableTriple<>(artifactName, artifactDefinition.getEsId(), component)); if (!ModelConverter.isAtomicComponent(component)) { final Map<String, String> interfaceFiles = new HashMap<>(); @@ -778,9 +776,9 @@ public class ToscaExportHandler { if (CollectionUtils.isNotEmpty(dataType.getProperties())) { toscaDataType.setProperties(dataType.getProperties().stream() .collect(Collectors.toMap( - s -> s.getName(), + PropertyDataDefinition::getName, s -> propertyConvertor - .convertProperty(dataTypes, s, PropertyConvertor.PropertyType.PROPERTY) + .convertProperty(dataTypes, s, PropertyType.PROPERTY) ))); } toscaDataTypeMap.put(dataType.getName(), toscaDataType); @@ -910,8 +908,7 @@ public class ToscaExportHandler { if (componentInstancesInputs != null && componentInstancesInputs.containsKey(instanceUniqueId) && !isComponentOfTypeServiceProxy(componentInstance)) { //For service proxy the inputs are already handled under instance properties above - addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, - props); + addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId, props); } //M3[00001] - NODE TEMPLATE INTERFACES - START @@ -987,7 +984,8 @@ public class ToscaExportHandler { .getUniqueId(), instInterface)); final Map<String, Object> interfaceMap = interfacesOperationsConverter - .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance), isComponentOfTypeServiceProxy(componentInstance)); + .getInterfacesMap(parentComponent, componentInstance, tmpInterfaces, dataTypes, isComponentOfTypeServiceProxy(componentInstance), + isComponentOfTypeServiceProxy(componentInstance)); interfacesOperationsConverter.removeInterfacesWithoutOperations(interfaceMap); nodeTemplate.setInterfaces(MapUtils.isEmpty(interfaceMap) ? null : interfaceMap); @@ -998,33 +996,6 @@ public class ToscaExportHandler { && componentInstance.getOriginType().getValue().equals("Service Proxy"); } - //M3[00001] - NODE TEMPLATE INTERFACES - START - private Map<String, Object> getComponentInstanceInterfaceInstances( - Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaces, - ComponentInstance componentInstance, - String instanceUniqueId) { - if (MapUtils.isEmpty(componentInstancesInterfaces)) { - return null; - } - - List<ComponentInstanceInterface> componentInstanceInterfaces = - componentInstancesInterfaces.get(instanceUniqueId); - - if (CollectionUtils.isEmpty(componentInstanceInterfaces)) { - return null; - } - - Map<String, Object> interfaces = new HashMap<>(); - for (ComponentInstanceInterface componentInstanceInterface : componentInstanceInterfaces) { - interfaces.put(componentInstanceInterface.getInterfaceId(), - removeOperationsKeyFromInterface(componentInstanceInterface.getInterfaceInstanceDataDefinition())); - } - - componentInstance.setInterfaces(interfaces); - - return interfaces; - } - private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes, Map<String, List<ComponentInstanceInput>> componentInstancesInputs, String instanceUniqueId, Map<String, Object> props) { @@ -1469,10 +1440,9 @@ public class ToscaExportHandler { } /** - * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement - * belongs to a relationship IF 1.The name of the requirement equals to the "requirement" field of the relation; AND - * 2. In case of a non-atomic resource, OwnerId of the requirement equals to requirementOwnerId of the relation OR - * uniqueId of toInstance equals to capabilityOwnerId of the relation + * Allows detecting the requirement belonging to the received relationship The detection logic is: A requirement belongs to a relationship IF + * 1.The name of the requirement equals to the "requirement" field of the relation; AND 2. In case of a non-atomic resource, OwnerId of the + * requirement equals to requirementOwnerId of the relation OR uniqueId of toInstance equals to capabilityOwnerId of the relation */ private boolean isRequirementBelongToRelation(Component originComponent, RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId) { @@ -1645,7 +1615,7 @@ public class ToscaExportHandler { addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName)); } else { if (propertyName != null) { - List propsList = new ArrayList(); + List<Object> propsList = new ArrayList<>(); addPropertyConstraintValueToList(propertyName, propertyValObj, propsList); propertyMapCopy.put(propertyName, propsList); } else { @@ -1676,7 +1646,7 @@ public class ToscaExportHandler { addPropertyConstraintValueToList(propertyName, propertyValObj, propertyMapCopy.get(propertyName)); } else { if (propertyName != null) { - final List<Object> propsList = new ArrayList(); + final List<Object> propsList = new ArrayList<>(); addPropertyConstraintValueToList(propertyName, propertyValObj, propsList); propertyMapCopy.put(propertyName, propsList); } else { @@ -1689,7 +1659,7 @@ public class ToscaExportHandler { addCalculatedConstraintsIntoPropertiesList(propertiesCopy, entry)); } - private void addPropertyConstraintValueToList(String propertyName, Map propertyValObj, List propsList) { + private void addPropertyConstraintValueToList(String propertyName, Map<String, List<Object>> propertyValObj, List<Object> propsList) { if (propertyValObj.containsKey(propertyName)) { propsList.add(propertyValObj.get(propertyName)); } else { @@ -1716,6 +1686,7 @@ public class ToscaExportHandler { } private class RepresentToscaPropertyAssignment implements Represent { + public Node representData(Object data) { final ToscaPropertyAssignment toscaOperationAssignment = (ToscaPropertyAssignment) data; if (toscaOperationAssignment.getValue() instanceof String) { @@ -1861,24 +1832,6 @@ public class ToscaExportHandler { } } - private Object removeOperationsKeyFromInterface(Object interfaceInstanceDataDefinition) { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); - - Map<String, Object> interfaceAsMap = ServiceUtils.getObjectAsMap(interfaceInstanceDataDefinition); - Map<String, Object> operations = (Map<String, Object>) interfaceAsMap.remove("operations"); - interfaceAsMap.remove("empty"); - - if (MapUtils.isNotEmpty(operations)) { - interfaceAsMap.putAll(operations); - } - - Object interfaceObject = objectMapper.convertValue(interfaceAsMap, Object.class); - - return interfaceObject; - - } - private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) { if (component == null || CollectionUtils.isEmpty(component.getInputs())) { return Collections.emptyMap(); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaAttribute.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaAttribute.java new file mode 100644 index 0000000000..891347d191 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaAttribute.java @@ -0,0 +1,55 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.model; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * Represents a TOSCA Attribute Definition (see TOSCA 1.3, Section 3.6.12 Attribute definition) + */ +@NoArgsConstructor +public class ToscaAttribute { + + //should be default, but it is a reserved word in Java + private Object defaultValue; + @Getter + @Setter + private Object value; + @Getter + @Setter + private String type; + @Getter + @Setter + private String description; + @Getter + @Setter + private String status; + + public Object getDefault() { + return defaultValue; + } + + public void setDefault(final Object defaultValue) { + this.defaultValue = defaultValue; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaOutput.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaOutput.java new file mode 100644 index 0000000000..826c7fcd8d --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaOutput.java @@ -0,0 +1,32 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.model; + +public class ToscaOutput extends ToscaProperty { + + public ToscaOutput(final ToscaAttribute toscaAttribute) { + this.setDescription(toscaAttribute.getDescription()); + this.setType(toscaAttribute.getType()); + this.setDefaultp(toscaAttribute.getDefault()); + this.setDescription(toscaAttribute.getStatus()); + this.setValue(toscaAttribute.getValue()); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaProperty.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaProperty.java index 952423e039..7ebb2cb00d 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaProperty.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaProperty.java @@ -7,9 +7,9 @@ * 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. @@ -32,6 +32,9 @@ public class ToscaProperty { private Object _defaultp_; @Getter @Setter + private Object value; + @Getter + @Setter private String type; @Getter @Setter diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTopolgyTemplate.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTopolgyTemplate.java index 00ab08b677..3cecbc2871 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTopolgyTemplate.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTopolgyTemplate.java @@ -7,9 +7,9 @@ * 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. @@ -31,6 +31,8 @@ public class ToscaTopolgyTemplate { @Setter private Map<String, ToscaProperty> inputs; @Setter + private Map<String, ToscaProperty> outputs; + @Setter private Map<String, ToscaNodeTemplate> node_templates; private Map<String, ToscaGroupTemplate> groups; private Map<String, ToscaPolicyTemplate> policies; @@ -40,16 +42,16 @@ public class ToscaTopolgyTemplate { private Map<String, ToscaRelationshipTemplate> relationshipTemplates; public void addGroups(Map<String, ToscaGroupTemplate> groups) { - if ( this.groups == null ){ + if (this.groups == null) { this.groups = new HashMap<>(); } this.groups.putAll(groups); } - public void addPolicies(Map<String, ToscaPolicyTemplate> policiesMap) { - if ( this.policies == null ){ + public void addPolicies(Map<String, ToscaPolicyTemplate> policiesMap) { + if (this.policies == null) { this.policies = new HashMap<>(); } - this.policies.putAll(policiesMap); - } + this.policies.putAll(policiesMap); + } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/OutputConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/OutputConverter.java new file mode 100644 index 0000000000..85400a747a --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/OutputConverter.java @@ -0,0 +1,64 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 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.utils; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.commons.collections.CollectionUtils; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.OutputDefinition; +import org.openecomp.sdc.be.tosca.AttributeConverter; +import org.openecomp.sdc.be.tosca.model.ToscaAttribute; +import org.openecomp.sdc.be.tosca.model.ToscaOutput; +import org.openecomp.sdc.be.tosca.model.ToscaProperty; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class OutputConverter { + + private final ObjectProvider<AttributeConverter> attributeConverterProvider; + + @Autowired + public OutputConverter(final ObjectProvider<AttributeConverter> attributeConverterProvider) { + this.attributeConverterProvider = attributeConverterProvider; + } + + public Map<String, ToscaProperty> convert(final List<OutputDefinition> outputDefinitionList, + final Map<String, DataTypeDefinition> dataTypes) { + final AttributeConverter attributeConverter = this.attributeConverterProvider.getObject(dataTypes); + final Map<String, ToscaProperty> outputMap = new HashMap<>(); + if (CollectionUtils.isEmpty(outputDefinitionList)) { + return Collections.emptyMap(); + } + outputDefinitionList.forEach(outputDefinition -> { + final ToscaAttribute toscaAttribute = attributeConverter.convert(outputDefinition); + final ToscaProperty toscaProperty = new ToscaOutput(toscaAttribute); + outputMap.put(outputDefinition.getName(), toscaProperty); + }); + return outputMap; + } +} + + + diff --git a/catalog-be/src/main/java/org/openecomp/sdc/config/CatalogBESpringConfig.java b/catalog-be/src/main/java/org/openecomp/sdc/config/CatalogBESpringConfig.java index 0c8d0fc012..52a1023062 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/config/CatalogBESpringConfig.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/config/CatalogBESpringConfig.java @@ -42,27 +42,28 @@ import org.springframework.core.annotation.Order; @Configuration @ComponentScan({"org.openecomp.sdc.be.user", - "org.openecomp.sdc.be.facade.operations", - "org.openecomp.sdc.be.impl", - "org.openecomp.sdc.be.auditing.impl", - "org.openecomp.sdc.be.distribution", - "org.openecomp.sdc.be.switchover.detector", - "org.openecomp.sdc.be.tosca", - "org.openecomp.sdc.be.components.validation", - "org.openecomp.sdc.be.catalog.impl", - "org.openecomp.sdc.be.components.impl", - "org.openecomp.sdc.be.components.path", - "org.openecomp.sdc.be.components.merge", - "org.openecomp.sdc.be.components.csar", - "org.openecomp.sdc.be.components.property", - "org.openecomp.sdc.be.csar.security", - "org.openecomp.sdc.be.datamodel.utils", - "org.openecomp.sdc.be.components.upgrade", - "org.openecomp.sdc.be.externalapi.servlet", - "org.openecomp.sdc.be.servlets", - "org.openecomp.sdc.be.filters", - "org.openecomp.sdc.be.plugins", - "org.openecomp.sdc.be.togglz" + "org.openecomp.sdc.be.facade.operations", + "org.openecomp.sdc.be.impl", + "org.openecomp.sdc.be.auditing.impl", + "org.openecomp.sdc.be.distribution", + "org.openecomp.sdc.be.switchover.detector", + "org.openecomp.sdc.be.tosca", + "org.openecomp.sdc.be.components.validation", + "org.openecomp.sdc.be.catalog.impl", + "org.openecomp.sdc.be.components.impl", + "org.openecomp.sdc.be.components.path", + "org.openecomp.sdc.be.components.merge", + "org.openecomp.sdc.be.components.csar", + "org.openecomp.sdc.be.components.property", + "org.openecomp.sdc.be.components.attribute", + "org.openecomp.sdc.be.csar.security", + "org.openecomp.sdc.be.datamodel.utils", + "org.openecomp.sdc.be.components.upgrade", + "org.openecomp.sdc.be.externalapi.servlet", + "org.openecomp.sdc.be.servlets", + "org.openecomp.sdc.be.filters", + "org.openecomp.sdc.be.plugins", + "org.openecomp.sdc.be.togglz" }) public class CatalogBESpringConfig { diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java index 12ffe1c193..456074fbba 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java @@ -1169,7 +1169,7 @@ class ComponentInstanceBusinessLogicTest { .thenReturn(StorageOperationStatus.OK); result = testSubject.updateInstanceRequirement(componentTypeEnum, containerComponentId, - componentInstanceUniqueId, capabilityType, capabilityName, requirementDef, userId); + componentInstanceUniqueId, requirementDef, userId); assertEquals(requirementDef, result.left().value()); } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java index 55a73c6f3b..d219347fc4 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java @@ -142,52 +142,52 @@ public class ResourceBusinessLogicTest { private static final String GENERIC_CR_NAME = "org.openecomp.resource.abstract.nodes.CR"; private static final String GENERIC_PNF_NAME = "org.openecomp.resource.abstract.nodes.PNF"; - final ServletContext servletContext = Mockito.mock(ServletContext.class); + private final ServletContext servletContext = Mockito.mock(ServletContext.class); IElementOperation mockElementDao; - JanusGraphDao mockJanusGraphDao = Mockito.mock(JanusGraphDao.class); - UserBusinessLogic mockUserAdmin = Mockito.mock(UserBusinessLogic.class); - ToscaOperationFacade toscaOperationFacade = Mockito.mock(ToscaOperationFacade.class); - NodeTypeOperation nodeTypeOperation = Mockito.mock(NodeTypeOperation.class); - NodeTemplateOperation nodeTemplateOperation = Mockito.mock(NodeTemplateOperation.class); - TopologyTemplateOperation topologyTemplateOperation = Mockito.mock(TopologyTemplateOperation.class); - final LifecycleBusinessLogic lifecycleBl = Mockito.mock(LifecycleBusinessLogic.class); - final CatalogOperation catalogOperation = Mockito.mock(CatalogOperation.class); - final ICapabilityTypeOperation capabilityTypeOperation = Mockito.mock(ICapabilityTypeOperation.class); - final PropertyOperation propertyOperation = Mockito.mock(PropertyOperation.class); - final ApplicationDataTypeCache applicationDataTypeCache = Mockito.mock(ApplicationDataTypeCache.class); - WebAppContextWrapper webAppContextWrapper = Mockito.mock(WebAppContextWrapper.class); - UserValidations userValidations = Mockito.mock(UserValidations.class); - WebApplicationContext webAppContext = Mockito.mock(WebApplicationContext.class); - IInterfaceLifecycleOperation interfaceTypeOperation = Mockito.mock(IInterfaceLifecycleOperation.class); - ArtifactCassandraDao artifactCassandraDao = Mockito.mock(ArtifactCassandraDao.class); - IElementOperation elementDao = new ElementOperationMock(); - - CsarUtils csarUtils = Mockito.mock(CsarUtils.class); - UserBusinessLogic userBusinessLogic = Mockito.mock(UserBusinessLogic.class); - IGroupOperation groupOperation = Mockito.mock(IGroupOperation.class); - IGroupInstanceOperation groupInstanceOperation = Mockito.mock(IGroupInstanceOperation.class); - IGroupTypeOperation groupTypeOperation = Mockito.mock(IGroupTypeOperation.class); - GroupBusinessLogic groupBusinessLogic = Mockito.mock(GroupBusinessLogic.class); - InterfaceOperation interfaceOperation = Mockito.mock(InterfaceOperation.class); - ArtifactsOperations artifactToscaOperation = Mockito.mock(ArtifactsOperations.class); - private PropertyBusinessLogic propertyBusinessLogic = Mockito.mock(PropertyBusinessLogic.class); - ArtifactsResolver artifactsResolver = Mockito.mock(ArtifactsResolver.class); - InterfaceLifecycleOperation interfaceLifecycleTypeOperation = Mockito.mock(InterfaceLifecycleOperation.class); - ComponentInstanceBusinessLogic componentInstanceBusinessLogic = Mockito.mock(ComponentInstanceBusinessLogic.class); - ResourceImportManager resourceImportManager = Mockito.mock(ResourceImportManager.class); - InputsBusinessLogic inputsBusinessLogic = Mockito.mock(InputsBusinessLogic.class); - CompositionBusinessLogic compositionBusinessLogic = Mockito.mock(CompositionBusinessLogic.class); - ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic = Mockito.mock(ResourceDataMergeBusinessLogic.class); - CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic = Mockito.mock(CsarArtifactsAndGroupsBusinessLogic.class); - MergeInstanceUtils mergeInstanceUtils = Mockito.mock(MergeInstanceUtils.class); - UiComponentDataConverter uiComponentDataConverter = Mockito.mock(UiComponentDataConverter.class); - ToscaExportHandler toscaExportHandler = Mockito.mock(ToscaExportHandler.class); - PolicyBusinessLogic policyBusinessLogic = Mockito.mock(PolicyBusinessLogic.class); - + private final JanusGraphDao mockJanusGraphDao = Mockito.mock(JanusGraphDao.class); + private final UserBusinessLogic mockUserAdmin = Mockito.mock(UserBusinessLogic.class); + private final ToscaOperationFacade toscaOperationFacade = Mockito.mock(ToscaOperationFacade.class); + private final NodeTypeOperation nodeTypeOperation = Mockito.mock(NodeTypeOperation.class); + private final NodeTemplateOperation nodeTemplateOperation = Mockito.mock(NodeTemplateOperation.class); + private final TopologyTemplateOperation topologyTemplateOperation = Mockito.mock(TopologyTemplateOperation.class); + private final LifecycleBusinessLogic lifecycleBl = Mockito.mock(LifecycleBusinessLogic.class); + private final CatalogOperation catalogOperation = Mockito.mock(CatalogOperation.class); + private final ICapabilityTypeOperation capabilityTypeOperation = Mockito.mock(ICapabilityTypeOperation.class); + private final PropertyOperation propertyOperation = Mockito.mock(PropertyOperation.class); + private final ApplicationDataTypeCache applicationDataTypeCache = Mockito.mock(ApplicationDataTypeCache.class); + private final WebAppContextWrapper webAppContextWrapper = Mockito.mock(WebAppContextWrapper.class); + private final UserValidations userValidations = Mockito.mock(UserValidations.class); + private final WebApplicationContext webAppContext = Mockito.mock(WebApplicationContext.class); + private final IInterfaceLifecycleOperation interfaceTypeOperation = Mockito.mock(IInterfaceLifecycleOperation.class); + private final ArtifactCassandraDao artifactCassandraDao = Mockito.mock(ArtifactCassandraDao.class); + private final IElementOperation elementDao = new ElementOperationMock(); + + private final CsarUtils csarUtils = Mockito.mock(CsarUtils.class); + private final UserBusinessLogic userBusinessLogic = Mockito.mock(UserBusinessLogic.class); + private final IGroupOperation groupOperation = Mockito.mock(IGroupOperation.class); + private final IGroupInstanceOperation groupInstanceOperation = Mockito.mock(IGroupInstanceOperation.class); + private final IGroupTypeOperation groupTypeOperation = Mockito.mock(IGroupTypeOperation.class); + private final GroupBusinessLogic groupBusinessLogic = Mockito.mock(GroupBusinessLogic.class); + private final InterfaceOperation interfaceOperation = Mockito.mock(InterfaceOperation.class); + private final ArtifactsOperations artifactToscaOperation = Mockito.mock(ArtifactsOperations.class); + private final PropertyBusinessLogic propertyBusinessLogic = Mockito.mock(PropertyBusinessLogic.class); + private final ArtifactsResolver artifactsResolver = Mockito.mock(ArtifactsResolver.class); + private final InterfaceLifecycleOperation interfaceLifecycleTypeOperation = Mockito.mock(InterfaceLifecycleOperation.class); + private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic = Mockito.mock(ComponentInstanceBusinessLogic.class); + private final ResourceImportManager resourceImportManager = Mockito.mock(ResourceImportManager.class); + private final InputsBusinessLogic inputsBusinessLogic = Mockito.mock(InputsBusinessLogic.class); + private final OutputsBusinessLogic outputsBusinessLogic = Mockito.mock(OutputsBusinessLogic.class); + private final CompositionBusinessLogic compositionBusinessLogic = Mockito.mock(CompositionBusinessLogic.class); + private final ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic = Mockito.mock(ResourceDataMergeBusinessLogic.class); + private final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic = Mockito.mock(CsarArtifactsAndGroupsBusinessLogic.class); + private final MergeInstanceUtils mergeInstanceUtils = Mockito.mock(MergeInstanceUtils.class); + private final UiComponentDataConverter uiComponentDataConverter = Mockito.mock(UiComponentDataConverter.class); + private final ToscaExportHandler toscaExportHandler = Mockito.mock(ToscaExportHandler.class); + private final PolicyBusinessLogic policyBusinessLogic = Mockito.mock(PolicyBusinessLogic.class); @InjectMocks ResponseFormatManager responseManager = null; - GraphLockOperation graphLockOperation = Mockito.mock(GraphLockOperation.class); + private final GraphLockOperation graphLockOperation = Mockito.mock(GraphLockOperation.class); User user = null; Resource resourceResponse = null; Resource genericVF = null; @@ -285,7 +285,7 @@ public class ResourceBusinessLogicTest { artifactManager.setNodeTemplateOperation(nodeTemplateOperation); bl = new ResourceBusinessLogic(mockElementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation, interfaceLifecycleTypeOperation, artifactManager, componentInstanceBusinessLogic, - resourceImportManager, inputsBusinessLogic, compositionBusinessLogic, resourceDataMergeBusinessLogic, + resourceImportManager, inputsBusinessLogic, outputsBusinessLogic, compositionBusinessLogic, resourceDataMergeBusinessLogic, csarArtifactsAndGroupsBusinessLogic, mergeInstanceUtils, uiComponentDataConverter, csarBusinessLogic, artifactToscaOperation, propertyBusinessLogic, componentContactIdValidator, componentNameValidator, componentTagsValidator, componentValidator, componentIconValidator, componentProjectCodeValidator, @@ -2273,4 +2273,4 @@ public class ResourceBusinessLogicTest { assertTrue(result.isRight()); assertTrue(result.right().value() instanceof ByActionStatusComponentException); } -}
\ No newline at end of file +} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTest.java index 48c2c9c2a2..47ca94dbdc 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTest.java @@ -7,9 +7,9 @@ * 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. @@ -30,6 +30,7 @@ import org.openecomp.sdc.be.components.csar.CsarBusinessLogic; import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.impl.CompositionBusinessLogic; import org.openecomp.sdc.be.components.impl.InputsBusinessLogic; +import org.openecomp.sdc.be.components.impl.OutputsBusinessLogic; import org.openecomp.sdc.be.components.impl.PolicyBusinessLogic; import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; @@ -56,6 +57,7 @@ public class CheckoutTest extends LifecycleTestBase { private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic = Mockito.mock(ComponentInstanceBusinessLogic.class); private final ResourceImportManager resourceImportManager = Mockito.mock(ResourceImportManager.class); private final InputsBusinessLogic inputsBusinessLogic = Mockito.mock(InputsBusinessLogic.class); + private final OutputsBusinessLogic outputsBusinessLogic = Mockito.mock(OutputsBusinessLogic.class); private final CompositionBusinessLogic compositionBusinessLogic = Mockito.mock(CompositionBusinessLogic.class); private final ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic = Mockito.mock(ResourceDataMergeBusinessLogic.class); private final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic = Mockito.mock(CsarArtifactsAndGroupsBusinessLogic.class); @@ -63,13 +65,13 @@ public class CheckoutTest extends LifecycleTestBase { private final UiComponentDataConverter uiComponentDataConverter = Mockito.mock(UiComponentDataConverter.class); private final CsarBusinessLogic csarBusinessLogic = Mockito.mock(CsarBusinessLogic.class); private final PropertyBusinessLogic propertyBusinessLogic = Mockito.mock(PropertyBusinessLogic.class); - protected ComponentContactIdValidator componentContactIdValidator = new ComponentContactIdValidator(componentsUtils); - protected ComponentNameValidator componentNameValidator = new ComponentNameValidator(componentsUtils, toscaOperationFacade); + private final ComponentContactIdValidator componentContactIdValidator = new ComponentContactIdValidator(componentsUtils); + private final ComponentNameValidator componentNameValidator = new ComponentNameValidator(componentsUtils, toscaOperationFacade); private final PolicyBusinessLogic policyBusinessLogic = Mockito.mock(PolicyBusinessLogic.class); @InjectMocks ResourceBusinessLogic bl = new ResourceBusinessLogic(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation, interfaceLifecycleTypeOperation, artifactsBusinessLogic, - componentInstanceBusinessLogic, resourceImportManager, inputsBusinessLogic, compositionBusinessLogic, + componentInstanceBusinessLogic, resourceImportManager, inputsBusinessLogic, outputsBusinessLogic,compositionBusinessLogic, resourceDataMergeBusinessLogic, csarArtifactsAndGroupsBusinessLogic, mergeInstanceUtils, uiComponentDataConverter, csarBusinessLogic, artifactToscaOperation, propertyBusinessLogic, componentContactIdValidator, componentNameValidator, componentTagsValidator, componentValidator, diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentInstanceServletTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentInstanceServletTest.java index abe2544f73..d164fe3058 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentInstanceServletTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentInstanceServletTest.java @@ -498,7 +498,7 @@ class ComponentInstanceServletTest extends JerseyTest { eq(AuditingActionEnum.GET_TOSCA_MODEL), eq(ComponentTypeEnum.SERVICE))) .thenReturn(Either.left(requirementDefinition)); when(componentInstanceBusinessLogic.updateInstanceRequirement(ComponentTypeEnum.SERVICE, - componentId, componentInstanceId, capabilityType, requirementName, requirementDefinition, USER_ID)) + componentId, componentInstanceId, requirementDefinition, USER_ID)) .thenReturn(Either.left(requirementDefinition)); when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat); when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200); 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 index d4fb60e878..3c425c1f08 100644 --- 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 @@ -124,7 +124,7 @@ class InterfacesOperationsConverterTest { final Map<String, Object> interfaceTypeElement = addInterfaceTypeElement(component, new ArrayList<>()); - ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, + ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null,null, interfacesOperationsConverter); ToscaTemplate template = new ToscaTemplate("test"); template.setInterface_types(interfaceTypeElement); @@ -152,7 +152,7 @@ class InterfacesOperationsConverterTest { final Map<String, Object> interfaceTypeElement = addInterfaceTypeElement(component, new ArrayList<>()); - ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, + ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null,null, interfacesOperationsConverter); ToscaTemplate template = new ToscaTemplate("testService"); template.setInterface_types(interfaceTypeElement); @@ -178,7 +178,7 @@ class InterfacesOperationsConverterTest { ToscaNodeType nodeType = new ToscaNodeType(); interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false); - ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, + ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null,null, interfacesOperationsConverter); ToscaTemplate template = new ToscaTemplate(NODE_TYPE_NAME); Map<String, ToscaNodeType> nodeTypes = new HashMap<>(); @@ -208,7 +208,7 @@ class InterfacesOperationsConverterTest { ToscaNodeType nodeType = new ToscaNodeType(); interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false); - ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, + ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null,null, interfacesOperationsConverter); ToscaTemplate template = new ToscaTemplate("testService"); Map<String, ToscaNodeType> nodeTypes = new HashMap<>(); @@ -267,7 +267,7 @@ class InterfacesOperationsConverterTest { ToscaNodeType nodeType = new ToscaNodeType(); interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, null, false); - ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, + ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null,null, interfacesOperationsConverter); ToscaTemplate template = new ToscaTemplate("test"); Map<String, ToscaNodeType> nodeTypes = new HashMap<>(); @@ -301,7 +301,7 @@ class InterfacesOperationsConverterTest { ToscaNodeType nodeType = new ToscaNodeType(); interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false); - ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, + ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null,null, interfacesOperationsConverter); ToscaTemplate template = new ToscaTemplate("test"); Map<String, ToscaNodeType> nodeTypes = new HashMap<>(); @@ -350,7 +350,7 @@ class InterfacesOperationsConverterTest { ToscaNodeType nodeType = new ToscaNodeType(); interfacesOperationsConverter.addInterfaceDefinitionElement(component, nodeType, dataTypes, false); - ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null, + ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null, null, null,null, interfacesOperationsConverter); ToscaTemplate template = new ToscaTemplate("test"); Map<String, ToscaNodeType> nodeTypes = new HashMap<>(); @@ -385,7 +385,7 @@ class InterfacesOperationsConverterTest { 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, + final ToscaExportHandler handler = new ToscaExportHandler(null, null, null, null, null, null, null, null,null, interfacesOperationsConverter); final ToscaTemplate template = new ToscaTemplate("testService"); final Map<String, ToscaNodeType> nodeTypes = new HashMap<>(); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/ToscaExportHandlerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/ToscaExportHandlerTest.java index 71a43acdb4..2b00668a74 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/ToscaExportHandlerTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/ToscaExportHandlerTest.java @@ -113,6 +113,7 @@ import org.openecomp.sdc.be.tosca.model.ToscaTemplateArtifact; import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement; import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate; import org.openecomp.sdc.be.tosca.utils.InputConverter; +import org.openecomp.sdc.be.tosca.utils.OutputConverter; public class ToscaExportHandlerTest extends BeConfDependentTest { @@ -140,6 +141,9 @@ public class ToscaExportHandlerTest extends BeConfDependentTest { private InputConverter inputConverter; @Mock + private OutputConverter outputConverter; + + @Mock private GroupExportParser groupExportParser; @Mock @@ -426,8 +430,7 @@ public class ToscaExportHandlerTest extends BeConfDependentTest { when(inputConverter.convertInputs(any(List.class), any(Map.class))).thenReturn(new HashMap<>()); - when(groupExportParser.getGroups(component)) - .thenReturn(null); + when(groupExportParser.getGroups(component)).thenReturn(null); // test component contains group result = Deencapsulation.invoke(testSubject, "convertToscaTemplate", component, toscaNode); diff --git a/catalog-be/src/test/resources/paths/path-context.xml b/catalog-be/src/test/resources/paths/path-context.xml index 73f53f4e8c..3b472dd16f 100644 --- a/catalog-be/src/test/resources/paths/path-context.xml +++ b/catalog-be/src/test/resources/paths/path-context.xml @@ -20,15 +20,16 @@ limitations under the License. Modifications copyright (c) 2018 Nokia ================================================================================ --> -<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:context="http://www.springframework.org/schema/context" - xmlns:aop="http://www.springframework.org/schema/aop" - xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xmlns:aop="http://www.springframework.org/schema/aop" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> - <context:annotation-config /> - <aop:aspectj-autoproxy proxy-target-class="true" /> + <context:annotation-config/> + <aop:aspectj-autoproxy proxy-target-class="true"/> <context:component-scan base-package="org.openecomp.sdc.be.dao.impl, @@ -36,10 +37,11 @@ Modifications copyright (c) 2018 Nokia org.openecomp.sdc.be.model.operations.impl, org.openecomp.sdc.be.model.cache, org.openecomp.sdc.be.dao.janusgraph, - org.openecomp.sdc.be.user, + org.openecomp.sdc.be.user, org.openecomp.sdc.be.impl, org.openecomp.sdc.be.auditing.impl, org.openecomp.sdc.be.components.impl, + org.openecomp.sdc.be.components.attribute, org.openecomp.sdc.be.components.merge, org.openecomp.sdc.be.components.property, org.openecomp.sdc.be.components.distribution.engine, @@ -56,29 +58,31 @@ Modifications copyright (c) 2018 Nokia org.openecomp.sdc.be.datamodel.utils, org.openecomp.sdc.be.model.utils, org.openecomp.sdc.be.dao.jsongraph"> - - </context:component-scan> + + </context:component-scan> <bean id="tosca-operation-facade" class="org.openecomp.sdc.be.components.path.beans.ForwardingPathToscaOperationFacade" /> <bean id="janusgraph-client" class="org.openecomp.sdc.be.components.path.beans.InMemoryJanusGraphClient" /> - <bean id="lifecycleBusinessLogic" class="org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic" /> - <bean id="userBusinessLogicExt" class="org.openecomp.sdc.be.user.UserBusinessLogicExt" /> + <bean id="lifecycleBusinessLogic" class="org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic"/> + <bean id="userBusinessLogicExt" class="org.openecomp.sdc.be.user.UserBusinessLogicExt"/> <bean id="asset-metadata-utils" class="org.openecomp.sdc.be.ecomp.converters.AssetMetadataConverter" /> <bean class="org.openecomp.sdc.be.dao.config.DAOSpringConfig"/> <bean id="cassandra-client" class="org.openecomp.sdc.be.components.path.beans.CassandraClientMock" /> - <bean id="audit-cassandra-dao" class="org.openecomp.sdc.be.components.path.beans.AuditCassandraDaoMock" /> - <bean id="artifact-cassandra-dao" class="org.openecomp.sdc.be.components.path.beans.ArtifactCassandraDaoMock" /> + <bean id="audit-cassandra-dao" class="org.openecomp.sdc.be.components.path.beans.AuditCassandraDaoMock"/> + <bean id="artifact-cassandra-dao" class="org.openecomp.sdc.be.components.path.beans.ArtifactCassandraDaoMock"/> <bean id="operational-environment-dao" class="org.openecomp.sdc.be.components.path.beans.EnvironmentCassandraDaoMock"/> - <bean id="sdc-schema-files-cassandra-dao" class="org.openecomp.sdc.be.components.path.beans.SdcSchemaFilesCassandraDaoMock" /> + <bean id="sdc-schema-files-cassandra-dao" class="org.openecomp.sdc.be.components.path.beans.SdcSchemaFilesCassandraDaoMock"/> <bean id="distributionEngine" class="org.openecomp.sdc.be.components.path.beans.DistributionEngineMock"/> - <bean id="forwardingPathValidator" class="org.openecomp.sdc.be.components.path.beans.ForwardingPathValidatorMock" /> + <bean id="forwardingPathValidator" class="org.openecomp.sdc.be.components.path.beans.ForwardingPathValidatorMock"/> <bean id="dataTypeValidatorConverter" class="org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter" /> <bean id="sdcSchemaUtils" class="org.openecomp.sdc.be.dao.cassandra.schema.SdcSchemaUtils" /> - <bean id="dmaapProducer" class="org.openecomp.sdc.be.catalog.impl.DmaapProducer" /> + <bean id="dmaapProducer" class="org.openecomp.sdc.be.catalog.impl.DmaapProducer"/> <bean id="catalogOperation" class="org.openecomp.sdc.be.facade.operations.CatalogOperation" /> - <bean id="userOperation" class="org.openecomp.sdc.be.facade.operations.UserOperation" /> - <bean id="dmaapProducerHealth" class="org.openecomp.sdc.be.catalog.impl.DmaapProducerHealth" /> - <bean id="feature_toggle_dao" class="org.openecomp.sdc.be.components.path.beans.FeatureToggleDaoMock" /> - <bean name="httpClient" class="org.apache.http.impl.client.HttpClients" factory-method="createDefault" > - </bean> + <bean id="userOperation" class="org.openecomp.sdc.be.facade.operations.UserOperation"/> + <bean id="dmaapProducerHealth" class="org.openecomp.sdc.be.catalog.impl.DmaapProducerHealth"/> + <bean id="feature_toggle_dao" class="org.openecomp.sdc.be.components.path.beans.FeatureToggleDaoMock"/> + <bean name="httpClient" class="org.apache.http.impl.client.HttpClients" factory-method="createDefault" /> + <bean class="org.openecomp.sdc.be.components.attribute.AttributeDeclarationOrchestrator"/> + <bean class="org.openecomp.sdc.be.components.attribute.ComponentInstanceOutputAttributeDeclarator"/> + <bean class="org.openecomp.sdc.be.components.attribute.ComponentInstanceAttributeDeclarator"/> </beans> diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java index 1d0c54b747..aceaf95d3d 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java @@ -102,6 +102,10 @@ public enum ActionStatus { CFVC_LOOP_DETECTED, INPUT_ALREADY_EXIST, + // Outputs + OUTPUT_IS_NOT_CHILD_OF_COMPONENT, + OUTPUT_ALREADY_EXIST, + //Forwarding Path related FORWARDING_PATH_NAME_MAXIMUM_LENGTH, FORWARDING_PATH_NAME_ALREADY_IN_USE, FORWARDING_PATH_NAME_EMPTY, FORWARDING_PATH_PROTOCOL_MAXIMUM_LENGTH, FORWARDING_PATH_DESTINATION_PORT_MAXIMUM_LENGTH, diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/EdgeLabelEnum.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/EdgeLabelEnum.java index dab74441e9..67d44067fc 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/EdgeLabelEnum.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/EdgeLabelEnum.java @@ -42,9 +42,11 @@ public enum EdgeLabelEnum { CREATOR, SUB_CATEGORY, INPUTS, + OUTPUTS, GROUPS, INST_PROPERTIES, INST_INPUTS, + INST_OUTPUTS, INST_ATTRIBUTES, INST_GROUPS, SERVICE_API_ARTIFACTS, diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/VertexTypeEnum.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/VertexTypeEnum.java index 8697f6643a..9868eb83e5 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/VertexTypeEnum.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/VertexTypeEnum.java @@ -69,10 +69,12 @@ public enum VertexTypeEnum { ADDITIONAL_INFORMATION ("additional_information", AdditionalInfoParameterDataDefinition.class), USER ("user", null), INPUTS ("inputs", PropertyDataDefinition.class), + OUTPUTS ("outputs", AttributeDataDefinition.class), GROUPS ("groups", GroupDataDefinition.class), INST_ATTRIBUTES ("instAttributes", MapAttributesDataDefinition.class), INST_PROPERTIES ("instProperties", MapPropertiesDataDefinition.class), INST_INPUTS ("instInputs", MapPropertiesDataDefinition.class), + INST_OUTPUTS ("instOutputs", MapAttributesDataDefinition.class), INST_GROUPS ("instGroups", MapGroupsDataDefinition.class), SERVICE_API_ARTIFACTS ("serviceApiArtifacts", ArtifactDataDefinition.class), CALCULATED_CAPABILITIES ("calculatedCapabilities", MapListCapabilityDataDefinition.class), diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java index f9e0d646b3..ee819310c1 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java @@ -47,11 +47,13 @@ public class AttributeDefinition extends AttributeDataDefinition implements IOpe } public AttributeDefinition(final AttributeDefinition attributeDefinition) { + super(attributeDefinition); this.type = attributeDefinition.getType(); this.description = attributeDefinition.getDescription(); this._default = attributeDefinition.get_default(); this.status = attributeDefinition.getStatus(); this.entry_schema = attributeDefinition.getEntry_schema(); + this.toscaPresentation = attributeDefinition.toscaPresentation; } @Override diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java index 600451d193..c40eef3309 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java @@ -349,6 +349,10 @@ public abstract class Component implements PropertiesOwner { return componentInstancesProperties == null ? emptyMap() : componentInstancesProperties; } + public Map<String, List<ComponentInstanceAttribute>> safeGetComponentInstancesAttributes() { + return componentInstancesAttributes == null ? emptyMap() : componentInstancesAttributes; + } + public Map<String, List<ComponentInstanceProperty>> safeGetUiComponentInstancesProperties() { return componentInstancesProperties == null ? emptyMap() : findUiComponentInstancesProperties(); } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstOutputsMap.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstOutputsMap.java new file mode 100644 index 0000000000..98b39fd1c2 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstOutputsMap.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2021, Nordix Foundation. 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.model; + +import static org.apache.commons.collections.MapUtils.isNotEmpty; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.Setter; +import org.apache.commons.lang3.tuple.Pair; + +@Setter +public class ComponentInstOutputsMap { + + private Map<String, List<ComponentInstanceAttribOutput>> componentInstanceOutputsMap; + private Map<String, List<ComponentInstanceAttribOutput>> componentInstanceAttributes; + + public Pair<String, List<ComponentInstanceAttribOutput>> resolveAttributesToDeclare() { + if (isNotEmpty(componentInstanceOutputsMap)) { + return singleMapEntry(componentInstanceOutputsMap); + } + if (isNotEmpty(componentInstanceAttributes)) { + return singleMapEntry(componentInstanceAttributes); + } + throw new IllegalStateException("there are no properties selected for declaration"); + } + + private Pair<String, List<ComponentInstanceAttribOutput>> singleMapEntry(final Map<String, List<ComponentInstanceAttribOutput>> attributesMap) { + final Map.Entry<String, List<ComponentInstanceAttribOutput>> singleEntry = attributesMap.entrySet().iterator().next(); + return Pair.of(singleEntry.getKey(), singleEntry.getValue()); + } + + public Map<String, List<ComponentInstanceAttribOutput>> getComponentInstanceOutputsMap() { + return componentInstanceOutputsMap == null ? new HashMap<>() : componentInstanceOutputsMap; + } + + public Map<String, List<ComponentInstanceAttribOutput>> getComponentInstanceAttributes() { + return componentInstanceAttributes == null ? new HashMap<>() : componentInstanceAttributes; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribOutput.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribOutput.java new file mode 100644 index 0000000000..9b14e1af54 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribOutput.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2021, Nordix Foundation. 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.model; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ComponentInstanceAttribOutput extends ComponentInstanceAttribute { + + private String attributesName; + private AttributeDefinition output; + + public ComponentInstanceAttribOutput() { + super(); + } + + public ComponentInstanceAttribOutput(ComponentInstanceAttribute p) { + super(p); + } + + public String[] getParsedAttribNames() { + String[] tokens = null; + if (attributesName != null && !attributesName.isEmpty()) { + tokens = attributesName.split("#"); + } + return tokens; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceOutput.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceOutput.java index db79511a67..be3f87eb9b 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceOutput.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceOutput.java @@ -22,12 +22,16 @@ package org.openecomp.sdc.be.model; import java.util.List; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; +import lombok.ToString; import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyRule; @Getter @Setter +@NoArgsConstructor +@ToString(callSuper = true) public class ComponentInstanceOutput extends OutputDefinition implements IComponentInstanceConnectedElement, IAttributeOutputCommon { /** @@ -35,21 +39,25 @@ public class ComponentInstanceOutput extends OutputDefinition implements ICompon */ private String valueUniqueUid; - private List<String> path = null; + private List<String> path; - private List<PropertyRule> rules = null; + private List<PropertyRule> rules; private String componentInstanceName; private String componentInstanceId; - public ComponentInstanceOutput(AttributeDataDefinition curPropertyDef, String outputId, String value, - String valueUniqueUid) { + public ComponentInstanceOutput(final AttributeDataDefinition curPropertyDef, + final String outputId, + final String value, + final String valueUniqueUid) { super(curPropertyDef); setOutputId(outputId); setValue(value); this.valueUniqueUid = valueUniqueUid; } - public ComponentInstanceOutput(OutputDefinition pd, String value, String valueUniqueUid) { + public ComponentInstanceOutput(final OutputDefinition pd, + final String value, + final String valueUniqueUid) { super(pd); setValue(value); @@ -60,14 +68,8 @@ public class ComponentInstanceOutput extends OutputDefinition implements ICompon super(attributeDataDefinition); if (attributeDataDefinition.getGetOutputValues() != null && !attributeDataDefinition.getGetOutputValues() .isEmpty()) { - setOutputId(attributeDataDefinition.getGetOutputValues().get(0).getInputId()); + setOutputId(attributeDataDefinition.getGetOutputValues().get(0).getOutputId()); } } - @Override - public String toString() { - return "ComponentInstanceOutput [ " + super.toString() + " , value=" + getValue() + ", valueUniqueUid = " - + valueUniqueUid + " , rules=" + rules + " , path=" + path + " ]"; - } - } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java index 87917d7861..4c8cb3d866 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java @@ -151,6 +151,10 @@ public class ComponentParametersView { this.setIgnoreComponentInstances(false); this.setIgnoreComponentInstancesInputs(false); break; + case COMPONENT_INSTANCE_OUTPUTS: + this.setIgnoreComponentInstances(false); + this.setIgnoreComponentInstancesOutputs(false); + break; case INSTANCE_CAPABILTY_PROPERTIES: this.setIgnoreCapabiltyProperties(false); break; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/InputDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/InputDefinition.java index 2f61e9e6f3..bbb71463fc 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/InputDefinition.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/InputDefinition.java @@ -20,6 +20,8 @@ package org.openecomp.sdc.be.model; +import lombok.Getter; +import lombok.Setter; import org.openecomp.sdc.be.datatypes.elements.Annotation; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; @@ -27,12 +29,13 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +@Getter +@Setter public class InputDefinition extends PropertyDefinition { private List<ComponentInstanceInput> inputs; private List<ComponentInstanceProperty> properties; - public InputDefinition(PropertyDataDefinition p) { super(p); } @@ -49,26 +52,8 @@ public class InputDefinition extends PropertyDefinition { super(other); } - public List<ComponentInstanceInput> getInputs() { - return inputs; - } - - public void setInputs(List<ComponentInstanceInput> inputs) { - this.inputs = inputs; - } - - public List<ComponentInstanceProperty> getProperties() { - return properties; - } - - public void setProperties(List<ComponentInstanceProperty> properties) { - this.properties = properties; - } - public void setAnnotationsToInput(Collection<Annotation> annotations){ this.setAnnotations(new ArrayList<>(annotations)); } - - } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/OutputDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/OutputDefinition.java index cbff8fa3af..354a5b2ae3 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/OutputDefinition.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/OutputDefinition.java @@ -19,12 +19,20 @@ package org.openecomp.sdc.be.model; +import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; +@Getter +@Setter +@NoArgsConstructor public class OutputDefinition extends AttributeDefinition { + private List<ComponentInstanceAttribute> attributes; - public OutputDefinition(final AttributeDataDefinition propertyDataDefinition) { - super(propertyDataDefinition); + public OutputDefinition(final AttributeDataDefinition attributeDataDefinition) { + super(attributeDataDefinition); } public OutputDefinition(AttributeDefinition propertyDefinition) { diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/datamodel/TopologyTemplate.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/datamodel/TopologyTemplate.java index 1bf35fbd9f..483e79c53b 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/datamodel/TopologyTemplate.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/datamodel/TopologyTemplate.java @@ -26,10 +26,10 @@ import lombok.Getter; import lombok.Setter; import org.apache.commons.collections.MapUtils; import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition; import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition; import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition; import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition; @@ -59,7 +59,9 @@ public class TopologyTemplate extends ToscaElement { } private Map<String, PropertyDataDefinition> inputs; + private Map<String, AttributeDataDefinition> outputs; private Map<String, MapPropertiesDataDefinition> instInputs; + private Map<String, MapAttributesDataDefinition> instOutputs; private Map<String, ? extends ToscaDataDefinition> heatParameters; private Map<String, MapAttributesDataDefinition> instAttributes; private Map<String, MapPropertiesDataDefinition> instProperties; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTemplateOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTemplateOperation.java index 3f3e54146d..babe44234e 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTemplateOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTemplateOperation.java @@ -23,6 +23,7 @@ package org.openecomp.sdc.be.model.jsonjanusgraph.operations; import fj.data.Either; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; @@ -33,7 +34,6 @@ import java.util.Map.Entry; import java.util.Optional; import java.util.Set; import java.util.UUID; -import java.util.function.BiConsumer; import java.util.function.BiPredicate; import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; @@ -82,7 +82,25 @@ import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; -import org.openecomp.sdc.be.model.*; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.CapabilityRequirementRelationship; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceOutput; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.GroupInstance; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RelationshipImpl; +import org.openecomp.sdc.be.model.RelationshipInfo; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.NodeType; import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.TopologyTemplate; import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement; @@ -233,37 +251,40 @@ public class NodeTemplateOperation extends BaseOperation { addToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap, componentInstance.getUniqueId()); /******** capability property ****************************/ - status = deleteToscaDataDeepElementsBlockOfToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, componentInstanceData.getUniqueId()); + status = deleteToscaDataDeepElementsBlockOfToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, + VertexTypeEnum.CALCULATED_CAP_PROPERTIES, componentInstanceData.getUniqueId()); if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) { - CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to remove calculated capabilty properties for instance {} in container {}. error {] ", componentInstanceData.getUniqueId(), updatedContainer.getUniqueId(), status); + CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, + "Failed to remove calculated capabilty properties for instance {} in container {}. error {] ", + componentInstanceData.getUniqueId(), updatedContainer.getUniqueId(), status); return Either.right(status); } - MapCapabilityProperty allCalculatedCapProp = calcCapProp == null || !calcCapProp.containsKey(componentInstanceData.getUniqueId()) ? new MapCapabilityProperty() : calcCapProp.get(componentInstanceData.getUniqueId()); - - additionalCap.forEach(new BiConsumer<String, List<CapabilityDefinition>>() { - @Override - public void accept(String s, List<CapabilityDefinition> caps) { - if (caps != null && !caps.isEmpty()) { - MapPropertiesDataDefinition dataToCreate; - for (CapabilityDefinition cap : caps) { - dataToCreate = new MapPropertiesDataDefinition(); - List<ComponentInstanceProperty> capPrps = cap.getProperties(); - if (capPrps != null) { - for (ComponentInstanceProperty cip : capPrps) { - dataToCreate.put(cip.getName(), new PropertyDataDefinition(cip)); - } - StringBuilder sb = new StringBuilder(componentInstance.getUniqueId()); - sb.append(ModelConverter.CAP_PROP_DELIM); - sb.append(cap.getOwnerId()); - sb.append(ModelConverter.CAP_PROP_DELIM).append(s).append(ModelConverter.CAP_PROP_DELIM).append(cap.getName()); - allCalculatedCapProp.put(sb.toString(), dataToCreate); + MapCapabilityProperty allCalculatedCapProp = + calcCapProp == null || !calcCapProp.containsKey(componentInstanceData.getUniqueId()) ? new MapCapabilityProperty() + : calcCapProp.get(componentInstanceData.getUniqueId()); + + additionalCap.forEach((s, caps) -> { + if (caps != null && !caps.isEmpty()) { + MapPropertiesDataDefinition dataToCreate; + for (CapabilityDefinition cap : caps) { + dataToCreate = new MapPropertiesDataDefinition(); + List<ComponentInstanceProperty> capPrps = cap.getProperties(); + if (capPrps != null) { + for (ComponentInstanceProperty cip : capPrps) { + dataToCreate.put(cip.getName(), new PropertyDataDefinition(cip)); } + StringBuilder sb = new StringBuilder(componentInstance.getUniqueId()); + sb.append(ModelConverter.CAP_PROP_DELIM); + sb.append(cap.getOwnerId()); + sb.append(ModelConverter.CAP_PROP_DELIM).append(s).append(ModelConverter.CAP_PROP_DELIM).append(cap.getName()); + allCalculatedCapProp.put(sb.toString(), dataToCreate); } } } }); - addToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, allCalculatedCapProp, componentInstance.getUniqueId()); + addToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(), EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, + VertexTypeEnum.CALCULATED_CAP_PROPERTIES, allCalculatedCapProp, componentInstance.getUniqueId()); } /******** Requirements property ****************************/ @@ -1294,8 +1315,7 @@ public class NodeTemplateOperation extends BaseOperation { private Boolean isUniqueInstanceName(TopologyTemplate container, String instanceName) { Boolean isUniqueName = true; try { - isUniqueName = !container.getComponentInstances().values().stream().anyMatch(ci -> ci.getName() != null && ci.getName().equals(instanceName)); - + isUniqueName = container.getComponentInstances().values().stream().noneMatch(ci -> ci.getName() != null && ci.getName().equals(instanceName)); } catch (Exception e) { CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during fetching component instance with name {} from component container {}. {} ", instanceName, container.getName(), e.getMessage()); } @@ -2134,10 +2154,8 @@ public class NodeTemplateOperation extends BaseOperation { if (!validateInstanceNames(componentInstanceTMap)) { throw new StorageException(StorageOperationStatus.INCONSISTENCY); } - if (!allowDeleted) { - if (!validateDeletedResources(componentInstanceTMap)) { - throw new StorageException(StorageOperationStatus.INCONSISTENCY); - } + if (!allowDeleted && !validateDeletedResources(componentInstanceTMap)) { + throw new StorageException(StorageOperationStatus.INCONSISTENCY); } instancesJsonData = convertToComponentInstanceDataDefinition(componentInstanceTMap, containerId, isUpdateCsar); @@ -2313,32 +2331,53 @@ public class NodeTemplateOperation extends BaseOperation { public StorageOperationStatus addComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) { List<String> pathKeys = new ArrayList<>(); pathKeys.add(componentInstanceId); - return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, property, pathKeys, JsonPresentationFields.NAME); + return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, + property, pathKeys, JsonPresentationFields.NAME); } - public StorageOperationStatus updateComponentInstanceProperties(Component containerComponent, String componentInstanceId, List<ComponentInstanceProperty> properties) { + public StorageOperationStatus updateComponentInstanceProperties(Component containerComponent, String componentInstanceId, + List<ComponentInstanceProperty> properties) { List<String> pathKeys = new ArrayList<>(); pathKeys.add(componentInstanceId); - return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, properties, pathKeys, JsonPresentationFields.NAME); + return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_PROPERTIES, + VertexTypeEnum.INST_PROPERTIES, properties, pathKeys, JsonPresentationFields.NAME); } - public StorageOperationStatus updateComponentInstanceAttribute(Component containerComponent, String componentInstanceId, ComponentInstanceAttribute property){ + public StorageOperationStatus updateComponentInstanceAttributes(final Component containerComponent, + final String componentInstanceId, + final List<ComponentInstanceAttribute> attributes) { + final List<String> pathKeys = Arrays.asList(componentInstanceId); + return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_ATTRIBUTES, + VertexTypeEnum.INST_ATTRIBUTES, attributes, pathKeys, JsonPresentationFields.NAME); + } + + public StorageOperationStatus updateComponentInstanceAttribute(final Component containerComponent, + final String componentInstanceId, + final ComponentInstanceAttribute attribute) { + final List<String> pathKeys = Arrays.asList(componentInstanceId); + return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_ATTRIBUTES, + VertexTypeEnum.INST_ATTRIBUTES, attribute, pathKeys, JsonPresentationFields.NAME); + } + + public StorageOperationStatus addComponentInstanceAttribute(Component containerComponent, String componentInstanceId, + ComponentInstanceAttribute attribute) { List<String> pathKeys = new ArrayList<>(); pathKeys.add(componentInstanceId); - return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES, property, pathKeys, JsonPresentationFields.NAME); + return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES, + attribute, pathKeys, JsonPresentationFields.NAME); } - public StorageOperationStatus addComponentInstanceAttribute(Component containerComponent, String componentInstanceId, ComponentInstanceAttribute attribute){ + public StorageOperationStatus updateComponentInstanceInput(Component containerComponent, String componentInstanceId, + ComponentInstanceInput property) { List<String> pathKeys = new ArrayList<>(); pathKeys.add(componentInstanceId); - return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_ATTRIBUTES, VertexTypeEnum.INST_ATTRIBUTES, attribute, pathKeys, JsonPresentationFields.NAME); + return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, property, pathKeys, JsonPresentationFields.NAME); } - public StorageOperationStatus updateComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) { - + public StorageOperationStatus updateComponentInstanceOutput(Component containerComponent, String componentInstanceId, ComponentInstanceOutput property) { List<String> pathKeys = new ArrayList<>(); pathKeys.add(componentInstanceId); - return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, property, pathKeys, JsonPresentationFields.NAME); + return updateToscaDataDeepElementOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_OUTPUTS, VertexTypeEnum.INST_OUTPUTS, property, pathKeys, JsonPresentationFields.NAME); } public StorageOperationStatus updateComponentInstanceInputs(Component containerComponent, String componentInstanceId, List<ComponentInstanceInput> properties) { @@ -2347,12 +2386,24 @@ public class NodeTemplateOperation extends BaseOperation { return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, properties, pathKeys, JsonPresentationFields.NAME); } + public StorageOperationStatus updateComponentInstanceOutputs(Component containerComponent, String componentInstanceId, List<ComponentInstanceOutput> properties) { + List<String> pathKeys = new ArrayList<>(); + pathKeys.add(componentInstanceId); + return updateToscaDataDeepElementsOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_OUTPUTS, VertexTypeEnum.INST_OUTPUTS, properties, pathKeys, JsonPresentationFields.NAME); + } + public StorageOperationStatus addComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) { List<String> pathKeys = new ArrayList<>(); pathKeys.add(componentInstanceId); return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_INPUTS, VertexTypeEnum.INST_INPUTS, property, pathKeys, JsonPresentationFields.NAME); } + public StorageOperationStatus addComponentInstanceOutput(Component containerComponent, String componentInstanceId, ComponentInstanceOutput property) { + List<String> pathKeys = new ArrayList<>(){}; + pathKeys.add(componentInstanceId); + return addToscaDataDeepElementToToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_OUTPUTS, VertexTypeEnum.INST_OUTPUTS, property, pathKeys, JsonPresentationFields.NAME); + } + public StorageOperationStatus createInstanceEdge(GraphVertex metadataVertex, ComponentInstanceDataDefinition componentInstance) { String instUniqueId = componentInstance.getUniqueId(); diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTypeOperation.java index 1860e696e5..e8aba6dcb6 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTypeOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeTypeOperation.java @@ -932,6 +932,7 @@ public class NodeTypeOperation extends ToscaElementOperation { case ARTIFACTS: case GROUPS: case INPUTS: + case OUTPUTS: return true; default: return false; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/TopologyTemplateOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/TopologyTemplateOperation.java index ed9196098e..a27989bc9e 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/TopologyTemplateOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/TopologyTemplateOperation.java @@ -35,6 +35,7 @@ import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; import org.openecomp.sdc.be.datatypes.category.MetadataKeyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; import org.openecomp.sdc.be.datatypes.elements.MapAttributesDataDefinition; import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty; import org.openecomp.sdc.be.datatypes.elements.MapListCapabilityDataDefinition; @@ -721,6 +722,14 @@ public class TopologyTemplateOperation extends ToscaElementOperation { } } + + if (!componentParametersView.isIgnoreOutputs()) { + final JanusGraphOperationStatus storageStatus = setOutputsFromGraph(componentV, toscaElement); + if (storageStatus != JanusGraphOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(storageStatus)); + } + } + if (!componentParametersView.isIgnoreProperties()) { status = setPropertiesFromGraph(componentV, toscaElement); if (status != JanusGraphOperationStatus.OK) { @@ -1130,6 +1139,20 @@ public class TopologyTemplateOperation extends ToscaElementOperation { return JanusGraphOperationStatus.OK; } + private JanusGraphOperationStatus setOutputsFromGraph(final GraphVertex componentV, + final TopologyTemplate toscaElement) { + final Either<Map<String, AttributeDataDefinition>, JanusGraphOperationStatus> result = + getDataFromGraph(componentV, EdgeLabelEnum.OUTPUTS); + if (result.isLeft()) { + toscaElement.setOutputs(result.left().value()); + } else { + if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) { + return result.right().value(); + } + } + return JanusGraphOperationStatus.OK; + } + private JanusGraphOperationStatus setGroupsFromGraph(GraphVertex componentV, TopologyTemplate toscaElement) { Either<Map<String, GroupDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.GROUPS); if (result.isLeft()) { diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java index cdddb2049f..b4517e47c5 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java @@ -91,6 +91,7 @@ import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.ComponentInstanceAttribute; import org.openecomp.sdc.be.model.ComponentInstanceInput; import org.openecomp.sdc.be.model.ComponentInstanceInterface; +import org.openecomp.sdc.be.model.ComponentInstanceOutput; import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.ComponentParametersView; import org.openecomp.sdc.be.model.DataTypeDefinition; @@ -99,6 +100,7 @@ import org.openecomp.sdc.be.model.GroupDefinition; import org.openecomp.sdc.be.model.GroupInstance; import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.OutputDefinition; import org.openecomp.sdc.be.model.PolicyDefinition; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.RelationshipInfo; @@ -1245,6 +1247,36 @@ public class ToscaOperationFacade { } + public Either<List<OutputDefinition>, StorageOperationStatus> addOutputsToComponent(Map<String, OutputDefinition> outputs, + String componentId) { + + Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao + .getVertexById(componentId, JsonParseFlagEnum.NoParse); + if (getVertexEither.isRight()) { + log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value()); + return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value())); + + } + + GraphVertex vertex = getVertexEither.left().value(); + Map<String, AttributeDefinition> outputsMap = outputs.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, e -> new AttributeDefinition(e.getValue()))); + + StorageOperationStatus status = topologyTemplateOperation + .addToscaDataToToscaElement(vertex, EdgeLabelEnum.OUTPUTS, VertexTypeEnum.OUTPUTS, outputsMap, JsonPresentationFields.NAME); + + if (StorageOperationStatus.OK == status) { + log.debug(COMPONENT_CREATED_SUCCESSFULLY); + List<OutputDefinition> outputsResList = null; + if (outputsMap != null && !outputsMap.isEmpty()) { + outputsResList = outputsMap.values().stream().map(OutputDefinition::new).collect(Collectors.toList()); + } + return Either.left(outputsResList); + } + return Either.right(status); + + } + /** * Add data types into a Component. * @@ -1252,7 +1284,8 @@ public class ToscaOperationFacade { * @param componentId unique ID of Component. * @return list of data types. */ - public Either<List<DataTypeDefinition>, StorageOperationStatus> addDataTypesToComponent(Map<String, DataTypeDefinition> dataTypes, String componentId) { + public Either<List<DataTypeDefinition>, StorageOperationStatus> addDataTypesToComponent(Map<String, DataTypeDefinition> dataTypes, + String componentId) { log.trace("#addDataTypesToComponent - enter, componentId={}", componentId); @@ -1511,7 +1544,38 @@ public class ToscaOperationFacade { return Either.left(instProperties); } - public Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> addComponentInstancePropertiesToComponent(Component containerComponent, Map<String, List<ComponentInstanceProperty>> instProperties) { + public Either<Map<String, List<ComponentInstanceOutput>>, StorageOperationStatus> addComponentInstanceOutputsToComponent( + Component containerComponent, Map<String, List<ComponentInstanceOutput>> instProperties) { + requireNonNull(instProperties); + StorageOperationStatus status; + for (final Entry<String, List<ComponentInstanceOutput>> entry : instProperties.entrySet()) { + final List<ComponentInstanceOutput> props = entry.getValue(); + final String componentInstanceId = entry.getKey(); + if (!isEmpty(props)) { + for (final ComponentInstanceOutput property : props) { + final List<ComponentInstanceOutput> componentInstancesInputs + = containerComponent.getComponentInstancesOutputs().get(componentInstanceId); + final Optional<ComponentInstanceOutput> instanceProperty = componentInstancesInputs.stream() + .filter(p -> p.getName().equals(property.getName())).findAny(); + if (instanceProperty.isPresent()) { + status = updateComponentInstanceOutput(containerComponent, componentInstanceId, property); + } else { + status = addComponentInstanceOutput(containerComponent, componentInstanceId, property); + } + if (status != StorageOperationStatus.OK) { + log.debug("Failed to update instance input {} for instance {} error {} ", property, componentInstanceId, status); + return Either.right(status); + } else { + log.trace("instance input {} for instance {} updated", property, componentInstanceId); + } + } + } + } + return Either.left(instProperties); + } + + public Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> addComponentInstancePropertiesToComponent( + Component containerComponent, Map<String, List<ComponentInstanceProperty>> instProperties) { requireNonNull(instProperties); for (Entry<String, List<ComponentInstanceProperty>> entry : instProperties.entrySet()) { List<ComponentInstanceProperty> props = entry.getValue(); @@ -1520,7 +1584,7 @@ public class ToscaOperationFacade { containerComponent.getComponentInstancesProperties().get(componentInstanceId); Map<String, List<CapabilityDefinition>> containerComponentCapabilities = containerComponent.getCapabilities(); - if(isEmpty(props)) { + if (isEmpty(props)) { continue; } for (ComponentInstanceProperty property : props) { @@ -1528,15 +1592,38 @@ public class ToscaOperationFacade { String propertyParentUniqueId = property.getParentUniqueId(); Optional<CapabilityDefinition> capPropDefinition = getPropertyCapability(propertyParentUniqueId, containerComponent); - if(capPropDefinition.isPresent() && MapUtils.isNotEmpty(containerComponentCapabilities)) { + if (capPropDefinition.isPresent() && MapUtils.isNotEmpty(containerComponentCapabilities)) { status = populateAndUpdateInstanceCapProperty(containerComponent, componentInstanceId, - containerComponentCapabilities, property, capPropDefinition.get()); + containerComponentCapabilities, property, capPropDefinition.get()); } - if(status == null) { + if (status == null) { status = updateOrAddComponentInstanceProperty(containerComponent, componentInstanceId, originalComponentInstProps, property); } - if(status != StorageOperationStatus.OK) { + if (status != StorageOperationStatus.OK) { + return Either.right(status); + } + } + } + return Either.left(instProperties); + } + + public Either<Map<String, List<ComponentInstanceAttribute>>, StorageOperationStatus> addComponentInstanceAttributesToComponent( + final Component containerComponent, final Map<String, List<ComponentInstanceAttribute>> instProperties) { + requireNonNull(instProperties); + for (final Entry<String, List<ComponentInstanceAttribute>> entry : instProperties.entrySet()) { + final List<ComponentInstanceAttribute> props = entry.getValue(); + if (isEmpty(props)) { + continue; + } + final String componentInstanceId = entry.getKey(); + final List<ComponentInstanceAttribute> originalComponentInstProps = + containerComponent.getComponentInstancesAttributes().get(componentInstanceId); + + for (final ComponentInstanceAttribute property : props) { + final StorageOperationStatus status = updateOrAddComponentInstanceAttribute( + containerComponent, componentInstanceId, originalComponentInstProps, property); + if (status != StorageOperationStatus.OK) { return Either.right(status); } } @@ -1549,7 +1636,7 @@ public class ToscaOperationFacade { ComponentInstanceProperty property, CapabilityDefinition capabilityDefinition) { List<CapabilityDefinition> capabilityDefinitions = containerComponentCapabilities.get(capabilityDefinition.getType()); - if(CollectionUtils.isEmpty(capabilityDefinitions)) { + if (CollectionUtils.isEmpty(capabilityDefinitions)) { return null; } Optional<CapabilityDefinition> capDefToGetProp = capabilityDefinitions.stream() @@ -1578,13 +1665,13 @@ public class ToscaOperationFacade { } private StorageOperationStatus updateOrAddComponentInstanceProperty(Component containerComponent, - String componentInstanceId, List<ComponentInstanceProperty> originalComponentInstProps, - ComponentInstanceProperty property) - { + String componentInstanceId, + List<ComponentInstanceProperty> originalComponentInstProps, + ComponentInstanceProperty property) { StorageOperationStatus status; // check if the property already exists or not Optional<ComponentInstanceProperty> instanceProperty = originalComponentInstProps.stream() - .filter(p -> p.getUniqueId().equals(property.getUniqueId())).findAny(); + .filter(p -> p.getUniqueId().equals(property.getUniqueId())).findAny(); if (instanceProperty.isPresent()) { status = updateComponentInstanceProperty(containerComponent, componentInstanceId, property); } else { @@ -1597,15 +1684,35 @@ public class ToscaOperationFacade { return status; } - public StorageOperationStatus updateInstanceCapabilityProperty(Component containerComponent, String componentInstanceId, + private StorageOperationStatus updateOrAddComponentInstanceAttribute(Component containerComponent, + String componentInstanceId, + List<ComponentInstanceAttribute> originalComponentInstProps, + ComponentInstanceAttribute property) { + StorageOperationStatus status; + // check if the property already exists or not + Optional<ComponentInstanceAttribute> instanceProperty = originalComponentInstProps.stream() + .filter(p -> p.getUniqueId().equals(property.getUniqueId())).findAny(); + if (instanceProperty.isPresent()) { + status = updateComponentInstanceAttribute(containerComponent, componentInstanceId, property); + } else { + status = addComponentInstanceAttribute(containerComponent, componentInstanceId, property); + } + if (status != StorageOperationStatus.OK) { + log.debug("Failed to update instance property {} for instance {} error {} ", + property, componentInstanceId, status); + } + return status; + } + + public StorageOperationStatus updateInstanceCapabilityProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property, CapabilityDefinition capabilityDefinition) { Optional<ComponentInstance> fetchedCIOptional = containerComponent.getComponentInstanceById(componentInstanceId); - if(!fetchedCIOptional.isPresent()) { + if (!fetchedCIOptional.isPresent()) { return StorageOperationStatus.GENERAL_ERROR; } Either<Component, StorageOperationStatus> getComponentRes = - getToscaFullElement(fetchedCIOptional.get().getComponentUid()); + getToscaFullElement(fetchedCIOptional.get().getComponentUid()); if(getComponentRes.isRight()) { return StorageOperationStatus.GENERAL_ERROR; } @@ -2034,12 +2141,7 @@ public class ToscaOperationFacade { log.debug("failed to get vertex from graph with property normalizedName: {}", normalizedName); return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexEither.right().value())); } - List<GraphVertex> vertexList = vertexEither.isLeft() ? vertexEither.left().value() : null; - if (vertexList != null && !vertexList.isEmpty()) { - return Either.left(false); - } else { - return Either.left(true); - } + return Either.left(CollectionUtils.isEmpty(vertexEither.isLeft() ? vertexEither.left().value() : null)); } private void fillNodeTypePropsMap(final Map<GraphPropertyEnum, Object> hasProps, @@ -2650,6 +2752,10 @@ public class ToscaOperationFacade { return getToscaElementOperation(resource).deleteToscaDataElement(resource.getUniqueId(), EdgeLabelEnum.INPUTS, VertexTypeEnum.INPUTS, inputName, JsonPresentationFields.NAME); } + public StorageOperationStatus deleteOutputOfResource(final Component resource, final String outputName) { + return getToscaElementOperation(resource).deleteToscaDataElement(resource.getUniqueId(), EdgeLabelEnum.OUTPUTS, VertexTypeEnum.OUTPUTS, outputName, JsonPresentationFields.NAME); + } + /** * Deletes a data type from a component. * @param component the container which has the data type @@ -2682,21 +2788,60 @@ public class ToscaOperationFacade { } } if (result == null) { - Optional<PropertyDefinition> newProperty = (getUpdatedComponentRes.left().value()) - .getProperties().stream().filter(p -> p.getName().equals(newPropertyDefinition.getName())).findAny(); - if (newProperty.isPresent()) { - result = Either.left(newProperty.get()); - } else { + Optional<PropertyDefinition> newProperty = (getUpdatedComponentRes.left().value()) + .getProperties().stream().filter(p -> p.getName().equals(newPropertyDefinition.getName())).findAny(); + if (newProperty.isPresent()) { + result = Either.left(newProperty.get()); + } else { CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS, newPropertyDefinition.getName(), component.getUniqueId(), StorageOperationStatus.NOT_FOUND); result = Either.right(StorageOperationStatus.NOT_FOUND); } - } - return result; - } + } + return result; + } - public Either<AttributeDefinition, StorageOperationStatus> addAttributeOfResource(Component component, AttributeDefinition newAttributeDef) { + public Either<AttributeDefinition, StorageOperationStatus> updateAttributeOfComponent(Component component, + AttributeDefinition newPropertyDefinition) { + + Either<Component, StorageOperationStatus> getUpdatedComponentRes = null; + Either<AttributeDefinition, StorageOperationStatus> result = null; + StorageOperationStatus status = getToscaElementOperation(component) + .updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, + newPropertyDefinition, JsonPresentationFields.NAME); + if (status != StorageOperationStatus.OK) { + CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS, + newPropertyDefinition.getName(), component.getName(), status); + result = Either.right(status); + } + if (result == null) { + ComponentParametersView filter = new ComponentParametersView(true); + filter.setIgnoreProperties(false); + getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter); + if (getUpdatedComponentRes.isRight()) { + CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS, + component.getUniqueId(), getUpdatedComponentRes.right().value()); + result = Either.right(status); + } + } + if (result == null) { + Optional<AttributeDefinition> newProperty = (getUpdatedComponentRes.left().value()) + .getAttributes().stream().filter(p -> p.getName().equals(newPropertyDefinition.getName())).findAny(); + if (newProperty.isPresent()) { + result = Either.left(newProperty.get()); + } else { + CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, + FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS, newPropertyDefinition.getName(), + component.getUniqueId(), StorageOperationStatus.NOT_FOUND); + result = Either.right(StorageOperationStatus.NOT_FOUND); + } + } + return result; + } + + public Either<AttributeDefinition, StorageOperationStatus> addAttributeOfResource(Component component, + AttributeDefinition newAttributeDef) { Either<Component, StorageOperationStatus> getUpdatedComponentRes = null; Either<AttributeDefinition, StorageOperationStatus> result = null; @@ -2706,7 +2851,9 @@ public class ToscaOperationFacade { newAttributeDef.setOwnerId(component.getUniqueId()); } - StorageOperationStatus status = getToscaElementOperation(component).addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, newAttributeDef, JsonPresentationFields.NAME); + StorageOperationStatus status = getToscaElementOperation(component) + .addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.ATTRIBUTES, VertexTypeEnum.ATTRIBUTES, newAttributeDef, + JsonPresentationFields.NAME); if (status != StorageOperationStatus.OK) { CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS, newAttributeDef.getName(), component.getName(), status); result = Either.right(status); @@ -2847,31 +2994,58 @@ public class ToscaOperationFacade { return nodeTemplateOperation.updateComponentInstanceProperties(containerComponent, componentInstanceId, properties); } + public StorageOperationStatus updateComponentInstanceAttributes(final Component containerComponent, + final String componentInstanceId, + final List<ComponentInstanceAttribute> attributes) { + return nodeTemplateOperation.updateComponentInstanceAttributes(containerComponent, componentInstanceId, attributes); + } - public StorageOperationStatus addComponentInstanceProperty(Component containerComponent, String componentInstanceId, ComponentInstanceProperty property) { + public StorageOperationStatus addComponentInstanceProperty(Component containerComponent, String componentInstanceId, + ComponentInstanceProperty property) { return nodeTemplateOperation.addComponentInstanceProperty(containerComponent, componentInstanceId, property); } - public StorageOperationStatus updateComponentInstanceAttribute(Component containerComponent, String componentInstanceId, ComponentInstanceAttribute property){ - return nodeTemplateOperation.updateComponentInstanceAttribute(containerComponent, componentInstanceId, property); + public StorageOperationStatus updateComponentInstanceAttribute(final Component containerComponent, + final String componentInstanceId, + final ComponentInstanceAttribute attribute) { + return nodeTemplateOperation.updateComponentInstanceAttribute(containerComponent, componentInstanceId, attribute); } - public StorageOperationStatus addComponentInstanceAttribute(Component containerComponent, String componentInstanceId, ComponentInstanceAttribute attribute){ + public StorageOperationStatus addComponentInstanceAttribute(Component containerComponent, String componentInstanceId, + ComponentInstanceAttribute attribute) { return nodeTemplateOperation.addComponentInstanceAttribute(containerComponent, componentInstanceId, attribute); } - public StorageOperationStatus updateComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) { + public StorageOperationStatus updateComponentInstanceInput(Component containerComponent, String componentInstanceId, + ComponentInstanceInput property) { return nodeTemplateOperation.updateComponentInstanceInput(containerComponent, componentInstanceId, property); } - public StorageOperationStatus updateComponentInstanceInputs(Component containerComponent, String componentInstanceId, List<ComponentInstanceInput> instanceInputs) { + public StorageOperationStatus updateComponentInstanceOutput(Component containerComponent, String componentInstanceId, + ComponentInstanceOutput property) { + return nodeTemplateOperation.updateComponentInstanceOutput(containerComponent, componentInstanceId, property); + } + + public StorageOperationStatus updateComponentInstanceInputs(Component containerComponent, String componentInstanceId, + List<ComponentInstanceInput> instanceInputs) { return nodeTemplateOperation.updateComponentInstanceInputs(containerComponent, componentInstanceId, instanceInputs); } - public StorageOperationStatus addComponentInstanceInput(Component containerComponent, String componentInstanceId, ComponentInstanceInput property) { + public StorageOperationStatus updateComponentInstanceOutputs(Component containerComponent, String componentInstanceId, + List<ComponentInstanceOutput> instanceInputs) { + return nodeTemplateOperation.updateComponentInstanceOutputs(containerComponent, componentInstanceId, instanceInputs); + } + + public StorageOperationStatus addComponentInstanceInput(Component containerComponent, String componentInstanceId, + ComponentInstanceInput property) { return nodeTemplateOperation.addComponentInstanceInput(containerComponent, componentInstanceId, property); } + public StorageOperationStatus addComponentInstanceOutput(Component containerComponent, String componentInstanceId, + ComponentInstanceOutput property) { + return nodeTemplateOperation.addComponentInstanceOutput(containerComponent, componentInstanceId, property); + } + public void setNodeTypeOperation(NodeTypeOperation nodeTypeOperation) { this.nodeTypeOperation = nodeTypeOperation; } @@ -2880,17 +3054,24 @@ public class ToscaOperationFacade { this.topologyTemplateOperation = topologyTemplateOperation; } - public StorageOperationStatus deleteComponentInstanceInputsFromTopologyTemplate(Component containerComponent, List<InputDefinition> inputsToDelete) { - return topologyTemplateOperation.deleteToscaDataElements(containerComponent.getUniqueId(), EdgeLabelEnum.INPUTS, inputsToDelete.stream().map(PropertyDataDefinition::getName).collect(Collectors.toList())); + public StorageOperationStatus deleteComponentInstanceInputsFromTopologyTemplate(Component containerComponent, + List<InputDefinition> inputsToDelete) { + return topologyTemplateOperation.deleteToscaDataElements(containerComponent.getUniqueId(), EdgeLabelEnum.INPUTS, + inputsToDelete.stream().map(PropertyDataDefinition::getName).collect(Collectors.toList())); } - public StorageOperationStatus updateComponentInstanceCapabiltyProperty(Component containerComponent, String componentInstanceUniqueId, String capabilityPropertyKey, ComponentInstanceProperty property) { - return nodeTemplateOperation.updateComponentInstanceCapabilityProperty(containerComponent, componentInstanceUniqueId, capabilityPropertyKey, property); + public StorageOperationStatus updateComponentInstanceCapabiltyProperty(Component containerComponent, String componentInstanceUniqueId, + String capabilityPropertyKey, + ComponentInstanceProperty property) { + return nodeTemplateOperation + .updateComponentInstanceCapabilityProperty(containerComponent, componentInstanceUniqueId, capabilityPropertyKey, property); } - public StorageOperationStatus updateComponentInstanceCapabilityProperties(Component containerComponent, String componentInstanceUniqueId) { + public StorageOperationStatus updateComponentInstanceCapabilityProperties(Component containerComponent, + String componentInstanceUniqueId) { return convertComponentInstanceProperties(containerComponent, componentInstanceUniqueId) - .map(instanceCapProps -> topologyTemplateOperation.updateComponentInstanceCapabilityProperties(containerComponent, componentInstanceUniqueId, instanceCapProps)) + .map(instanceCapProps -> topologyTemplateOperation + .updateComponentInstanceCapabilityProperties(containerComponent, componentInstanceUniqueId, instanceCapProps)) .orElse(StorageOperationStatus.NOT_FOUND); } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java index db6a8e100f..08f672b4c8 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java @@ -94,6 +94,7 @@ import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.ComponentInstanceAttribute; import org.openecomp.sdc.be.model.ComponentInstanceInput; import org.openecomp.sdc.be.model.ComponentInstanceInterface; +import org.openecomp.sdc.be.model.ComponentInstanceOutput; import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.DistributionStatusEnum; @@ -102,6 +103,7 @@ import org.openecomp.sdc.be.model.GroupInstance; import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.MapInterfaceInstanceDataDefinition; +import org.openecomp.sdc.be.model.OutputDefinition; import org.openecomp.sdc.be.model.PolicyDefinition; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.RelationshipImpl; @@ -204,6 +206,8 @@ public class ModelConverter { convertInputs(topologyTemplate, service); + convertOutputs(topologyTemplate, service); + convertProperties(topologyTemplate, service); convertPolicies(topologyTemplate, service); @@ -282,6 +286,7 @@ public class ModelConverter { convertComponentInstances(topologyTemplate, resource); convertRelations(topologyTemplate, resource); convertInputs(topologyTemplate, resource); + convertOutputs(topologyTemplate, resource); convertGroups(topologyTemplate, resource); setCapabilitiesToComponentAndGroups(topologyTemplate, resource); convertPolicies(topologyTemplate, resource); @@ -355,6 +360,8 @@ public class ModelConverter { setComponentInstancesInputsToComponent(topologyTemplate, component); + setComponentInstancesOutputsToComponent(topologyTemplate, component); + setComponentInstancesToComponent(topologyTemplate, component); setComponentInstancesCapabilitiesToComponentAndCI(topologyTemplate, component); @@ -1347,6 +1354,18 @@ public class ModelConverter { } } + private static void convertOutputs(final TopologyTemplate topologyTemplate, final Component component) { + final Map<String, AttributeDataDefinition> outputsMap = topologyTemplate.getOutputs(); + if (MapUtils.isEmpty(outputsMap)) { + return; + } + final List<OutputDefinition> outputList = outputsMap.values() + .stream() + .map(OutputDefinition::new) + .collect(Collectors.toList()); + component.setOutputs(outputList); + } + private static void convertProperties(Component component, TopologyTemplate topologyTemplate) { List<PropertyDefinition> propertiesList = component.getProperties(); if (propertiesList != null && !propertiesList.isEmpty()) { @@ -1573,6 +1592,21 @@ public class ModelConverter { } } + private static void setComponentInstancesOutputsToComponent(final TopologyTemplate topologyTemplate, final Component component) { + if (topologyTemplate.getInstOutputs() != null) { + final Map<String, List<ComponentInstanceOutput>> outputs = new HashMap<>(); + for (final Entry<String, MapAttributesDataDefinition> entry : topologyTemplate.getInstOutputs().entrySet()) { + if (entry.getValue() != null && entry.getValue().getMapToscaDataDefinition() != null) { + final String key = entry.getKey(); + final List<ComponentInstanceOutput> componentInstanceAttributes = entry.getValue().getMapToscaDataDefinition().entrySet().stream() + .map(e -> new ComponentInstanceOutput(e.getValue())).collect(Collectors.toList()); + outputs.put(key, componentInstanceAttributes); + } + } + component.setComponentInstancesOutputs(outputs); + } + } + private static void setComponentInstancesPropertiesToComponent(TopologyTemplate topologyTemplate, Component component) { if (topologyTemplate.getInstProperties() != null) { Map<String, List<ComponentInstanceProperty>> properties = new HashMap<>(); diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransfer.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransfer.java index 1d1c8cd9dc..c7e34fcbfa 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransfer.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransfer.java @@ -40,6 +40,7 @@ import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.GroupDefinition; import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.OutputDefinition; import org.openecomp.sdc.be.model.PolicyDefinition; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; @@ -70,6 +71,7 @@ public class UiComponentDataTransfer { private List<PolicyDefinition> policies; private Map<String, List<RequirementDefinition>> requirements; private List<InputDefinition> inputs; + private List<OutputDefinition> outputs; private List<GroupDefinition> groups; private Map<String, InterfaceDefinition> interfaces; @@ -82,7 +84,4 @@ public class UiComponentDataTransfer { private List<AttributeDefinition> attributes; private Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaces; - public UiComponentDataTransfer() { - } - } diff --git a/catalog-ui/src/app/models/attributes-outputs/attribute-be-model.ts b/catalog-ui/src/app/models/attributes-outputs/attribute-be-model.ts index e06a807264..6af23a55ae 100644 --- a/catalog-ui/src/app/models/attributes-outputs/attribute-be-model.ts +++ b/catalog-ui/src/app/models/attributes-outputs/attribute-be-model.ts @@ -34,7 +34,6 @@ export class AttributeBEModel { constraints: any[]; defaultValue: string; - definition: boolean; description: string; fromDerived: boolean; getOutputValues: AttributeOutputDetail[]; @@ -69,7 +68,6 @@ export class AttributeBEModel { this.type = attribute.type; this.uniqueId = attribute.uniqueId; this.value = attribute.value; - this.definition = attribute.definition; this.getOutputValues = attribute.getOutputValues; this.parentAttributeType = attribute.parentAttributeType; this.subAttributeOutputPath = attribute.subAttributeOutputPath; diff --git a/common-app-api/src/main/java/org/openecomp/sdc/common/api/Constants.java b/common-app-api/src/main/java/org/openecomp/sdc/common/api/Constants.java index 340b198460..20c85683b7 100644 --- a/common-app-api/src/main/java/org/openecomp/sdc/common/api/Constants.java +++ b/common-app-api/src/main/java/org/openecomp/sdc/common/api/Constants.java @@ -131,6 +131,7 @@ public final class Constants { public static final String VF_LICENSE_DISPLAY_NAME = "VF License"; public static final String VF_LICENSE_DESCRIPTION = "VF license file"; public static final String GET_INPUT = "get_input"; + public static final String GET_ATTRIBUTE = "get_attribute"; public static final String GET_POLICY = "get_policy"; public static final String SERVICE_TEMPLATE_FILE_POSTFIX = "ServiceTemplate.yaml"; public static final String SERVICE_TEMPLATES_CONTAINING_FOLDER = "Definitions/"; diff --git a/common-app-logging/src/main/java/org/openecomp/sdc/common/log/enums/LoggerSupportabilityActions.java b/common-app-logging/src/main/java/org/openecomp/sdc/common/log/enums/LoggerSupportabilityActions.java index de4f78e13a..4f61b63a54 100644 --- a/common-app-logging/src/main/java/org/openecomp/sdc/common/log/enums/LoggerSupportabilityActions.java +++ b/common-app-logging/src/main/java/org/openecomp/sdc/common/log/enums/LoggerSupportabilityActions.java @@ -36,6 +36,7 @@ public enum LoggerSupportabilityActions { CREATE_RESOURCE("CREATE RESOURCE"), CREATE_PROPERTIES("ADD PROPERTIES"), CREATE_INPUTS("ADD INPUTS"), + CREATE_OUTPUTS("ADD OUTPUTS"), CREATE_POLICIES("ADD POLICIES"), CREATE_RELATIONS("ADD RELATIONS"), CREATE_CAPABILITY_REQUIREMENTS("CREATE CAPABILITY REQUIREMENTS"), diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/AttributeDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/AttributeDataDefinition.java index f1ca2167f6..d159da853a 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/AttributeDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/AttributeDataDefinition.java @@ -19,9 +19,9 @@ */ package org.openecomp.sdc.be.datatypes.elements; -import java.io.Serializable; import java.util.List; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; import org.onap.sdc.tosca.datatypes.model.EntrySchema; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; @@ -29,14 +29,16 @@ import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; @Getter @Setter -public class AttributeDataDefinition extends ToscaDataDefinition implements Serializable { +@NoArgsConstructor +public class AttributeDataDefinition extends ToscaDataDefinition { private List<GetOutputValueDataDefinition> getOutputValues; private String outputId; private String value; - - public AttributeDataDefinition() { - } + private String outputPath; + private String instanceUniqueId; + private String attributeId; + private String parentUniqueId; public AttributeDataDefinition(final AttributeDataDefinition attributeDataDefinition) { super(); @@ -46,16 +48,21 @@ public class AttributeDataDefinition extends ToscaDataDefinition implements Seri this.setType(attributeDataDefinition.getType()); this.setDescription(attributeDataDefinition.getDescription()); this.set_default(attributeDataDefinition.get_default()); + this.setValue(attributeDataDefinition.getValue()); this.setStatus(attributeDataDefinition.getStatus()); this.setEntry_schema(attributeDataDefinition.getEntry_schema()); this.setSchema(attributeDataDefinition.getSchema()); + this.setOutputPath(attributeDataDefinition.getOutputPath()); + this.setInstanceUniqueId(attributeDataDefinition.getInstanceUniqueId()); + this.setAttributeId(attributeDataDefinition.getAttributeId()); + this.setParentUniqueId(attributeDataDefinition.getParentUniqueId()); } public String getUniqueId() { return (String) getToscaPresentationValue(JsonPresentationFields.UNIQUE_ID); } - public void setUniqueId(String uniqueId) { + public void setUniqueId(final String uniqueId) { setToscaPresentationValue(JsonPresentationFields.UNIQUE_ID, uniqueId); } @@ -65,7 +72,7 @@ public class AttributeDataDefinition extends ToscaDataDefinition implements Seri } @Override - public void setOwnerId(String ownerId) { + public void setOwnerId(final String ownerId) { setToscaPresentationValue(JsonPresentationFields.OWNER_ID, ownerId); } @@ -73,7 +80,7 @@ public class AttributeDataDefinition extends ToscaDataDefinition implements Seri return (String) getToscaPresentationValue(JsonPresentationFields.NAME); } - public void setName(String name) { + public void setName(final String name) { setToscaPresentationValue(JsonPresentationFields.NAME, name); } @@ -82,7 +89,8 @@ public class AttributeDataDefinition extends ToscaDataDefinition implements Seri return (String) getToscaPresentationValue(JsonPresentationFields.TYPE); } - public void setType(String type) { + @Override + public void setType(final String type) { setToscaPresentationValue(JsonPresentationFields.TYPE, type); } @@ -90,7 +98,7 @@ public class AttributeDataDefinition extends ToscaDataDefinition implements Seri return (String) getToscaPresentationValue(JsonPresentationFields.DESCRIPTION); } - public void setDescription(String description) { + public void setDescription(final String description) { setToscaPresentationValue(JsonPresentationFields.DESCRIPTION, description); } @@ -98,7 +106,7 @@ public class AttributeDataDefinition extends ToscaDataDefinition implements Seri return getToscaPresentationValue(JsonPresentationFields.DEFAULT); } - public void set_default(Object _default) { + public void set_default(final Object _default) { setToscaPresentationValue(JsonPresentationFields.DEFAULT, _default); } @@ -106,7 +114,7 @@ public class AttributeDataDefinition extends ToscaDataDefinition implements Seri return (String) getToscaPresentationValue(JsonPresentationFields.STATUS); } - public void setStatus(String status) { + public void setStatus(final String status) { setToscaPresentationValue(JsonPresentationFields.STATUS, status); } @@ -114,7 +122,7 @@ public class AttributeDataDefinition extends ToscaDataDefinition implements Seri return (EntrySchema) getToscaPresentationValue(JsonPresentationFields.SCHEMA); } - public void setEntry_schema(EntrySchema entrySchema) { + public void setEntry_schema(final EntrySchema entrySchema) { setToscaPresentationValue(JsonPresentationFields.SCHEMA, entrySchema); } @@ -122,4 +130,8 @@ public class AttributeDataDefinition extends ToscaDataDefinition implements Seri return (SchemaDefinition) getToscaPresentationValue(JsonPresentationFields.SCHEMA); } + public String getParentUniqueId() { + return getOwnerId(); + } + } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/GetOutputValueDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/GetOutputValueDataDefinition.java index 8bb7f7e153..534aa232c8 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/GetOutputValueDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/GetOutputValueDataDefinition.java @@ -34,11 +34,11 @@ import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; public class GetOutputValueDataDefinition extends ToscaDataDefinition { private String attribName; - private String inputName; - private String inputId; + private String outputName; + private String outputId; private Integer indexValue; private GetOutputValueDataDefinition getOutputIndex; - private boolean isList = false; + private boolean isList; public GetOutputValueDataDefinition() { super(); @@ -50,8 +50,8 @@ public class GetOutputValueDataDefinition extends ToscaDataDefinition { public GetOutputValueDataDefinition(GetOutputValueDataDefinition p) { this.setAttribName(p.getAttribName()); - this.setInputName(p.getInputName()); - this.setInputId(p.getInputId()); + this.setOutputName(p.getOutputName()); + this.setOutputId(p.getOutputId()); this.setIndexValue(p.getIndexValue()); this.setGetOutputIndex(p.getGetOutputIndex()); this.setList(p.isList()); diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ComponentFieldsEnum.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ComponentFieldsEnum.java index 91c956d613..ac6d1bba82 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ComponentFieldsEnum.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ComponentFieldsEnum.java @@ -40,6 +40,7 @@ public enum ComponentFieldsEnum { ATTRIBUTES("attributes"), COMPONENT_INSTANCES_ATTRIBUTES("componentInstancesAttributes"), COMPONENT_INSTANCE_INPUTS("componentInstancesInputs"), + COMPONENT_INSTANCE_OUTPUTS("componentInstancesOutputs"), COMPONENT_INSTANCE_RELATION("componentInstancesRelations"), DEPLOYMENT_ARTIFACTS("deploymentArtifacts"), TOSCA_ARTIFACTS("toscaArtifacts"), diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/DeclarationTypeEnum.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/DeclarationTypeEnum.java index a25df30fcd..30b536ea1d 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/DeclarationTypeEnum.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/DeclarationTypeEnum.java @@ -22,5 +22,6 @@ package org.openecomp.sdc.be.datatypes.enums; public enum DeclarationTypeEnum { INPUT, - POLICY; + OUTPUT, + POLICY } |