From da6b4a245482f4eebade8f487fc9d63f456469ab Mon Sep 17 00:00:00 2001 From: JvD_Ericsson Date: Thu, 21 Sep 2023 11:41:34 +0100 Subject: [PATCH] Fix bugs in attribute outputs page * Attributes being added to the template for each output declared if the attribute is a property and has a value * Unable to set a default value on a property from Output page * Fix issues with the save button * infinite save pop up when trying to leave the page with changes and clicking save * parse error in the console that would make the save button remain enabled after save was succesful * output values not being removed from attribute after output is deleted * nested attribute values not being updated Issue-ID: SDC-4632 Signed-off-by: JvD_Ericsson Change-Id: I08abd6cd96963b09be7941c3a91559e241ace24f --- .../ComponentInstanceAttributeDeclarator.java | 22 ++++++++++--- .../impl/ComponentInstanceBusinessLogic.java | 32 ++++++++++++++++--- .../be/components/impl/OutputsBusinessLogic.java | 12 +++++--- .../impl/ServiceImportBusinessLogic.java | 36 ++++++++++++++++++++++ .../openecomp/sdc/be/tosca/AttributeConverter.java | 3 +- catalog-ui/src/app/models/attributes.ts | 2 -- .../attributes-table.component.html | 2 +- .../dynamic-attribute.component.html | 2 +- .../attributes-outputs.page.component.ts | 2 ++ 9 files changed, 94 insertions(+), 19 deletions(-) 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 index 4c75624ec1..4fb8bb73f3 100644 --- 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 @@ -17,6 +17,7 @@ * limitations under the License. * ============LICENSE_END========================================================= */ + package org.openecomp.sdc.be.components.attribute; import fj.data.Either; @@ -27,6 +28,7 @@ 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.datatypes.elements.GetOutputValueDataDefinition; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.ComponentInstanceAttribute; @@ -70,13 +72,25 @@ public class ComponentInstanceAttributeDeclarator extends DefaultAttributeDeclar @Override public StorageOperationStatus unDeclareAttributesAsOutputs(final Component component, final OutputDefinition output) { - final List componentInstancePropertiesDeclaredAsInput = componentInstanceBusinessLogic + final List componentInstanceAttributesDeclaredAsOutput = componentInstanceBusinessLogic .getComponentInstanceAttributesByOutputId(component, output.getUniqueId()); - if (CollectionUtils.isEmpty(componentInstancePropertiesDeclaredAsInput)) { + if (CollectionUtils.isEmpty(componentInstanceAttributesDeclaredAsOutput)) { return StorageOperationStatus.OK; } + unDeclareOutput(output, componentInstanceAttributesDeclaredAsOutput); return toscaOperationFacade - .updateComponentInstanceAttributes(component, componentInstancePropertiesDeclaredAsInput.get(0).getComponentInstanceId(), - componentInstancePropertiesDeclaredAsInput); + .updateComponentInstanceAttributes(component, componentInstanceAttributesDeclaredAsOutput.get(0).getComponentInstanceId(), + componentInstanceAttributesDeclaredAsOutput); + } + + private void unDeclareOutput(OutputDefinition output, + List componentInstanceAttributesDeclaredAsOutput) { + componentInstanceAttributesDeclaredAsOutput.forEach(attribute -> { + Optional attributeOutput = + attribute.getGetOutputValues().stream().filter(attOut -> output.getUniqueId().equals(attOut.getOutputId())).findFirst(); + if (attributeOutput.isPresent()) { + attribute.getGetOutputValues().remove(attributeOutput.get()); + } + }); } } 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 ff98163b69..ddbc5dc041 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 @@ -2248,14 +2248,35 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { private ComponentInstanceAttribute validateAttributeExistsOnComponent(final ComponentInstanceAttribute attribute, final Component containerComponent, final ComponentInstance foundResourceInstance) { - final List instanceProperties = + final List instanceAttributes = containerComponent.getComponentInstancesAttributes().get(foundResourceInstance.getUniqueId()); + final List instanceProperties = + containerComponent.getComponentInstancesProperties().get(foundResourceInstance.getUniqueId()); final Optional instanceAttribute = + instanceAttributes.stream().filter(p -> p.getName().equals(attribute.getName())).findAny(); + final Optional instanceProperty = instanceProperties.stream().filter(p -> p.getName().equals(attribute.getName())).findAny(); - if (!instanceAttribute.isPresent()) { - throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, attribute.getName()); + if (instanceAttribute.isPresent()) { + return instanceAttribute.get(); + } + if (instanceProperty.isPresent()) { + ComponentInstanceAttribute propAttribute = getComponentInstanceAttribute(instanceProperty.get()); + return propAttribute; } - return instanceAttribute.get(); + throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, attribute.getName()); + } + + private ComponentInstanceAttribute getComponentInstanceAttribute(ComponentInstanceProperty property) { + ComponentInstanceAttribute attribute = new ComponentInstanceAttribute(); + attribute.setParentUniqueId(property.getParentUniqueId()); + attribute.setName(property.getName()); + attribute.setOwnerId(property.getOwnerId()); + attribute.setType(property.getType()); + attribute.setSchema(property.getSchema()); + attribute.setUniqueId(property.getUniqueId()); + attribute.setValue(property.getValue()); + attribute.setDefaultValue(property.getDefaultValue()); + return attribute; } private ResponseFormat updateCapabilityPropertyOnContainerComponent(ComponentInstanceProperty property, @@ -3051,7 +3072,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } Component eitherOriginComponent = getInstanceOriginNode(currentResourceInstance); - DataForMergeHolder dataHolder = compInstMergeDataBL.saveAllDataBeforeDeleting(containerComponent, currentResourceInstance, eitherOriginComponent); + DataForMergeHolder dataHolder = + compInstMergeDataBL.saveAllDataBeforeDeleting(containerComponent, currentResourceInstance, eitherOriginComponent); ComponentInstance resResourceInfo = deleteComponentInstance(containerComponent, componentInstanceId, containerComponentType); 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 603270ec0a..c38b3d8f99 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 @@ -136,7 +136,8 @@ public class OutputsBusinessLogic extends BaseBusinessLogic { component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp); ImmutablePair status = validateOutputName(component, componentInstOutputsMapUi); if (status.getLeft() != StorageOperationStatus.OK) { - throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.OUTPUT_NAME_ALREADY_EXIST, status.getRight())); + throw new ByResponseFormatComponentException( + componentsUtils.getResponseFormat(ActionStatus.OUTPUT_NAME_ALREADY_EXIST, status.getRight())); } result = attributeDeclarationOrchestrator.declareAttributesToOutputs(component, componentInstOutputsMapUi) .left().bind(outputsToCreate -> prepareOutputsForCreation(userId, componentId, outputsToCreate)) @@ -164,7 +165,7 @@ public class OutputsBusinessLogic extends BaseBusinessLogic { } private ImmutablePair validateOutputName(final Component component, - final ComponentInstOutputsMap componentInstOutputsMapUi) { + final ComponentInstOutputsMap componentInstOutputsMapUi) { final Map> outputDeclaredProperties = new HashMap<>(); if (MapUtils.isNotEmpty(componentInstOutputsMapUi.getComponentInstanceOutputsMap())) { outputDeclaredProperties.putAll(componentInstOutputsMapUi.getComponentInstanceOutputsMap()); @@ -300,7 +301,8 @@ public class OutputsBusinessLogic extends BaseBusinessLogic { final var optionalComponentInstance = component.getComponentInstanceByName(getAttribute.get(0)); if (optionalComponentInstance.isPresent()) { final var createdOutputs - = createOutputs(component.getUniqueId(), userId, getAttribute.get(1), optionalComponentInstance.get(),outputDefinitionValue.getName()); + = createOutputs(component.getUniqueId(), userId, getAttribute.get(1), optionalComponentInstance.get(), + outputDefinitionValue.getName()); if (createdOutputs.isRight()) { return Either.right((createdOutputs.right().value())); } @@ -328,7 +330,7 @@ public class OutputsBusinessLogic extends BaseBusinessLogic { if (componentInstanceAttributeOptional.isPresent()) { final var componentInstOutputsMap = new ComponentInstOutputsMap(); componentInstOutputsMap.setComponentInstanceAttributes(Collections.singletonMap(componentInstance.getUniqueId(), - Collections.singletonList(new ComponentInstanceAttribOutput(componentInstanceAttributeOptional.get(),outputName)))); + Collections.singletonList(new ComponentInstanceAttribOutput(componentInstanceAttributeOptional.get(), outputName)))); return createMultipleOutputs(userId, componentUniqueId, ComponentTypeEnum.SERVICE, componentInstOutputsMap, true, false); } @@ -342,7 +344,7 @@ public class OutputsBusinessLogic extends BaseBusinessLogic { final ComponentInstOutputsMap componentInstOutputsMap = new ComponentInstOutputsMap(); ComponentInstanceAttribOutput attribute = getComponentInstanceAttribOutput(propertyDefinition); componentInstOutputsMap.setComponentInstanceAttributes(Collections.singletonMap(componentInstance.getUniqueId(), - Collections.singletonList(new ComponentInstanceAttribOutput(attribute,outputName)))); + Collections.singletonList(new ComponentInstanceAttribOutput(attribute, outputName)))); return createMultipleOutputs(userId, componentUniqueId, ComponentTypeEnum.SERVICE, componentInstOutputsMap, true, false); } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java index 316c940ac4..7dadbee790 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java @@ -2157,6 +2157,7 @@ public class ServiceImportBusinessLogic { if (originResource.getAttributes() != null && !originResource.getAttributes().isEmpty()) { instAttributes.put(resourceInstanceId, originResource.getAttributes()); addAttributeValueToResourceInstance(instAttributes, uploadComponentInstanceInfo.getAttributes()); + instAttributes.get(resourceInstanceId).addAll(addImplicitAttributeValues(originResource, uploadComponentInstanceInfo)); } if (uploadComponentInstanceInfo.getUploadNodeFilterInfo() == null) { instNodeFilter.put(resourceInstanceId, new UploadNodeFilterInfo()); @@ -2187,6 +2188,41 @@ public class ServiceImportBusinessLogic { } } + private List addImplicitAttributeValues(Resource originResource, UploadComponentInstanceInfo uploadComponentInstanceInfo) { + List origAttributes = originResource.getAttributes().stream().map(AttributeDefinition::getName).collect(toList()); + Map uploadAttributes = uploadComponentInstanceInfo.getAttributes(); + List newAttributesToAdd = + uploadAttributes.keySet().stream().filter(newAttribute -> !origAttributes.contains(newAttribute)) + .collect(toList()); + List propsToAddAsAttributes = + originResource.getProperties().stream().filter(prop -> newAttributesToAdd.contains(prop.getName())).collect(toList()); + propsToAddAsAttributes.stream().forEach(prop -> { + Object value = uploadAttributes.get(prop.getName()).getValue(); + if (value instanceof Collection || value instanceof Map) { + Gson gson = new Gson(); + String json = gson.toJson(value); + prop.setValue(json); + } else { + prop.setValue(String.valueOf(value)); + } + }); + List attributesToAdd = new ArrayList<>(); + for (PropertyDefinition prop: propsToAddAsAttributes) { + attributesToAdd.add(getPropertyAsAttribute(prop)); + } + return attributesToAdd; + } + + private AttributeDefinition getPropertyAsAttribute(PropertyDefinition property) { + AttributeDefinition attribute = new AttributeDefinition(); + attribute.setName(property.getName()); + attribute.setType(property.getType()); + attribute.setSchema(property.getSchema()); + attribute.setValue(property.getValue()); + attribute.setDefaultValue(property.getDefaultValue()); + return attribute; + } + protected void addInputsValuesToRi(UploadComponentInstanceInfo uploadComponentInstanceInfo, Component component, Resource originResource, ComponentInstance currentCompInstance, Map> instInputs, Map allDataTypes) { 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 index 4a98fa99f4..143fb7b34b 100644 --- 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 @@ -16,6 +16,7 @@ * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ + package org.openecomp.sdc.be.tosca; import com.google.gson.JsonElement; @@ -183,7 +184,7 @@ public class AttributeConverter { public void convertAndAddValue(final Map attribs, final AttributeDefinition attribute) { final Object convertedValue = convertToToscaObject(attribute, attribute.getValue(), false); - if (!ToscaValueBaseConverter.isEmptyObjectValue(convertedValue)) { + if (!ToscaValueBaseConverter.isEmptyObjectValue(convertedValue) && !attribute.isGetOutputAttribute()) { attribs.put(attribute.getName(), convertedValue); } } diff --git a/catalog-ui/src/app/models/attributes.ts b/catalog-ui/src/app/models/attributes.ts index 711e5b3c49..3bbbd1eb74 100644 --- a/catalog-ui/src/app/models/attributes.ts +++ b/catalog-ui/src/app/models/attributes.ts @@ -105,8 +105,6 @@ export class AttributeModel extends AttributeBEModel implements IAttributeModel // forcing creating new object, so editing different one than the object in the table this.schema = new SchemaAttributeGroupModel(new SchemaAttribute(this.schema.property)); } - - this.convertValueToView(); } public convertToServerObject(): string { diff --git a/catalog-ui/src/app/ng2/components/logic/attributes-table/attributes-table.component.html b/catalog-ui/src/app/ng2/components/logic/attributes-table/attributes-table.component.html index e9360421a6..a6ce2884ca 100644 --- a/catalog-ui/src/app/ng2/components/logic/attributes-table/attributes-table.component.html +++ b/catalog-ui/src/app/ng2/components/logic/attributes-table/attributes-table.component.html @@ -84,7 +84,7 @@ [attributeNameSearchText]="attributeNameSearchText" [readonly]="readonly" (attributeChanged)="onAttributeChanged(property)" - (expandChild)="property.updateExpandedChildPropertyId($event)" + (expandChild)="property.updateExpandedChildAttributeId($event)" (clickOnAttributeRow)="onClickAttributeInnerRow($event, instanceId)" (checkAttribute)="attributeChecked(property, $event)" > diff --git a/catalog-ui/src/app/ng2/components/logic/attributes-table/dynamic-attribute/dynamic-attribute.component.html b/catalog-ui/src/app/ng2/components/logic/attributes-table/dynamic-attribute/dynamic-attribute.component.html index 7f271af4e1..f5de4aac2c 100644 --- a/catalog-ui/src/app/ng2/components/logic/attributes-table/dynamic-attribute/dynamic-attribute.component.html +++ b/catalog-ui/src/app/ng2/components/logic/attributes-table/dynamic-attribute/dynamic-attribute.component.html @@ -89,7 +89,7 @@ [attributeNameSearchText]="attributeNameSearchText" [readonly]="readonly" [hasChildren]="getHasChildren(prop)" - (propertyChanged)="childValueChanged(prop)" + (attributeChanged)="childValueChanged(prop)" (mapKeyChanged)="updateChildKeyInParent(prop, $event)" (expandChild)="expandChildById($event)" (deleteItem)="deleteListOrMapItem($event)" diff --git a/catalog-ui/src/app/ng2/pages/attributes-outputs/attributes-outputs.page.component.ts b/catalog-ui/src/app/ng2/pages/attributes-outputs/attributes-outputs.page.component.ts index 48700f2ecb..6dc8abfa4d 100644 --- a/catalog-ui/src/app/ng2/pages/attributes-outputs/attributes-outputs.page.component.ts +++ b/catalog-ui/src/app/ng2/pages/attributes-outputs/attributes-outputs.page.component.ts @@ -655,6 +655,8 @@ export class AttributesOutputsComponent { if (this.isAttributesTabSelected) { this.checkedAttributesCount = 0; } + this.hasChangedData = false; + this.isValidChangedData = false; }, () => { this.Notification.error({ -- 2.16.6