summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJvD_Ericsson <jeff.van.dam@est.tech>2022-05-23 08:26:40 +0100
committerMichael Morris <michael.morris@est.tech>2022-06-03 12:20:16 +0000
commita80da69b9e95a6cbdbe50251c37c9dcc50650e4c (patch)
treef21a6acc25dab04f42b2891e5d1ec2b099c36dd6
parentff317808f308af03321de0f0b0849cd9f6f8ccad (diff)
Maintain VFC instance attribute outputs on instance version change
Issue-ID: SDC-4025 Signed-off-by: JvD_Ericsson <jeff.van.dam@est.tech> Change-Id: Ia44a6ac73d9a52042caaacf0c5f790e1e2fc73f1
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java8
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceAttributesAndOutputsMerge.java137
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceAttributesMergeBL.java73
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceMergeDataBusinessLogic.java2
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceOutputsRedeclareHandler.java78
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/DataForMergeHolder.java48
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/output/DeclaredOutputsResolver.java66
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/output/OutputsValuesMergingBusinessLogic.java63
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceAttributesAndOutputsMergeTest.java183
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/ComponentBuilder.java30
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/ObjectGenerator.java20
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java8
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java21
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/AttributeDataDefinition.java22
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/utils/AttributeDefinitionUtils.java42
15 files changed, 792 insertions, 9 deletions
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 392020be4d..2caa721b5e 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
@@ -2936,13 +2936,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
} else {
origComponent = getOriginComponentFromComponentInstance(newComponentInstance);
newComponentInstance.setName(resResourceInfo.getName());
- final Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade
- .getToscaFullElement(newComponentInstance.getComponentUid());
- if (getComponentRes.isRight()) {
- throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
- }
- final Component component = getComponentRes.left().value();
- final Map<String, InterfaceDefinition> componentInterfaces = component.getInterfaces();
+ final Map<String, InterfaceDefinition> componentInterfaces = origComponent.getInterfaces();
if (MapUtils.isNotEmpty(componentInterfaces)) {
componentInterfaces.forEach(newComponentInstance::addInterface);
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceAttributesAndOutputsMerge.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceAttributesAndOutputsMerge.java
new file mode 100644
index 0000000000..c1ab30d646
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceAttributesAndOutputsMerge.java
@@ -0,0 +1,137 @@
+/*
+* ============LICENSE_START=======================================================
+* SDC
+* ================================================================================
+* Copyright (C) 2022 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.merge.instance;
+
+import fj.data.Either;
+import java.util.List;
+import java.util.ArrayList;
+import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+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.ComponentParametersView;
+import org.openecomp.sdc.be.model.OutputDefinition;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+
+
+
+import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
+
+@org.springframework.stereotype.Component("ComponentInstanceAttributesMerge")
+public class ComponentInstanceAttributesAndOutputsMerge implements ComponentInstanceMergeInterface {
+
+ private static final Logger log = Logger.getLogger(ComponentInstanceAttributesAndOutputsMerge.class);
+ private final ToscaOperationFacade toscaOperationFacade;
+ private final ComponentsUtils componentsUtils;
+ private final ComponentInstanceAttributesMergeBL componentInstanceAttributesMergeBL;
+ private final ComponentInstanceOutputsRedeclareHandler instanceOutputsRedeclareHandler;
+
+ public ComponentInstanceAttributesAndOutputsMerge(ToscaOperationFacade toscaOperationFacade, ComponentsUtils componentsUtils,
+ ComponentInstanceAttributesMergeBL componentInstanceAttributesMergeBL,
+ ComponentInstanceOutputsRedeclareHandler instanceOutputsRedeclareHandler) {
+ this.toscaOperationFacade = toscaOperationFacade;
+ this.componentsUtils = componentsUtils;
+ this.componentInstanceAttributesMergeBL = componentInstanceAttributesMergeBL;
+ this.instanceOutputsRedeclareHandler = instanceOutputsRedeclareHandler;
+ }
+
+
+ @Override
+ public void saveDataBeforeMerge(DataForMergeHolder dataHolder, Component containerComponent, ComponentInstance currentResourceInstance,
+ Component originComponent) {
+ dataHolder.setOrigComponentInstanceAttributes(containerComponent.safeGetComponentInstancesAttributes()
+ .get(currentResourceInstance.getUniqueId()));
+ dataHolder.setOrigComponentOutputs(containerComponent.getOutputs());
+ }
+
+
+ @Override
+ public Component mergeDataAfterCreate(User user, DataForMergeHolder dataHolder, Component updatedContainerComponent, String newInstanceId) {
+ Either<List<ComponentInstanceAttribute>, ActionStatus> attributesEither = mergeComponentInstanceAttributesIntoContainer(dataHolder,
+ updatedContainerComponent, newInstanceId);
+ if (attributesEither.isRight()) {
+ ActionStatus actionStatus = attributesEither.right().value();
+ throw new ByActionStatusComponentException(actionStatus);
+ }
+ Either<List<OutputDefinition>, ActionStatus> outputsEither = mergeComponentOutputsIntoContainer(dataHolder,
+ updatedContainerComponent.getUniqueId(), newInstanceId);
+ if (outputsEither.isRight()) {
+ ActionStatus actionStatus = outputsEither.right().value();
+ throw new ByActionStatusComponentException(actionStatus);
+ }
+ return updatedContainerComponent;
+ }
+
+ private Either<List<ComponentInstanceAttribute>, ActionStatus> mergeComponentInstanceAttributesIntoContainer(DataForMergeHolder dataHolder,
+ Component updatedComponent,
+ String instanceId) {
+ List<ComponentInstanceAttribute> originComponentInstanceAttributes = dataHolder.getOrigComponentInstanceAttributes();
+ List<ComponentInstanceAttribute> newComponentInstancesAttributes = updatedComponent.safeGetComponentInstanceAttributes(instanceId);
+ ActionStatus actionStatus = componentInstanceAttributesMergeBL
+ .mergeComponentInstanceAttributes(originComponentInstanceAttributes, updatedComponent, instanceId);
+ if (actionStatus != ActionStatus.OK) {
+ log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, updatedComponent.getName(),
+ "Failed to update component " + updatedComponent.getName() + " " + instanceId
+ + " with instance attributes " + newComponentInstancesAttributes);
+ return Either.right(actionStatus);
+ }
+ return Either.left(newComponentInstancesAttributes);
+ }
+
+ private Either<List<OutputDefinition>, ActionStatus> mergeComponentOutputsIntoContainer(DataForMergeHolder dataHolder,
+ String newContainerComponentId, String newInstanceId) {
+ List<OutputDefinition> origComponentOutputs = dataHolder.getOrigComponentOutputs();
+ List<OutputDefinition> outputsToAddToContainer = new ArrayList<>();
+ if (isNotEmpty(origComponentOutputs)) {
+ Either<Component, StorageOperationStatus> componentWithInstancesAttributesAndOutputs = getComponentOutputs(newContainerComponentId);
+ if (componentWithInstancesAttributesAndOutputs.isRight()) {
+ log.error(EcompLoggerErrorCode.DATA_ERROR, newContainerComponentId, "Component " + newContainerComponentId
+ + " was not found");
+ return Either.right(componentsUtils.convertFromStorageResponse(componentWithInstancesAttributesAndOutputs.right().value()));
+ }
+ Component updatedContainerComponent = componentWithInstancesAttributesAndOutputs.left().value();
+ ActionStatus redeclareStatus = instanceOutputsRedeclareHandler
+ .redeclareComponentOutputsForInstance(updatedContainerComponent, newInstanceId, origComponentOutputs);
+
+ if (redeclareStatus != ActionStatus.OK) {
+ log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, updatedContainerComponent.getName(),
+ "Failed to update component " + updatedContainerComponent.getName() + " " + newContainerComponentId
+ + " with merged inputs " + outputsToAddToContainer);
+ return Either.right(redeclareStatus);
+ }
+ }
+ return Either.left(outputsToAddToContainer);
+ }
+
+ private Either<Component, StorageOperationStatus> getComponentOutputs(String containerComponentId) {
+ ComponentParametersView filter = new ComponentParametersView(true);
+ filter.setIgnoreComponentInstances(false);
+ filter.setIgnoreOutputs(false);
+ filter.setIgnoreComponentInstancesAttributes(false);
+ filter.setIgnoreArtifacts(false);
+ return toscaOperationFacade.getToscaElement(containerComponentId, filter);
+ }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceAttributesMergeBL.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceAttributesMergeBL.java
new file mode 100644
index 0000000000..5ee91f6152
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceAttributesMergeBL.java
@@ -0,0 +1,73 @@
+/*
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2022 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.merge.instance;
+
+import static org.openecomp.sdc.be.components.merge.resource.ResourceDataMergeBusinessLogic.ANY_ORDER_COMMAND;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.impl.ComponentsUtils;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
+import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.springframework.core.annotation.Order;
+
+@org.springframework.stereotype.Component
+@Order(ANY_ORDER_COMMAND)
+public class ComponentInstanceAttributesMergeBL {
+
+ private final ToscaOperationFacade toscaOperationFacade;
+ private final ComponentsUtils componentsUtils;
+
+ public ComponentInstanceAttributesMergeBL(ToscaOperationFacade toscaOperationFacade, ComponentsUtils componentsUtils) {
+ this.toscaOperationFacade = toscaOperationFacade;
+ this.componentsUtils = componentsUtils;
+ }
+
+ public ActionStatus mergeComponentInstanceAttributes(List<ComponentInstanceAttribute> oldInstAttributes,
+ Component newComponent, String instanceId) {
+ List<ComponentInstanceAttribute> newInstAttributes = newComponent.safeGetComponentInstanceAttributes(instanceId);
+ if (newInstAttributes == null) {
+ return ActionStatus.OK;
+ }
+ List<ComponentInstanceAttribute> commonInstAttributes = new ArrayList<>();
+ newInstAttributes.forEach(newAttribute -> oldInstAttributes
+ .stream().filter(oldAttribute -> newAttribute.getName().equals(oldAttribute.getName())).forEach(oldInstAttribute -> {
+ if ((oldInstAttribute.getValue() == null || oldInstAttribute.getValue().equals(oldInstAttribute.getDefaultValue()))
+ && newAttribute.getDefaultValue() != null) {
+ oldInstAttribute.setValue(newAttribute.getDefaultValue());
+ oldInstAttribute.setDefaultValue(newAttribute.getDefaultValue());
+ }
+ oldInstAttribute.setDescription(newAttribute.getDescription());
+ commonInstAttributes.add(oldInstAttribute);
+ }));
+ return updateComponentInstanceAttributes(newComponent, instanceId, commonInstAttributes);
+ }
+
+ private ActionStatus updateComponentInstanceAttributes(Component component, String instanceId, List<ComponentInstanceAttribute> newInstAttributes) {
+ StorageOperationStatus storageOperationStatus = toscaOperationFacade.updateComponentInstanceAttributes(component, instanceId, newInstAttributes);
+ if (storageOperationStatus != StorageOperationStatus.OK) {
+ return componentsUtils.convertFromStorageResponse(storageOperationStatus);
+ }
+ return ActionStatus.OK;
+ }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceMergeDataBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceMergeDataBusinessLogic.java
index 7353a1205f..51349c190b 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceMergeDataBusinessLogic.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceMergeDataBusinessLogic.java
@@ -103,6 +103,8 @@ public class ComponentInstanceMergeDataBusinessLogic {
filter.setIgnoreArtifacts(false);
filter.setIgnoreServicePath(false);
filter.setIgnoreComponentInstancesInterfaces(false);
+ filter.setIgnoreComponentInstancesAttributes(false);
+ filter.setIgnoreOutputs(false);
return toscaOperationFacade.getToscaElement(containerComponentId, filter);
}
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceOutputsRedeclareHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceOutputsRedeclareHandler.java
new file mode 100644
index 0000000000..0c851f807c
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceOutputsRedeclareHandler.java
@@ -0,0 +1,78 @@
+/*
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2022 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.merge.instance;
+
+import static java.util.stream.Collectors.toList;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Stream;
+import org.openecomp.sdc.be.components.merge.output.DeclaredOutputsResolver;
+import org.openecomp.sdc.be.components.merge.output.OutputsValuesMergingBusinessLogic;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+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.OutputDefinition;
+import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+
+@org.springframework.stereotype.Component
+public class ComponentInstanceOutputsRedeclareHandler {
+
+ private static final Logger log = Logger.getLogger(ComponentInstanceOutputsRedeclareHandler.class);
+ private final DeclaredOutputsResolver declaredOutputsResolver;
+ private final ToscaOperationFacade toscaOperationFacade;
+ private final ComponentsUtils componentsUtils;
+ private final OutputsValuesMergingBusinessLogic outputsValuesMergingBusinessLogic;
+
+ public ComponentInstanceOutputsRedeclareHandler(DeclaredOutputsResolver declaredOutputsResolver, ToscaOperationFacade toscaOperationFacade,
+ ComponentsUtils componentsUtils,
+ OutputsValuesMergingBusinessLogic outputsValuesMergingBusinessLogic) {
+ this.declaredOutputsResolver = declaredOutputsResolver;
+ this.toscaOperationFacade = toscaOperationFacade;
+ this.componentsUtils = componentsUtils;
+ this.outputsValuesMergingBusinessLogic = outputsValuesMergingBusinessLogic;
+ }
+
+ public ActionStatus redeclareComponentOutputsForInstance(Component container, String newInstanceId, List<OutputDefinition> oldOutputs) {
+ log.debug(
+ "#redeclareComponentOutputsForInstance - getting outputs that were previously declared from instance {} and setting on current component {}",
+ newInstanceId, container.getUniqueId());
+ List<AttributeDataDefinition> allAttributesForInstance = getAllGetAttributesForInstance(container, newInstanceId);
+ List<OutputDefinition> previouslyDeclaredOutputs = declaredOutputsResolver
+ .getPreviouslyDeclaredOutputsToMerge(oldOutputs, allAttributesForInstance, newInstanceId);
+ outputsValuesMergingBusinessLogic.mergeComponentOutputs(oldOutputs, previouslyDeclaredOutputs);
+ return updateOutputs(container.getUniqueId(), previouslyDeclaredOutputs);
+ }
+
+ private List<AttributeDataDefinition> getAllGetAttributesForInstance(Component newComponent, String instanceId) {
+ return Stream
+ .of(newComponent.safeGetComponentInstanceAttributes(instanceId))
+ .flatMap(Collection::stream).map(AttributeDataDefinition::new).collect(toList());
+ }
+
+ private ActionStatus updateOutputs(String containerId, List<OutputDefinition> outputsToUpdate) {
+ log.debug("#updateInputs - updating inputs for container {}", containerId);
+ return toscaOperationFacade.updateOutputsToComponent(outputsToUpdate, containerId)
+ .either(updatedInputs -> ActionStatus.OK, componentsUtils::convertFromStorageResponse);
+ }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/DataForMergeHolder.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/DataForMergeHolder.java
index 623d86e8e1..21c7461589 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/DataForMergeHolder.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/DataForMergeHolder.java
@@ -28,10 +28,12 @@ import java.util.Optional;
import org.openecomp.sdc.be.model.ArtifactDefinition;
import org.openecomp.sdc.be.model.CapabilityDefinition;
import org.openecomp.sdc.be.model.Component;
+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.ComponentInstanceProperty;
import org.openecomp.sdc.be.model.InputDefinition;
+import org.openecomp.sdc.be.model.OutputDefinition;
/**
* Created by chaya on 9/7/2017.
@@ -52,10 +54,14 @@ public class DataForMergeHolder {
private String origComponentInstId;
private List<ComponentInstanceInterface> origComponentInstanceInterfaces;
private Map<String, Integer> componentInstanceDeploymentArtifactsTimeOut;
+ private final List<ComponentInstanceAttribute> origComponentInstanceAttributes;
+ private final List<OutputDefinition> origComponentOutputs;
public DataForMergeHolder() {
origComponentInstanceInputs = new ArrayList<>();
origComponentInstanceProperties = new ArrayList<>();
+ origComponentInstanceAttributes = new ArrayList<>();
+ origComponentOutputs = new ArrayList<>();
origComponentInputs = new ArrayList<>();
origCompInstDeploymentArtifactsCreatedOnTheInstance = new HashMap<>();
origCompInstDeploymentArtifactsCreatedOnTheInstance = new HashMap<>();
@@ -77,7 +83,7 @@ public class DataForMergeHolder {
}
void setOrigComponentInstanceInputs(List<ComponentInstanceInput> origComponentInstanceInputs) {
- Optional.ofNullable(origComponentInstanceInputs).orElse(Collections.emptyList()).stream().forEach(input -> {
+ Optional.ofNullable(origComponentInstanceInputs).orElse(Collections.emptyList()).forEach(input -> {
ComponentInstanceInput copyInput = new ComponentInstanceInput();
copyInput.setType(input.getType());
copyInput.setPath(input.getPath());
@@ -107,7 +113,7 @@ public class DataForMergeHolder {
}
void setOrigComponentInstanceProperties(List<ComponentInstanceProperty> origComponentInstanceProperties) {
- Optional.ofNullable(origComponentInstanceProperties).orElse(Collections.emptyList()).stream().forEach(property -> {
+ Optional.ofNullable(origComponentInstanceProperties).orElse(Collections.emptyList()).forEach(property -> {
ComponentInstanceProperty propertyCopy = new ComponentInstanceProperty();
propertyCopy.setType(property.getType());
propertyCopy.setName(property.getName());
@@ -207,4 +213,42 @@ public class DataForMergeHolder {
public void setOrigComponentInstanceInterfaces(List<ComponentInstanceInterface> origComponentInstanceInterfaces) {
this.origComponentInstanceInterfaces = origComponentInstanceInterfaces;
}
+
+ List<ComponentInstanceAttribute> getOrigComponentInstanceAttributes() {
+ return origComponentInstanceAttributes;
+ }
+
+ void setOrigComponentInstanceAttributes(List<ComponentInstanceAttribute> origComponentInstanceAttributes) {
+ Optional.ofNullable(origComponentInstanceAttributes).orElse(Collections.emptyList()).forEach(attribute -> {
+ ComponentInstanceAttribute attributeCopy = new ComponentInstanceAttribute();
+ attributeCopy.setType(attribute.getType());
+ attributeCopy.setName(attribute.getName());
+ attributeCopy.setValue(attribute.getValue());
+ attributeCopy.setUniqueId(attribute.getUniqueId());
+ attributeCopy.setDefaultValue(attribute.getDefaultValue());
+ attributeCopy.setOutputId(attribute.getOutputId());
+ attributeCopy.setGetOutputValues(attribute.getGetOutputValues());
+ attributeCopy.setOutputPath(attribute.getOutputPath());
+ this.origComponentInstanceAttributes.add(attributeCopy);
+ });
+ }
+
+ List<OutputDefinition> getOrigComponentOutputs() {
+ return origComponentOutputs;
+ }
+
+ void setOrigComponentOutputs(List<OutputDefinition> origComponentOutputs) {
+ Optional.ofNullable(origComponentOutputs).orElse(Collections.emptyList()).forEach(output -> {
+ OutputDefinition outputCopy = new OutputDefinition();
+ outputCopy.setType(output.getType());
+ outputCopy.setName(output.getName());
+ outputCopy.setValue(output.getValue());
+ outputCopy.setUniqueId(output.getUniqueId());
+ outputCopy.setDefaultValue(output.getDefaultValue());
+ outputCopy.setOutputId(output.getOutputId());
+ outputCopy.setGetOutputValues(output.getGetOutputValues());
+ outputCopy.setOutputPath(output.getOutputPath());
+ this.origComponentOutputs.add(outputCopy);
+ });
+ }
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/output/DeclaredOutputsResolver.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/output/DeclaredOutputsResolver.java
new file mode 100644
index 0000000000..e48779a580
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/output/DeclaredOutputsResolver.java
@@ -0,0 +1,66 @@
+/*
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2022 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.merge.output;
+
+import static org.openecomp.sdc.be.utils.AttributeDefinitionUtils.getAttributesMappedToOutputs;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.openecomp.sdc.be.dao.utils.MapUtil;
+import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.GetOutputValueDataDefinition;
+import org.openecomp.sdc.be.model.OutputDefinition;
+
+@org.springframework.stereotype.Component
+public class DeclaredOutputsResolver {
+
+ public List<OutputDefinition> getPreviouslyDeclaredOutputsToMerge(List<OutputDefinition> oldOutputs, List<AttributeDataDefinition> attributes,
+ String instanceId) {
+ List<AttributeDataDefinition> attributesMappedToOutputsOnNewInstance = getAttributesMappedToOutputs(attributes);
+ return createOutputs(oldOutputs, attributesMappedToOutputsOnNewInstance, instanceId);
+ }
+
+ private List<OutputDefinition> createOutputs(List<OutputDefinition> oldOutputs,
+ List<AttributeDataDefinition> attributesMappedToOutputsOnNewInstance, String instanceId) {
+ Map<String, OutputDefinition> oldOutputsById = MapUtil.toMap(oldOutputs, OutputDefinition::getUniqueId);
+ List<OutputDefinition> outputsToRedeclare = new ArrayList<>();
+ attributesMappedToOutputsOnNewInstance.forEach(attribute -> {
+ List<OutputDefinition> outputDefinitions = prepareOutputsForRedeclaration(oldOutputsById, attribute, instanceId);
+ outputsToRedeclare.addAll(outputDefinitions);
+ });
+ return outputsToRedeclare;
+ }
+
+ private List<OutputDefinition> prepareOutputsForRedeclaration(Map<String, OutputDefinition> oldOutputsById,
+ AttributeDataDefinition attributeToCreateOutputFor, String instanceID) {
+ List<GetOutputValueDataDefinition> getOutputValueDataDefinition = attributeToCreateOutputFor.getGetOutputValues();
+ List<OutputDefinition> outputsForRedeclaration = new ArrayList<>();
+ for (GetOutputValueDataDefinition out : getOutputValueDataDefinition) {
+ if (oldOutputsById.containsKey(out.getOutputId())) {
+ OutputDefinition test = oldOutputsById.get(out.getOutputId());
+ test.setAttributeId(attributeToCreateOutputFor.getUniqueId());
+ test.setInstanceUniqueId(instanceID);
+ outputsForRedeclaration.add(test);
+ }
+ }
+ return outputsForRedeclaration;
+ }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/output/OutputsValuesMergingBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/output/OutputsValuesMergingBusinessLogic.java
new file mode 100644
index 0000000000..888672c78e
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/output/OutputsValuesMergingBusinessLogic.java
@@ -0,0 +1,63 @@
+/*
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2022 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.merge.output;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.openecomp.sdc.be.dao.utils.MapUtil;
+import org.openecomp.sdc.be.model.OutputDefinition;
+import org.springframework.stereotype.Component;
+
+@Component
+public class OutputsValuesMergingBusinessLogic {
+
+ public void mergeComponentOutputs(List<OutputDefinition> oldOutputs, List<OutputDefinition> outputsToMerge) {
+ Map<String, OutputDefinition> oldOutputsByName = MapUtil.toMap(oldOutputs, OutputDefinition::getName);
+ Map<String, OutputDefinition> outputsToMergeByName = MapUtil.toMap(outputsToMerge, OutputDefinition::getName);
+ mergeComponentOutputs(oldOutputsByName, outputsToMergeByName);
+ }
+
+ public void mergeComponentOutputs(Map<String, OutputDefinition> oldOutputs, Map<String, OutputDefinition> updatedOutputs) {
+ updatedOutputs.forEach((outputName, output) -> mergeOutputsValues(oldOutputs.get(outputName), output));
+ }
+
+ private void mergeOutputsValues(OutputDefinition oldOutput, OutputDefinition updatedOutput) {
+ if (shouldMergeOldValue(oldOutput, updatedOutput)) {
+ updatedOutput.setDefaultValue(oldOutput.getDefaultValue());
+ }
+ }
+
+ private boolean shouldMergeOldValue(OutputDefinition oldOutput, OutputDefinition newOutput) {
+ return isNonEmptyDefaultValue(oldOutput) && isEmptyDefaultValue(newOutput) && isSameType(oldOutput, newOutput);
+ }
+
+ private boolean isSameType(OutputDefinition oldOutput, OutputDefinition updatedOutput) {
+ return oldOutput.typeEquals(updatedOutput);
+ }
+
+ private boolean isEmptyDefaultValue(OutputDefinition output) {
+ return output != null && StringUtils.isEmpty(output.getDefaultValue());
+ }
+
+ private boolean isNonEmptyDefaultValue(OutputDefinition output) {
+ return output != null && !isEmptyDefaultValue(output);
+ }
+}
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceAttributesAndOutputsMergeTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceAttributesAndOutputsMergeTest.java
new file mode 100644
index 0000000000..931469a2cf
--- /dev/null
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceAttributesAndOutputsMergeTest.java
@@ -0,0 +1,183 @@
+/*
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2022 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.merge.instance;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.when;
+
+import fj.data.Either;
+import java.util.List;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
+import org.openecomp.sdc.be.components.utils.ObjectGenerator;
+import org.openecomp.sdc.be.components.utils.ResourceBuilder;
+import org.openecomp.sdc.be.config.ConfigurationManager;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.impl.ComponentsUtils;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.ComponentInstanceAttribute;
+import org.openecomp.sdc.be.model.ComponentParametersView;
+import org.openecomp.sdc.be.model.OutputDefinition;
+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.operations.ToscaOperationFacade;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.common.impl.ExternalConfiguration;
+import org.openecomp.sdc.common.impl.FSConfigurationSource;
+import org.openecomp.sdc.exception.ResponseFormat;
+
+class ComponentInstanceAttributesAndOutputsMergeTest {
+
+ private static final String INSTANCE_ID1 = "inst1";
+ private static final User USER = new User();
+
+ @InjectMocks
+ private ComponentInstanceAttributesAndOutputsMerge testInstance;
+
+ @Mock
+ private ToscaOperationFacade toscaOperationFacade;
+
+ @Mock
+ private ComponentsUtils componentsUtils;
+
+ @Mock
+ private ComponentInstanceAttributesMergeBL componentInstanceAttributesMergeBL;
+
+ @Mock
+ private ComponentInstanceOutputsRedeclareHandler componentInstanceOutputsRedeclareHandler;
+
+ private Resource resourceToUpdate;
+
+ @BeforeEach
+ public void setUp() throws Exception {
+ MockitoAnnotations.openMocks(this);
+ resourceToUpdate = new ResourceBuilder()
+ .addInstanceAttribute(INSTANCE_ID1, "instAttribute1")
+ .addInstanceAttribute(INSTANCE_ID1, "instAttribute2")
+ .addOutput("output1")
+ .addOutput("output2")
+ .setUniqueId("resourceId").build();
+
+ List<OutputDefinition> oldOutputs = ObjectGenerator.buildOutputs("output1");
+ List<ComponentInstanceAttribute> oldInstAttribute = ObjectGenerator.buildInstanceAttributes("instAttribute1", "instAttribute3");
+
+ DataForMergeHolder oldDataHolder = new DataForMergeHolder();
+ oldDataHolder.setOrigComponentOutputs(oldOutputs);
+ oldDataHolder.setOrigComponentInstanceAttributes(oldInstAttribute);
+ new ConfigurationManager(new FSConfigurationSource(ExternalConfiguration.getChangeListener(), "src/test/resources/config/catalog-be"));
+ }
+
+ @Test
+ void mergeDataAfterCreate() {
+ List<OutputDefinition> oldOutputs = ObjectGenerator.buildOutputs("output1");
+ List<ComponentInstanceAttribute> oldInstAttributes = ObjectGenerator.buildInstanceAttributes("instAttribute1", "instAttribute3");
+
+ DataForMergeHolder dataForMergeHolder = new DataForMergeHolder();
+ dataForMergeHolder.setOrigComponentOutputs(oldOutputs);
+ dataForMergeHolder.setOrigComponentInstanceAttributes(oldInstAttributes);
+
+ ArgumentCaptor<ComponentParametersView> parametersViewCaptor = ArgumentCaptor.forClass(ComponentParametersView.class);
+
+ when(componentInstanceAttributesMergeBL.mergeComponentInstanceAttributes(anyList(), eq(resourceToUpdate), eq(INSTANCE_ID1)))
+ .thenReturn(ActionStatus.OK);
+ when(componentInstanceOutputsRedeclareHandler.redeclareComponentOutputsForInstance(any(), any(), anyList()))
+ .thenReturn(ActionStatus.OK);
+ when(toscaOperationFacade.getToscaElement(eq("resourceId"), parametersViewCaptor.capture()))
+ .thenReturn(Either.left(resourceToUpdate));
+ Component mergeResult = testInstance.mergeDataAfterCreate(USER, dataForMergeHolder, resourceToUpdate, INSTANCE_ID1);
+ assertEquals(mergeResult, resourceToUpdate);
+ assertComponentFilter(parametersViewCaptor.getValue());
+ }
+
+ @Test
+ void mergeDataAfterCreate_failedToMergeComponentInstanceOutputs() {
+ List<OutputDefinition> oldOutputs = ObjectGenerator.buildOutputs("output1");
+ List<ComponentInstanceAttribute> oldInstAttributes = ObjectGenerator.buildInstanceAttributes("instAttribute1", "instAttribute3");
+
+ DataForMergeHolder dataForMergeHolder = new DataForMergeHolder();
+ dataForMergeHolder.setOrigComponentOutputs(oldOutputs);
+ dataForMergeHolder.setOrigComponentInstanceAttributes(oldInstAttributes);
+
+ ArgumentCaptor<ComponentParametersView> parametersViewCaptor = ArgumentCaptor.forClass(ComponentParametersView.class);
+
+ when(componentInstanceAttributesMergeBL.mergeComponentInstanceAttributes(anyList(), eq(resourceToUpdate), eq(INSTANCE_ID1)))
+ .thenReturn(ActionStatus.OK);
+ when(toscaOperationFacade.getToscaElement(eq("resourceId"), parametersViewCaptor.capture()))
+ .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR));
+ when(componentsUtils.convertFromStorageResponse(StorageOperationStatus.GENERAL_ERROR)).thenReturn(ActionStatus.GENERAL_ERROR);
+ assertThrows(ComponentException.class, () -> {
+ testInstance.mergeDataAfterCreate(USER, dataForMergeHolder, resourceToUpdate, "inst1");
+ });
+ verifyNoInteractions(componentInstanceOutputsRedeclareHandler);
+ }
+
+ @Test
+ void mergeDataAfterCreate_failedToMergeComponentInstAttributes() {
+ final ResponseFormat errorResponse = new ResponseFormat();
+ when(componentInstanceAttributesMergeBL.mergeComponentInstanceAttributes(anyList(), any(Component.class), anyString()))
+ .thenReturn(ActionStatus.GENERAL_ERROR);
+ when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(errorResponse);
+ final DataForMergeHolder dataHolder = new DataForMergeHolder();
+ final Service service = new Service();
+ assertThrows(ComponentException.class, () -> {
+ testInstance.mergeDataAfterCreate(USER, dataHolder, service, "inst1");
+ });
+ verifyNoInteractions(componentInstanceOutputsRedeclareHandler, toscaOperationFacade);
+ }
+
+ @Test
+ void mergeDataAfterCreate_mergeInputs_FailedToFetchResource() {
+ final ResponseFormat errorResponse = new ResponseFormat();
+ when(componentInstanceAttributesMergeBL.mergeComponentInstanceAttributes(anyList(), any(Component.class), anyString()))
+ .thenReturn(ActionStatus.OK);
+ when(toscaOperationFacade.getToscaElement(any(), any(ComponentParametersView.class)))
+ .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR));
+ when(componentsUtils.convertFromStorageResponse(StorageOperationStatus.GENERAL_ERROR)).thenReturn(ActionStatus.GENERAL_ERROR);
+ when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(errorResponse);
+ final DataForMergeHolder dataHolder = new DataForMergeHolder();
+ dataHolder.setOrigComponentOutputs(ObjectGenerator.buildOutputs("output1", "output2"));
+ final Service service = new Service();
+ assertThrows(ComponentException.class, () -> {
+ testInstance.mergeDataAfterCreate(USER, dataHolder, service, "inst1");
+ });
+ verifyNoInteractions(componentInstanceOutputsRedeclareHandler);
+ }
+
+ private void assertComponentFilter(ComponentParametersView value) {
+ assertFalse(value.isIgnoreComponentInstances());
+ assertFalse(value.isIgnoreComponentInstancesAttributes());
+ assertFalse(value.isIgnoreOutputs());
+ assertFalse(value.isIgnoreArtifacts());
+ }
+}
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/ComponentBuilder.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/ComponentBuilder.java
index 0dad76ebfe..b9e181fcfe 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/ComponentBuilder.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/ComponentBuilder.java
@@ -25,7 +25,9 @@ import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
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.GroupDefinition;
import org.openecomp.sdc.be.model.InputDefinition;
@@ -37,6 +39,7 @@ import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
public abstract class ComponentBuilder<T extends Component, B extends ComponentBuilder<T, B>> {
@@ -190,6 +193,33 @@ public abstract class ComponentBuilder<T extends Component, B extends ComponentB
return self();
}
+ public void addInstanceAttribute(String instanceId, ComponentInstanceAttribute attribute) {
+ Map<String, List<ComponentInstanceAttribute>> compInstAttribute = component.safeGetComponentInstancesAttributes();
+ if (compInstAttribute == null || compInstAttribute.isEmpty()) {
+ component.setComponentInstancesAttributes(new HashMap<>());
+ }
+ Map<String, List<ComponentInstanceAttribute>> instAttribute = component.safeGetComponentInstancesAttributes();
+ instAttribute.computeIfAbsent(instanceId, key -> new ArrayList<>()).add(attribute);
+ self();
+ }
+
+ public ComponentBuilder<T, B> addInstanceAttribute(String instanceId, String AttributeName) {
+ ComponentInstanceAttribute componentInstanceAttribute = new ComponentInstanceAttribute();
+ componentInstanceAttribute.setName(AttributeName);
+ componentInstanceAttribute.setUniqueId(AttributeName);
+ this.addInstanceAttribute(instanceId, componentInstanceAttribute);
+ return self();
+ }
+
+ public void addInstanceOutput(String instanceId, ComponentInstanceOutput attribute) {
+ if (component.getComponentInstancesOutputs() == null) {
+ component.setComponentInstancesOutputs(new HashMap<>());
+ }
+ component.getComponentInstancesOutputs().computeIfAbsent(instanceId, key -> new ArrayList<>()).add(attribute);
+ self();
+ }
+
+
public ComponentBuilder<T, B> addRelationship(RequirementCapabilityRelDef requirementCapabilityRelDef) {
if (component.getComponentInstancesRelations() == null) {
component.setComponentInstancesRelations(new ArrayList<>());
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/ObjectGenerator.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/ObjectGenerator.java
index c6a36971a8..8f194f1d0f 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/ObjectGenerator.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/ObjectGenerator.java
@@ -21,10 +21,12 @@
package org.openecomp.sdc.be.components.utils;
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.ComponentInstanceProperty;
import org.openecomp.sdc.be.model.HeatParameterDefinition;
import org.openecomp.sdc.be.model.InputDefinition;
+import org.openecomp.sdc.be.model.OutputDefinition;
import org.openecomp.sdc.be.model.PropertyDefinition;
import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
import org.openecomp.sdc.be.model.Resource;
@@ -80,6 +82,24 @@ public class ObjectGenerator {
return inputs;
}
+ public static List<ComponentInstanceAttribute> buildInstanceAttributes(String ... attributesNames) {
+ return Stream.of(attributesNames).map(name -> {
+ ComponentInstanceAttribute instAttribute = new ComponentInstanceAttribute();
+ instAttribute.setName(name);
+ return instAttribute;
+ }).collect(Collectors.toList());
+ }
+
+ public static List<OutputDefinition> buildOutputs(String ... outputNames) {
+ List<OutputDefinition> outputs = new ArrayList<>();
+ for (String outputName : outputNames) {
+ OutputDefinition outputDefinition = new OutputDefinition();
+ outputDefinition.setName(outputName);
+ outputs.add(outputDefinition);
+ }
+ return outputs;
+ }
+
public static Resource buildResourceWithComponentInstance(String ... instanceNames) {
List<ComponentInstance> instances = new ArrayList<>();
for (String instanceName : instanceNames) {
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 1c0cfc4c5d..3252d79281 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
@@ -387,10 +387,18 @@ public abstract class Component implements PropertiesOwner {
return this.safeGetComponentInstanceEntity(cmptInstacneId, this.componentInstancesProperties);
}
+ public List<ComponentInstanceAttribute> safeGetComponentInstanceAttributes(String cmptInstacneId) {
+ return this.safeGetComponentInstanceEntity(cmptInstacneId, this.componentInstancesAttributes);
+ }
+
public List<ComponentInstanceInput> safeGetComponentInstanceInput(String comptInstanceId) {
return this.safeGetComponentInstanceEntity(comptInstanceId, this.componentInstancesInputs);
}
+ public List<ComponentInstanceOutput> safeGetComponentInstanceOutput(String comptInstanceId) {
+ return this.safeGetComponentInstanceEntity(comptInstanceId, this.componentInstancesOutputs);
+ }
+
public List<ComponentInstanceInterface> safeGetComponentInstanceInterfaces(String cmptInstacneId) {
return this.safeGetComponentInstanceEntity(cmptInstacneId, this.componentInstancesInterfaces);
}
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 09e02337a1..cf1b23ec88 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
@@ -1517,6 +1517,27 @@ public class ToscaOperationFacade {
return Either.right(status);
}
+ public Either<List<OutputDefinition>, StorageOperationStatus> updateOutputsToComponent(List<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();
+ List<AttributeDataDefinition> outputsAsDataDef = outputs.stream().map(AttributeDataDefinition::new).collect(Collectors.toList());
+ StorageOperationStatus status = topologyTemplateOperation
+ .updateToscaDataOfToscaElement(vertex, EdgeLabelEnum.OUTPUTS, VertexTypeEnum.OUTPUTS, outputsAsDataDef, JsonPresentationFields.NAME);
+ if (StorageOperationStatus.OK == status) {
+ log.debug(COMPONENT_CREATED_SUCCESSFULLY);
+ List<OutputDefinition> outputsResList = null;
+ if (!outputsAsDataDef.isEmpty()) {
+ outputsResList = outputsAsDataDef.stream().map(OutputDefinition::new).collect(Collectors.toList());
+ }
+ return Either.left(outputsResList);
+ }
+ return Either.right(status);
+ }
+
// region - ComponentInstance
public Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> associateComponentInstancePropertiesToComponent(
Map<String, List<ComponentInstanceProperty>> instProperties, String componentId) {
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 ee78821b23..7e99418221 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
@@ -140,4 +140,26 @@ public class AttributeDataDefinition extends ToscaDataDefinition {
public String getParentUniqueId() {
return getOwnerId();
}
+
+ public boolean isGetOutputAttribute() {
+ return this.getGetOutputValues() != null && !this.getGetOutputValues().isEmpty();
+ }
+
+ public boolean typeEquals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ AttributeDataDefinition other = (AttributeDataDefinition) obj;
+ if (this.getType() == null) {
+ return other.getType() == null;
+ }
+ return false;
+ }
+
}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/utils/AttributeDefinitionUtils.java b/common-be/src/main/java/org/openecomp/sdc/be/utils/AttributeDefinitionUtils.java
new file mode 100644
index 0000000000..00836e787b
--- /dev/null
+++ b/common-be/src/main/java/org/openecomp/sdc/be/utils/AttributeDefinitionUtils.java
@@ -0,0 +1,42 @@
+/*
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2022 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.utils;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class AttributeDefinitionUtils {
+
+ public static List<AttributeDataDefinition> getAttributesMappedToOutputs(List<AttributeDataDefinition> attributes) {
+ if (attributes == null) {
+ return Collections.emptyList();
+ }
+ return filterGetOutputAttributes(attributes);
+ }
+
+ private static <T extends AttributeDataDefinition> List<AttributeDataDefinition> filterGetOutputAttributes(List<T> attributeDefinitions) {
+ return attributeDefinitions.stream().filter(AttributeDataDefinition::isGetOutputAttribute).collect(Collectors.toList());
+ }
+}