From 2e6a7eb218ad07a19fd1cc09b94e1f6a82e05360 Mon Sep 17 00:00:00 2001 From: "Sindhuri.A" Date: Fri, 7 Sep 2018 13:53:56 +0530 Subject: Single node copy paste keyboard shorcut on canvas Keyboard Shortcut copy paste for single node on Composition page canvas for services Issue-ID: SDC-1736 Change-Id: I669a728d3641a59ba7a4d8cc18fdae1000a0377f Signed-off-by: Sindhuri.A --- .../impl/ComponentInstanceBusinessLogic.java | 515 ++++++++++++++++++--- .../sdc/be/servlets/ComponentInstanceServlet.java | 44 ++ .../main/resources/config/error-configuration.yaml | 6 + .../impl/ComponentInstanceBusinessLogicTest.java | 222 ++++++++- .../be/servlets/ComponentInstanceServletTest.java | 38 ++ 5 files changed, 753 insertions(+), 72 deletions(-) (limited to 'catalog-be/src') 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 35493f715c..04d543c10b 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 @@ -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. @@ -36,43 +36,45 @@ import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; -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.GroupDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; import org.openecomp.sdc.be.impl.ForwardingPathUtils; import org.openecomp.sdc.be.info.CreateAndAssotiateInfo; -import org.openecomp.sdc.be.model.ArtifactDefinition; -import org.openecomp.sdc.be.model.CapabilityDefinition; import org.openecomp.sdc.be.model.Component; -import org.openecomp.sdc.be.model.ComponentInstance; -import org.openecomp.sdc.be.model.ComponentInstanceInput; -import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.CapabilityDefinition; +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.ComponentInstancePropInput; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.GroupDefinition; import org.openecomp.sdc.be.model.InputDefinition; -import org.openecomp.sdc.be.model.LifecycleStateEnum; -import org.openecomp.sdc.be.model.PropertyDefinition; -import org.openecomp.sdc.be.model.PropertyDefinition.PropertyNames; import org.openecomp.sdc.be.model.RelationshipInfo; import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; -import org.openecomp.sdc.be.model.RequirementDefinition; -import org.openecomp.sdc.be.model.Resource; -import org.openecomp.sdc.be.model.Service; -import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.PropertyDefinition.PropertyNames; import org.openecomp.sdc.be.model.jsontitan.operations.ForwardingPathOperation; import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade; import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter; import org.openecomp.sdc.be.model.operations.api.IComponentInstanceOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; import org.openecomp.sdc.be.resources.data.ComponentInstanceData; @@ -132,11 +134,11 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { @Autowired private ForwardingPathOperation forwardingPathOperation; - public ComponentInstanceBusinessLogic() { } - public Either createComponentInstance(String containerComponentParam, String containerComponentId, String userId, ComponentInstance resourceInstance) { + public Either createComponentInstance( + String containerComponentParam, String containerComponentId, String userId, ComponentInstance resourceInstance) { return createComponentInstance(containerComponentParam, containerComponentId, userId, resourceInstance, false, true); } @@ -171,7 +173,6 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { }); } return resList; - } public List getComponentInstanceInputsByInputId(org.openecomp.sdc.be.model.Component component, String inputId){ @@ -205,10 +206,10 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { }); } return resList; - } - public Either createComponentInstance(String containerComponentParam, String containerComponentId, String userId, ComponentInstance resourceInstance, boolean inTransaction, boolean needLock) { + public Either createComponentInstance( + String containerComponentParam, String containerComponentId, String userId, ComponentInstance resourceInstance, boolean inTransaction, boolean needLock) { Component origComponent = null; Either resultOp = null; @@ -462,15 +463,15 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { return resultOp; } -/** - * addResourceInstanceArtifacts - add artifacts (HEAT_ENV) to resource instance The instance artifacts are generated from the resource's artifacts - * @param containerComponent - * @param componentInstance - * @param originComponent - * @param user - * @param existingEnvVersions - * @return - */ + /** + * addResourceInstanceArtifacts - add artifacts (HEAT_ENV) to resource instance The instance artifacts are generated from the resource's artifacts + * @param containerComponent + * @param componentInstance + * @param originComponent + * @param user + * @param existingEnvVersions + * @return + */ protected Either addComponentInstanceArtifacts(org.openecomp.sdc.be.model.Component containerComponent, ComponentInstance componentInstance, org.openecomp.sdc.be.model.Component originComponent, User user, Map existingEnvVersions) { log.debug("add artifacts to resource instance"); @@ -584,7 +585,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } public Either updateComponentInstanceMetadata(String containerComponentParam, String containerComponentId, String componentInstanceId, String userId, ComponentInstance componentInstance, boolean inTransaction, - boolean needLock, boolean createNewTransaction) { + boolean needLock, boolean createNewTransaction) { validateUserExists(userId, "update Component Instance", inTransaction); @@ -682,7 +683,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { boolean validateParent = validateParent(containerComponent, componentInstance.getUniqueId()); if (!validateParent) { resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstance.getName(), instanceType.getValue().toLowerCase(), containerComponentType.getValue().toLowerCase(), - containerComponentId)); + containerComponentId)); return resultOp; } } @@ -761,7 +762,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } private Either updateComponentInstanceMetadata(Component containerComponent, ComponentTypeEnum containerComponentType, org.openecomp.sdc.be.model.Component origComponent, String componentInstanceId, - ComponentInstance componentInstance) { + ComponentInstance componentInstance) { Either resultOp = null; Optional componentInstanceOptional = null; @@ -881,7 +882,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { return resultOp; } Either deleteEither = deleteForwardingPathsRelatedTobeDeletedComponentInstance(containerComponentId, - containerComponentType, resultOp); + containerComponentType, resultOp); if (deleteEither.isRight()){ return deleteEither; } @@ -893,7 +894,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } public Either deleteForwardingPathsRelatedTobeDeletedComponentInstance(String containerComponentId, ComponentTypeEnum containerComponentType, - Either resultOp) { + Either resultOp) { if(containerComponentType.equals(ComponentTypeEnum.SERVICE) && resultOp.isLeft() ){ final ComponentInstance componentInstance = resultOp.left().value(); List pathIDsToBeDeleted = getForwardingPathsRelatedToComponentInstance(containerComponentId, componentInstance.getName()); @@ -917,7 +918,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { return Either.right(componentsUtils.getResponseFormat(storageStatus.right().value())); } Either, StorageOperationStatus> result = forwardingPathOperation.deleteForwardingPath(storageStatus.left().value(), - Sets.newHashSet(pathIdsToDelete)); + Sets.newHashSet(pathIdsToDelete)); if(result.isRight()) { return Either.right(componentsUtils.getResponseFormat(result.right().value())); @@ -944,7 +945,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { return pathDataDefinition.getPathElements().getListToscaDataDefinition() .stream().anyMatch(elementDataDefinition -> elementDataDefinition.getFromNode().equalsIgnoreCase(componentInstanceId) || elementDataDefinition.getToNode() - .equalsIgnoreCase(componentInstanceId)); + .equalsIgnoreCase(componentInstanceId)); } @@ -1021,7 +1022,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } public Either associateRIToRI(String componentId, String userId, RequirementCapabilityRelDef requirementDef, ComponentTypeEnum componentTypeEnum, boolean inTransaction, boolean needLock, - boolean createNewTransaction) { + boolean createNewTransaction) { validateUserExists(userId, "associate Ri To RI", inTransaction); @@ -1240,8 +1241,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { private boolean isBelongingRequirement(RelationshipInfo relationshipInfo, RequirementDataDefinition req) { return req.getName().equals(relationshipInfo.getRequirement()) && - req.getUniqueId().equals(relationshipInfo.getRequirementUid()) && - req.getOwnerId().equals(relationshipInfo.getRequirementOwnerId()); + req.getUniqueId().equals(relationshipInfo.getRequirementUid()) && + req.getOwnerId().equals(relationshipInfo.getRequirementOwnerId()); } private Either setRelatedCapability(RequirementCapabilityRelDef foundRelation, Component containerComponent) { @@ -1688,7 +1689,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } public Either createOrUpdateGroupInstancePropertyValue(ComponentTypeEnum componentTypeEnum, String componentId, String resourceInstanceId, String groupInstanceId, ComponentInstanceProperty property, - String userId) { + String userId) { Either resultOp = null; @@ -1955,33 +1956,33 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { return eitherResponse; } - public Either, ResponseFormat> forwardingPathOnVersionChange(String containerComponentParam, - String containerComponentId, - String componentInstanceId, - ComponentInstance newComponentInstance) { + public Either, ResponseFormat> forwardingPathOnVersionChange(String containerComponentParam, + String containerComponentId, + String componentInstanceId, + ComponentInstance newComponentInstance) { Either, ResponseFormat> resultOp; Either validateComponentType = validateComponentType(containerComponentParam); if (validateComponentType.isRight()) { - return Either.right(validateComponentType.right().value()); + return Either.right(validateComponentType.right().value()); } final ComponentTypeEnum containerComponentType = validateComponentType.left().value(); ComponentParametersView componentParametersView = getComponentParametersViewForForwardingPath(); //Fetch Component Either validateComponentExists = - validateComponentExists(containerComponentId, containerComponentType, componentParametersView); + validateComponentExists(containerComponentId, containerComponentType, componentParametersView); if (validateComponentExists.isRight()) { - return Either.right(validateComponentExists.right().value()); + return Either.right(validateComponentExists.right().value()); } Component containerComponent = validateComponentExists.left().value(); //Fetch current component instance Either eitherResourceInstance = - getResourceInstanceById(containerComponent, componentInstanceId); + getResourceInstanceById(containerComponent, componentInstanceId); if (eitherResourceInstance.isRight()) { - resultOp = Either.right(componentsUtils.getResponseFormat( - ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceId, containerComponentId)); - return resultOp; + resultOp = Either.right(componentsUtils.getResponseFormat( + ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceId, containerComponentId)); + return resultOp; } ComponentInstance currentResourceInstance = eitherResourceInstance.left().value(); @@ -1989,29 +1990,29 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { String resourceId = newComponentInstance.getComponentUid(); Either componentExistsRes = toscaOperationFacade.validateComponentExists(resourceId); if (componentExistsRes.isRight()) { - log.debug("Failed to find resource ", resourceId); - resultOp = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse - (componentExistsRes.right().value()), resourceId)); - return resultOp; + log.debug("Failed to find resource ", resourceId); + resultOp = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse + (componentExistsRes.right().value()), resourceId)); + return resultOp; } else if (!componentExistsRes.left().value()) { - log.debug("The resource {} not found ", resourceId); - resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceId)); - return resultOp; + log.debug("The resource {} not found ", resourceId); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceId)); + return resultOp; } //Fetch component using new component instance uid Either eitherResourceName = getOriginComponentFromComponentInstance(newComponentInstance); if (eitherResourceName.isRight()) { - resultOp = Either.right(eitherResourceName.right().value()); - return resultOp; + resultOp = Either.right(eitherResourceName.right().value()); + return resultOp; } Component updatedContainerComponent=eitherResourceName.left().value(); Set toDeleteForwardingPaths = getForwardingPaths(containerComponent, - currentResourceInstance, updatedContainerComponent); + currentResourceInstance, updatedContainerComponent); resultOp=Either.left(toDeleteForwardingPaths); return resultOp; - } + } private Set getForwardingPaths(Component containerComponent, ComponentInstance currentResourceInstance, Component updatedContainerComponent) { @@ -2022,7 +2023,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { ForwardingPathUtils forwardingPathUtils = new ForwardingPathUtils(); return forwardingPathUtils. - getForwardingPathsToBeDeletedOnVersionChange(service,dataForMergeHolder,updatedContainerComponent); + getForwardingPathsToBeDeletedOnVersionChange(service,dataForMergeHolder,updatedContainerComponent); } private ComponentParametersView getComponentParametersViewForForwardingPath() { @@ -2499,7 +2500,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { Component containerComponent = getResourceResult.left().value(); if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) { - log.info("Restricted operation for user: {} on component {}", userId, containerComponentId); + log.info("Restricted operation for user: {sourcePropList} on component {}", userId, containerComponentId); return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); } Either resourceInstanceStatus = getResourceInstanceById(containerComponent, componentInstanceUniqueId); @@ -2525,8 +2526,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { for (ComponentInstanceProperty property : properties) { Either newPropertyValueEither = updatePropertyObjectValue(property, false); newPropertyValueEither.bimap(updatedValue -> - updateCapabilityPropertyOnContainerComponent(property,updatedValue, containerComponent, foundResourceInstance, capabilityType, capabilityName, ownerId), - responseFormat -> Either.right(responseFormat)); + updateCapabilityPropertyOnContainerComponent(property,updatedValue, containerComponent, foundResourceInstance, capabilityType, capabilityName, ownerId), + responseFormat -> Either.right(responseFormat)); } Either updateContainerRes = toscaOperationFacade.updateComponentInstanceMetadataOfTopologyTemplate(containerComponent); @@ -2550,7 +2551,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } public Either, ResponseFormat> updateInstanceCapabilityProperties(ComponentTypeEnum componentTypeEnum, String containerComponentId, String componentInstanceUniqueId, String capabilityType, String capabilityName, - List properties, String userId) { + List properties, String userId) { Either, ResponseFormat> resultOp = null; validateUserExists(userId, "update instance capability property", false); @@ -2610,4 +2611,382 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { graphLockOperation.unlockComponent(containerComponentId, componentTypeEnum.getNodeType()); } } + + public Either, ResponseFormat> copyComponentInstance(ComponentInstance inputComponentInstance, + String containerComponentId, + String componentInstanceId, + String userId) { + + Map resultMap = new HashMap<>(); + Either getOrigComponent = toscaOperationFacade.getToscaElement(containerComponentId); + if (getOrigComponent.isRight()) { + log.error("Failed to get the original component information"); + return Either.right(componentsUtils.getResponseFormat( + ActionStatus.USER_DEFINED, "Failed to copy the component instance to the canvas")); + } + + Component origComponent = getOrigComponent.left().value(); + + Either lockComponent = lockComponent(origComponent, "copyComponentInstance"); + if (lockComponent.isRight()) { + log.error("destComponentInstance's data is {}", origComponent.toString()); + return Either.right(lockComponent.right().value()); + } + + + Either actionResponse = null; + try { + actionResponse = createComponentInstance( + "services", containerComponentId, userId, inputComponentInstance, true, false); + + + } + finally { + + // on failure of the create instance unlock the resource and rollback the transaction. + if (null== actionResponse || actionResponse.isRight()) { + titanDao.rollback(); + log.error("Failed to copy the component instance to the canvas"); + + unlockComponent(actionResponse, origComponent); + + return Either.right(componentsUtils.getResponseFormat( + ActionStatus.USER_DEFINED, "Failed to copy the component instance to the canvas")); + } + + } + + Either resultOp = null; + + try { + ComponentInstance destComponentInstance = actionResponse.left().value(); + log.debug("destComponentInstance's data is {}", destComponentInstance.toString()); + + + resultOp = deepCopyComponentInstance( + origComponent, containerComponentId, componentInstanceId, destComponentInstance, userId); + + resultMap.put("componentInstance", destComponentInstance); + } + finally{ + // unlock resource + unlockComponent(resultOp, origComponent); + + if (resultOp == null || resultOp.isRight()) { + titanDao.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 { + titanDao.commit(); + log.debug("Success trasaction commit"); + } + } + + return Either.left(resultMap); + } + + private Either deepCopyComponentInstance( + Component sourceComponent, String containerComponentId, String sourceComponentInstanceId, + ComponentInstance destComponentInstance, String userId) { + + Either 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")); + } + + Component destComponent = getDestComponent.left().value(); + + Either copyComponentInstanceWithPropertiesAndInputs = copyComponentInstanceWithPropertiesAndInputs( + sourceComponent, destComponent, sourceComponentInstanceId, destComponentInstance, userId); + if (copyComponentInstanceWithPropertiesAndInputs.isRight()) { + log.error("Failed to copy component instance with properties and inputs as part of deep copy"); + return Either.right(componentsUtils.getResponseFormat( + ActionStatus.USER_DEFINED, "Failed to copy the component instance with properties and inputs as part of deep copy")); + } + + Either copyComponentInstanceWithAttributes = copyComponentInstanceWithAttributes( + sourceComponent, destComponent, sourceComponentInstanceId, destComponentInstance, userId); + if (copyComponentInstanceWithAttributes.isRight()) { + log.error("Failed to copy component instance with attributes as part of deep copy"); + return Either.right(componentsUtils.getResponseFormat( + ActionStatus.USER_DEFINED, "Failed to copy the component instance with attributes as part of deep copy")); + } + return Either.left("Copy component Instance OK"); + } + + private Either copyComponentInstanceWithPropertiesAndInputs( + Component sourceComponent, Component destComponent, String sourceComponentInstanceId, + ComponentInstance destComponentInstance, String userId) { + log.debug("start to copy ComponentInstance with properties and inputs"); + + List sourcePropList = null; + if (sourceComponent.getComponentInstancesProperties() != null + && sourceComponent.getComponentInstancesProperties().get(sourceComponentInstanceId) != null) { + sourcePropList = sourceComponent.getComponentInstancesProperties().get(sourceComponentInstanceId); + log.debug("sourcePropList"); + } + + List destPropList = null; + String destComponentInstanceId = destComponentInstance.getUniqueId(); + log.debug("destComponentInstanceId: {}", destComponentInstance.getUniqueId()); + if (destComponent.getComponentInstancesProperties() != null + && destComponent.getComponentInstancesProperties().get(destComponentInstanceId) != null) { + destPropList = destComponent.getComponentInstancesProperties().get(destComponentInstanceId); + log.debug("destPropList {}"); + } + + List componentInstancePropInputList = new ArrayList<>(); + + if (null != destPropList && null != sourcePropList) { + log.debug("start to set property and attribute"); + for (ComponentInstanceProperty destProp : destPropList) { + String destPropertyName = destProp.getName(); + for (ComponentInstanceProperty sourceProp : sourcePropList) { + if (!destPropertyName.equals(sourceProp.getName())) { + continue; + } + log.debug("now set property"); + if (sourceProp.getGetInputValues() == 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 updatePropertyValueEither = updateComponentInstanceProperty( + 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")); + } + break; + } + + log.debug("Now start to update inputs"); + + if (sourceProp.getGetInputValues() != null) { + if (sourceProp.getGetInputValues().size() < 1) { + log.debug("property is return from input, set by man"); + break; + } + log.debug("Now starting to copy the {} property", destPropertyName); + + Either getSourceInputDefaultValue = getInputListDefaultValue( + sourceComponent, sourceProp.getGetInputValues().get(0).getInputId()); + if (getSourceInputDefaultValue.isRight()) { + return Either.right(getSourceInputDefaultValue.right().value()); + } + componentInstancePropInputList.add(new ComponentInstancePropInput(destProp)); + } + } + } + } + return Either.left("Copy component Instance OK"); + } + + private Either copyComponentInstanceWithAttributes(Component sourceComponent, + Component destComponent, + String sourceComponentInstanceId, + ComponentInstance destComponentInstance, + String userId) { + String destComponentInstanceId = destComponentInstance.getUniqueId(); + + log.info("start to copy component instance with attributes"); + + List sourceAttributeList = null; + if (sourceComponent.getComponentInstancesAttributes() != null + && sourceComponent.getComponentInstancesAttributes().get(sourceComponentInstanceId) != null) { + sourceAttributeList = sourceComponent.getComponentInstancesAttributes().get(sourceComponentInstanceId); + log.info("sourceAttributes {}"); + } + + List destAttributeList = null; + if (destComponent.getComponentInstancesAttributes() != null + && destComponent.getComponentInstancesAttributes().get(destComponentInstanceId) != null) { + destAttributeList = destComponent.getComponentInstancesAttributes().get(destComponentInstanceId); + log.info("destAttributeList {}"); + } + if (null != sourceAttributeList && null != destAttributeList) { + log.info("set attribute"); + + for (ComponentInstanceProperty sourceAttribute : sourceAttributeList) { + String sourceAttributeName = sourceAttribute.getName(); + for (ComponentInstanceProperty destAttribute : destAttributeList) { + if (sourceAttributeName.equals(destAttribute.getName())) { + if (sourceAttribute.getValue() != null && !sourceAttribute.getValue().isEmpty()) { + log.debug("Start to copy the attribute exists {}", sourceAttributeName); + + sourceAttribute.setUniqueId( + UniqueIdBuilder.buildResourceInstanceUniuqeId( + "attribute" , destComponentInstanceId.split("\\.")[1] , sourceAttributeName)); + + Either updateAttributeValueEither = + createOrUpdateAttributeValueForCopyPaste(ComponentTypeEnum.SERVICE, + destComponent.getUniqueId(), destComponentInstanceId, sourceAttribute, + userId); + if (updateAttributeValueEither.isRight()) { + log.error("Failed to copy the attribute"); + return Either.right(componentsUtils + .getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, + "Failed to paste component instance to the canvas, attribute copy")); + } + break; + } + } + } + } + } + + return Either.left("Copy component Instance OK"); + } + + private Either createOrUpdateAttributeValueForCopyPaste(ComponentTypeEnum componentTypeEnum, + String componentId, + String resourceInstanceId, + ComponentInstanceProperty attribute, + String userId) { + + Either resultOp = null; + + validateUserExists(userId, "Create or Update attribute value", false); + + if (componentTypeEnum == null) { + BeEcompErrorManager.getInstance().logInvalidInputError( + "createOrUpdateAttributeValue", "invalid component type", ErrorSeverity.INFO); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED)); + return resultOp; + } + + Either getResourceResult = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll); + + if (getResourceResult.isRight()) { + log.info("Failed to retrieve component id {}", componentId); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + return resultOp; + } + + Component containerComponent = getResourceResult.left().value(); + + Either resourceInstanceStatus = getResourceInstanceById(containerComponent, resourceInstanceId); + + if (resourceInstanceStatus.isRight()) { + resultOp = Either.right(componentsUtils.getResponseFormat( + ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, resourceInstanceId, componentId)); + return resultOp; + } + + ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value(); + + + String propertyType = attribute.getType(); + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + log.info("The type of attribute id{},is {} ", attribute.getUniqueId(), propertyType); + + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + SchemaDefinition def = attribute.getSchema(); + if (def == null) { + log.info("Schema doesn't exists for attribute of type {}", type); + return Either.right(componentsUtils.getResponseFormat( + componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE))); + } + PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + log.info("Attribute in Schema Definition inside attribute of type {} doesn't exist", type); + return Either.right(componentsUtils.getResponseFormat( + componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE))); + } + } + + List instanceAttributes = containerComponent. + getComponentInstancesAttributes().get(resourceInstanceId); + Optional instanceAttribute = + instanceAttributes.stream().filter(p -> p.getUniqueId().equals(attribute.getUniqueId())).findAny(); + StorageOperationStatus status; + + if (instanceAttribute.isPresent()) { + log.info("updateComponentInstanceAttribute"); + status = toscaOperationFacade.updateComponentInstanceAttribute(containerComponent, foundResourceInstance.getUniqueId(), attribute); + } else { + log.info("addComponentInstanceAttribute"); + status = toscaOperationFacade.addComponentInstanceAttribute(containerComponent, foundResourceInstance.getUniqueId(), attribute); + } + if (status != StorageOperationStatus.OK) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status); + resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "")); + return resultOp; + } + List path = new ArrayList<>(); + path.add(foundResourceInstance.getUniqueId()); + attribute.setPath(path); + + foundResourceInstance.setCustomizationUUID(UUID.randomUUID().toString()); + Either updateContainerRes = toscaOperationFacade. + updateComponentInstanceMetadataOfTopologyTemplate(containerComponent); + + if (updateContainerRes.isRight()) { + ActionStatus actionStatus = componentsUtils. + convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value()); + resultOp = Either.right(componentsUtils. + getResponseFormatForResourceInstanceProperty(actionStatus, "")); + return resultOp; + } + resultOp = Either.left(attribute); + return resultOp; + + + + } + + private Either updateComponentInstanceProperty(String containerComponentId, + String componentInstanceId, + ComponentInstanceProperty property) { + Either resultOp; + Either getComponent = toscaOperationFacade.getToscaElement(containerComponentId); + + if (getComponent.isRight()) { + log.error("Failed to get the component information"); + return Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty( + ActionStatus.INVALID_CONTENT_PARAM, "Failed to get the component information")); + } + + Component containerComponent = getComponent.left().value(); + + StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceProperty( + containerComponent, componentInstanceId, property); + if (status != StorageOperationStatus.OK) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status); + resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "")); + return resultOp; + } + + Either updateContainerRes = toscaOperationFacade. + updateComponentInstanceMetadataOfTopologyTemplate(containerComponent); + + if (updateContainerRes.isRight()) { + ActionStatus actionStatus = componentsUtils. + convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value()); + resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "")); + return resultOp; + } + + return Either.left("Update OK"); + } + + private Either getInputListDefaultValue(Component component, String inputId) { + List inputList = component.getInputs(); + for (InputDefinition input : inputList) { + if (input.getUniqueId().equals(inputId)) { + if (input.getDefaultValue() == null) { + log.debug("The input's default value is null"); + return Either.left(null); + } + return Either.left(input.getDefaultValue()); + } + } + log.error("The input's default value with id {} is not found", inputId); + return Either.right(componentsUtils.getResponseFormat( + ActionStatus.USER_DEFINED, "Failed to paste component instance to the canvas")); + } } 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 dec12d770f..3195727a68 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 @@ -58,6 +58,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; +import java.util.Map; /** * Root resource (exposed at "/" path) .json @@ -1205,4 +1206,47 @@ public class ComponentInstanceServlet extends AbstractValidationsServlet { } + @POST + @Path("/services/{componentId}/copyComponentInstance/{componentInstanceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces((MediaType.APPLICATION_JSON)) + @ApiOperation(value = "Copy Component Instance", httpMethod = "POST", notes = "Returns updated service information", response = Service.class) + @ApiResponses(value = { + @ApiResponse(code = 201, message = "Copy and Paste Success"), + @ApiResponse(code = 403, message = "Restricted Operation"), + @ApiResponse(code = 400, message = "Invalid Content / Missing content")}) + public Response copyComponentInstance( + @ApiParam(value = "service unique id in pasted canvas") @PathParam("componentId") final String containerComponentId, + @ApiParam(value = "Data for copying", required = true) String data, @PathParam("componentInstanceId") final String componentInstanceId, + @Context final HttpServletRequest request) { + log.info("Start to copy component instance"); + ServletContext context = request.getSession().getServletContext(); + String userId = request.getHeader(Constants.USER_ID_HEADER); + final String CNTAINER_CMPT_TYPE = "services"; + + try { + ComponentInstance inputComponentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class); + inputComponentInstance.setInvariantName(null); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(CNTAINER_CMPT_TYPE); + ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context); + if (componentInstanceLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, componentTypeEnum); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, "services")); + } + Either, ResponseFormat> copyComponentInstance = componentInstanceLogic.copyComponentInstance( + inputComponentInstance, containerComponentId, componentInstanceId, userId); + + if (copyComponentInstance.isRight()) { + log.error("Failed to copy ComponentInstance {}", copyComponentInstance.right().value()); + return buildErrorResponse(copyComponentInstance.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + copyComponentInstance.left().value()); + } catch (Exception e) { + log.error("Failed to convert json to Map { }, error: { }", data, e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.USER_DEFINED, + "Failed to get the copied component instance information")); + } + } } diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml index 6156090df3..aa000f14a7 100644 --- a/catalog-be/src/main/resources/config/error-configuration.yaml +++ b/catalog-be/src/main/resources/config/error-configuration.yaml @@ -105,6 +105,12 @@ errors: message: "Error: Invalid userId '%1'.", messageId: "SVC4008" } +#---------SVC4009----------------------------- + USER_DEFINED: { + code: 400, + message: "Error: User Defined '%1'.", + messageId: "SVC4009" + } #---------SVC4049------------------------------ # %1 - service/resource COMPONENT_MISSING_CONTACT: { diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java index 1a6483009d..929bb97281 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java @@ -1,6 +1,5 @@ package org.openecomp.sdc.be.components.impl; -import static org.junit.Assert.assertSame; import static org.assertj.core.api.Assertions.assertThat; import fj.data.Either; @@ -16,14 +15,18 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; import org.openecomp.sdc.be.components.validation.UserValidations; import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.jsongraph.TitanDao; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; import org.openecomp.sdc.be.datatypes.elements.*; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.ServletUtils; import org.openecomp.sdc.be.info.CreateAndAssotiateInfo; @@ -32,19 +35,22 @@ import org.openecomp.sdc.be.model.LifecycleStateEnum; import org.openecomp.sdc.be.model.jsontitan.operations.ForwardingPathOperation; import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.GraphLockOperation; import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; import org.openecomp.sdc.exception.ResponseFormat; import java.util.function.BiPredicate; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anySet; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; -import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.when; @@ -86,6 +92,13 @@ public class ComponentInstanceBusinessLogicTest { private User user; @Mock private UserValidations userValidations; + @Mock + private TitanDao titanDao; + @Mock + private ArtifactsBusinessLogic artifactBusinessLogic; + @Mock + private GraphLockOperation graphLockOperation; + private Component service; private Component resource; private ComponentInstance toInstance; @@ -158,8 +171,8 @@ public class ComponentInstanceBusinessLogicTest { Either, ResponseFormat> resultOp = componentInstanceBusinessLogic.forwardingPathOnVersionChange (containerComponentParam,containerComponentID,componentInstanceID,newComponentInstance); - Assert.assertEquals(1,resultOp.left().value().size()); - Assert.assertEquals("FP-ID-1",resultOp.left().value().iterator().next()); + assertEquals(1,resultOp.left().value().size()); + assertEquals("FP-ID-1",resultOp.left().value().iterator().next()); } @@ -1067,4 +1080,205 @@ public class ComponentInstanceBusinessLogicTest { when(toscaOperationFacade.getToscaFullElement(containerComponentId)).thenReturn(Either.left(resource)); result=testSubject.updateInstanceCapabilityProperties(componentTypeEnum, containerComponentId, componentInstanceUniqueId, capabilityType, capabilityName, properties, userId); } + + @Test + public void testCopyComponentInstanceWrongUserId() { + + Either, ResponseFormat> result; + ComponentInstance inputComponentInstance = createComponetInstanceFromComponent(resource); + String containerComponentId = service.getUniqueId(); + String componentInstanceId = resource.getUniqueId(); + String oldLastUpdatedUserId = service.getLastUpdaterUserId(); + service.setLastUpdaterUserId("wrong user id"); + + Either leftServiceOp = Either.left(service); + when(toscaOperationFacade.getToscaElement(containerComponentId)).thenReturn(leftServiceOp); + when(toscaOperationFacade.getToscaElement(eq(containerComponentId), any(ComponentParametersView.class))) + .thenReturn(leftServiceOp); + when(titanDao.rollback()).thenReturn(TitanOperationStatus.OK); + when(graphLockOperation.unlockComponent(Mockito.anyString(), eq(NodeTypeEnum.Service))) + .thenReturn(StorageOperationStatus.OK); + when(graphLockOperation.lockComponent(Mockito.anyString(), eq(NodeTypeEnum.Service))) + .thenReturn(StorageOperationStatus.OK); + + result = componentInstanceBusinessLogic + .copyComponentInstance(inputComponentInstance, containerComponentId, componentInstanceId, USER_ID); + + service.setLastUpdaterUserId(oldLastUpdatedUserId); + + assertThat(result.isRight()); + } + + @Test + public void testCopyComponentInstanceComponentWrongState() { + Either, ResponseFormat> result; + ComponentInstance inputComponentInstance = createComponetInstanceFromComponent(resource); + String containerComponentId = service.getUniqueId(); + String componentInstanceId = resource.getUniqueId(); + String oldServiceLastUpdatedUserId = service.getLastUpdaterUserId(); + service.setLastUpdaterUserId(USER_ID); + + Either leftServiceOp = Either.left(service); + when(toscaOperationFacade.getToscaElement(containerComponentId)).thenReturn(leftServiceOp); + when(toscaOperationFacade.getToscaElement(eq(containerComponentId), any(ComponentParametersView.class))) + .thenReturn(leftServiceOp); + when(titanDao.rollback()).thenReturn(TitanOperationStatus.OK); + when(graphLockOperation.unlockComponent(Mockito.anyString(), eq(NodeTypeEnum.Service))) + .thenReturn(StorageOperationStatus.OK); + when(graphLockOperation.lockComponent(Mockito.anyString(), eq(NodeTypeEnum.Service))) + .thenReturn(StorageOperationStatus.OK); + Either getComponentRes = Either.left(resource); + when(toscaOperationFacade.getToscaFullElement(inputComponentInstance.getComponentUid())) + .thenReturn(getComponentRes); + + result = componentInstanceBusinessLogic + .copyComponentInstance(inputComponentInstance, containerComponentId, componentInstanceId, USER_ID); + + service.setLastUpdaterUserId(oldServiceLastUpdatedUserId); + + assertThat(result.isRight()); + } + + @Test + public void testCopyComponentInstance() { + Either, ResponseFormat> result; + ComponentInstance inputComponentInstance = createComponetInstanceFromComponent(resource); + String containerComponentId = service.getUniqueId(); + String componentInstanceId = resource.getUniqueId(); + String oldServiceLastUpdatedUserId = service.getLastUpdaterUserId(); + service.setLastUpdaterUserId(USER_ID); + LifecycleStateEnum oldResourceLifeCycle = resource.getLifecycleState(); + resource.setLifecycleState(LifecycleStateEnum.CERTIFIED); + + Either leftServiceOp = Either.left(service); + when(toscaOperationFacade.getToscaElement(containerComponentId)).thenReturn(leftServiceOp); + when(toscaOperationFacade.getToscaElement(eq(containerComponentId), any(ComponentParametersView.class))) + .thenReturn(leftServiceOp); + when(graphLockOperation.unlockComponent(Mockito.anyString(), eq(NodeTypeEnum.Service))) + .thenReturn(StorageOperationStatus.OK); + when(graphLockOperation.lockComponent(Mockito.anyString(), eq(NodeTypeEnum.Service))) + .thenReturn(StorageOperationStatus.OK); + Either getComponentRes = Either.left(resource); + when(toscaOperationFacade.getToscaFullElement(inputComponentInstance.getComponentUid())) + .thenReturn(getComponentRes); + ImmutablePair pair = new ImmutablePair<>(resource, TO_INSTANCE_ID); + Either, StorageOperationStatus> result2 = Either.left(pair); + when(toscaOperationFacade + .addComponentInstanceToTopologyTemplate(eq(service), eq(resource), eq(inputComponentInstance), eq(false), + isNull(User.class))).thenReturn(result2); + Either, StorageOperationStatus> getResourceDeploymentArtifacts = Either + .left(new HashMap()); + when(artifactBusinessLogic.getArtifacts(eq(inputComponentInstance.getComponentUid()), eq(NodeTypeEnum.Resource), + eq(ArtifactGroupTypeEnum.DEPLOYMENT), isNull(String.class))).thenReturn(getResourceDeploymentArtifacts); + StorageOperationStatus artStatus = StorageOperationStatus.OK; + when(toscaOperationFacade + .addInformationalArtifactsToInstance(eq(resource.getUniqueId()), eq(inputComponentInstance), + isNull(Map.class))).thenReturn(artStatus); + + result = componentInstanceBusinessLogic + .copyComponentInstance(inputComponentInstance, containerComponentId, componentInstanceId, USER_ID); + + service.setLastUpdaterUserId(oldServiceLastUpdatedUserId); + resource.setLifecycleState(oldResourceLifeCycle); + + assertThat(result.isLeft()); + } + + @Test + public void testCreateOrUpdateAttributeValueForCopyPaste() { + ComponentInstance serviceComponentInstance = createComponetInstanceFromComponent(service); + ComponentInstanceProperty attribute = new ComponentInstanceProperty(); + attribute.setType("string"); + attribute.setUniqueId("testCreateOrUpdateAttributeValueForCopyPaste"); + SchemaDefinition def = Mockito.mock(SchemaDefinition.class); + attribute.setSchema(def); + LifecycleStateEnum oldLifeCycleState = service.getLifecycleState(); + String oldLastUpdatedUserId = service.getLastUpdaterUserId(); + service.setLastUpdaterUserId(USER_ID); + service.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + + Map> instAttrsMap = new HashMap>(); + List instAttrsList = new ArrayList(); + ComponentInstanceProperty prop = new ComponentInstanceProperty(); + prop.setUniqueId(attribute.getUniqueId()); + instAttrsList.add(prop); + instAttrsMap.put(toInstance.getUniqueId(), instAttrsList); + service.setComponentInstancesAttributes(instAttrsMap); + + Either serviceEitherLeft = Either.left(service); + when(toscaOperationFacade.getToscaElement(serviceComponentInstance.getUniqueId(), JsonParseFlagEnum.ParseAll)).thenReturn(serviceEitherLeft); + when(toscaOperationFacade.updateComponentInstanceAttribute(service, toInstance.getUniqueId(), attribute)).thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacade.updateComponentInstanceMetadataOfTopologyTemplate(service)).thenReturn(serviceEitherLeft); + + Either result = Deencapsulation.invoke(componentInstanceBusinessLogic, "createOrUpdateAttributeValueForCopyPaste", ComponentTypeEnum.SERVICE, + serviceComponentInstance.getUniqueId(), + toInstance.getUniqueId(), + attribute, + USER_ID); + + service.setLastUpdaterUserId(oldLastUpdatedUserId); + service.setLifecycleState(oldLifeCycleState); + + assertTrue(result.isLeft()); + ComponentInstanceProperty resultProp = result.left().value(); + assertEquals(resultProp.getPath().size(), 1); + assertEquals(resultProp.getPath().get(0), toInstance.getUniqueId()); + } + + @Test + public void testUpdateComponentInstanceProperty() { + + String containerComponentId = service.getUniqueId(); + String componentInstanceId = "dummy_id"; + ComponentInstanceProperty property = Mockito.mock(ComponentInstanceProperty.class); + + Either getComponent = Either.left(service); + when(toscaOperationFacade.getToscaElement(containerComponentId)).thenReturn(getComponent); + StorageOperationStatus status = StorageOperationStatus.OK; + when(toscaOperationFacade.updateComponentInstanceProperty(service, componentInstanceId, property)) + .thenReturn(status); + Either updateContainerRes = Either.left(service); + when(toscaOperationFacade.updateComponentInstanceMetadataOfTopologyTemplate(service)) + .thenReturn(updateContainerRes); + + Either result = Deencapsulation + .invoke(componentInstanceBusinessLogic, "updateComponentInstanceProperty", containerComponentId, + componentInstanceId, property); + + assertTrue(result.isLeft()); + } + + @Test + public void testGetInputListDefaultValue() { + Component component = service; + String inputId = "dummy_id"; + String defaultValue = "dummy_default_value"; + List newInputs = new ArrayList(); + InputDefinition in = new InputDefinition(); + in.setUniqueId(inputId); + in.setDefaultValue(defaultValue); + newInputs.add(in); + List oldInputs = service.getInputs(); + service.setInputs(newInputs); + + Either result = Deencapsulation + .invoke(componentInstanceBusinessLogic, "getInputListDefaultValue", component, inputId); + + service.setInputs(oldInputs); + + assertEquals(result.left().value(), defaultValue); + } + + private ComponentInstance createComponetInstanceFromComponent(Component component) { + ComponentInstance componentInst = new ComponentInstance(); + componentInst.setUniqueId(component.getUniqueId()); + componentInst.setComponentUid(component.getUniqueId() + "_test"); + componentInst.setPosX("10"); + componentInst.setPosY("10"); + componentInst.setCapabilities(component.getCapabilities()); + componentInst.setRequirements(component.getRequirements()); + componentInst.setArtifacts(component.getArtifacts()); + componentInst.setDeploymentArtifacts(component.getDeploymentArtifacts()); + return componentInst; + } } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentInstanceServletTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentInstanceServletTest.java index 0c91b49fee..d8e7896d71 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentInstanceServletTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentInstanceServletTest.java @@ -1,6 +1,10 @@ package org.openecomp.sdc.be.servlets; import fj.data.Either; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.ws.rs.client.Entity; import org.eclipse.jetty.http.HttpStatus; import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.server.ResourceConfig; @@ -16,7 +20,10 @@ import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.ServletUtils; import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.exception.ResponseFormat; import org.springframework.context.ApplicationContext; @@ -31,6 +38,7 @@ import javax.ws.rs.core.Response; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @@ -94,6 +102,36 @@ public class ComponentInstanceServletTest extends JerseyTest { assertEquals(response.getStatus(), HttpStatus.BAD_REQUEST_400); } + @Test + public void testCopyComponentInstanceSuccess(){ + + String componentId = "componentId"; + String componentInstanceId = "componentInstanceId"; + String path = "/v1/catalog/services/" + componentId + "/copyComponentInstance/" + componentInstanceId; + + Either, ResponseFormat> successResponse = Either.left(new HashMap()); + when(componentInstanceBusinessLogic.copyComponentInstance(any(ComponentInstance.class), eq(componentId), eq(componentInstanceId), eq(USER_ID))).thenReturn(successResponse); + when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200); + when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat); + + ComponentInstance c = new ComponentInstance(); + c.setName("comp1"); + c.setUniqueId("comp1"); + c.setComponentUid("comp1"); + c.setPosX("10"); + c.setPosY("10"); + c.setCapabilities(new HashMap>()); + c.setRequirements(new HashMap>()); + + Response response = target() + .path(path) + .request(MediaType.APPLICATION_JSON) + .header("USER_ID", USER_ID) + .post(Entity.json(c)); + + assertEquals(response.getStatus(), HttpStatus.OK_200); + } + @Override protected ResourceConfig configure() { forceSet(TestProperties.CONTAINER_PORT, "0"); -- cgit 1.2.3-korg