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 /catalog-be/src/main/java/org | |
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
Diffstat (limited to 'catalog-be/src/main/java/org')
26 files changed, 2122 insertions, 494 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 { |