From eaa3a10b650c44e7eaabf94ed48c94031c5d4a1e Mon Sep 17 00:00:00 2001 From: "katy.rotman" Date: Sun, 29 Apr 2018 14:56:55 +0300 Subject: Fix for fail submit service&recommit change 44091 Issue-ID: SDC-1267 Change-Id: I3439e8f4df8c17c3d3635e804473212f1a9aaf34 Signed-off-by: katy.rotman --- .../csar/CsarArtifactsAndGroupsBusinessLogic.java | 16 +- .../be/components/impl/ArtifactResolverImpl.java | 27 +- .../be/components/impl/ArtifactsBusinessLogic.java | 316 +++++++++++++++++---- .../impl/InterfaceOperationBusinessLogic.java | 62 ++-- .../validation/InterfaceOperationValidation.java | 21 +- .../datamodel/utils/InterfaceUIDataConverter.java | 8 +- .../servlet/ArtifactExternalServlet.java | 82 ++++++ .../org/openecomp/sdc/be/impl/ComponentsUtils.java | 21 +- .../ResourceInterfaceOperationServlet.java | 1 - .../java/org/openecomp/sdc/be/tosca/CsarUtils.java | 238 ++++++++++------ .../sdc/be/tosca/utils/OperationArtifactUtil.java | 41 +++ .../main/resources/config/error-configuration.yaml | 18 +- .../be/components/InterfaceOperationTestUtils.java | 7 +- .../components/impl/ArtifactBusinessLogicTest.java | 4 +- .../be/components/impl/ArtifactResolverTest.java | 24 ++ .../impl/InterfaceOperationBusinessLogicTest.java | 19 +- .../InterfaceOperationValidationTest.java | 13 + .../be/tosca/utils/OperationArtifactUtilTest.java | 61 ++++ .../org/openecomp/sdc/be/dao/api/ActionStatus.java | 6 +- .../jsontitan/operations/ArtifactsOperations.java | 55 +++- .../elements/InterfaceOperationDataDefinition.java | 13 +- 21 files changed, 854 insertions(+), 199 deletions(-) create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/OperationArtifactUtil.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/OperationArtifactUtilTest.java diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarArtifactsAndGroupsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarArtifactsAndGroupsBusinessLogic.java index 0ee2dabf08..8c6b7dd3fb 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarArtifactsAndGroupsBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarArtifactsAndGroupsBusinessLogic.java @@ -25,7 +25,17 @@ import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.info.ArtifactTemplateInfo; import org.openecomp.sdc.be.info.MergedArtifactInfo; -import org.openecomp.sdc.be.model.*; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.CsarInfo; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.GroupProperty; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.heat.HeatParameterType; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; @@ -797,7 +807,7 @@ public class CsarArtifactsAndGroupsBusinessLogic extends BaseBusinessLogic { if (op.isPresent()) { ArtifactDefinition artifactInfoHeatEnv = op.get(); Either updateArifactOnResource = artifactToscaOperation - .updateArifactOnResource(artifactInfoHeatEnv, updatedResource.getUniqueId(), + .updateArtifactOnResource(artifactInfoHeatEnv, updatedResource.getUniqueId(), artifactInfoHeatEnv.getUniqueId(), null, null); if (updateArifactOnResource.isRight()) { log.debug("Failed to update heat env on CSAR flow for component {} artifact {} label {}", @@ -868,7 +878,7 @@ public class CsarArtifactsAndGroupsBusinessLogic extends BaseBusinessLogic { } currentInfo.setListHeatParameters(currentHeatEnvParams); Either updateArifactOnResource = artifactToscaOperation - .updateArifactOnResource(currentInfo, resource.getUniqueId(), currentInfo.getUniqueId(), + .updateArtifactOnResource(currentInfo, resource.getUniqueId(), currentInfo.getUniqueId(), null, null); if (updateArifactOnResource.isRight()) { log.debug( diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactResolverImpl.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactResolverImpl.java index fcaf5cdfc6..e79efbcfc1 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactResolverImpl.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactResolverImpl.java @@ -20,16 +20,24 @@ package org.openecomp.sdc.be.components.impl; -import java.util.*; - +import org.apache.commons.collections.MapUtils; import org.openecomp.sdc.be.components.ArtifactsResolver; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.model.ArtifactDefinition; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.Service; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + @org.springframework.stereotype.Component("artifact-resolver") public class ArtifactResolverImpl implements ArtifactsResolver { @@ -55,11 +63,22 @@ public class ArtifactResolverImpl implements ArtifactsResolver { private List getAllComponentsArtifacts(Component component, ComponentTypeEnum componentType) { Map deploymentArtifacts = Optional.ofNullable(component.getDeploymentArtifacts()).orElse(Collections.emptyMap()); Map artifacts = Optional.ofNullable(component.getArtifacts()).orElse(Collections.emptyMap()); + Map interfaceArtifacts= Collections.emptyMap(); + if (componentType == ComponentTypeEnum.RESOURCE) { + Map interfaces = ((Resource) component).getInterfaces(); + if (MapUtils.isNotEmpty(interfaces)) { + interfaceArtifacts = interfaces.values().stream() + .flatMap(inte -> inte.getOperationsMap().values().stream()) + .map(operation -> operation.getImplementationArtifact()) + .collect(Collectors.toMap(artifactDefinition -> artifactDefinition.getUniqueId(), artifactDefinition -> artifactDefinition)); + } + } + Map serviceApiArtifacts = Collections.emptyMap(); if (componentType.equals(ComponentTypeEnum.SERVICE)) { serviceApiArtifacts = Optional.ofNullable(((Service) component).getServiceApiArtifacts()).orElse(Collections.emptyMap()); } - return appendAllArtifacts(deploymentArtifacts, artifacts, serviceApiArtifacts); + return appendAllArtifacts(deploymentArtifacts, artifacts, interfaceArtifacts, serviceApiArtifacts); } private List getAllInstanceArtifacts(ComponentInstance instance) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java index 39ad806cda..c9250ae70f 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java @@ -29,6 +29,7 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; +import org.elasticsearch.common.Strings; import org.openecomp.sdc.be.components.ArtifactsResolver; import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaTagNamesEnum; @@ -50,9 +51,25 @@ import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; import org.openecomp.sdc.be.info.ArtifactTemplateInfo; -import org.openecomp.sdc.be.model.*; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.GroupInstance; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Operation; +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.heat.HeatParameterType; +import org.openecomp.sdc.be.model.jsontitan.operations.InterfaceOperation; import org.openecomp.sdc.be.model.jsontitan.operations.NodeTemplateOperation; +import org.openecomp.sdc.be.model.jsontitan.utils.InterfaceUtils; import org.openecomp.sdc.be.model.operations.api.IElementOperation; import org.openecomp.sdc.be.model.operations.api.IHeatParametersOperation; import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation; @@ -175,6 +192,9 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { @Autowired private ArtifactsResolver artifactsResolver; + @Autowired + private InterfaceOperation interfaceOperation; + public enum ArtifactOperationEnum { CREATE, UPDATE, DELETE, DOWNLOAD, LINK; @@ -211,12 +231,12 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { // new flow US556184 public Either, ResponseFormat> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType, ArtifactOperationInfo operation, String artifactId, ArtifactDefinition artifactInfo, - String origMd5, String originData, String interfaceName, String operationName, String parentId, String containerComponentType) { - return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName, operationName, parentId, containerComponentType, true, false); + String origMd5, String originData, String interfaceUuid, String operationUuid, String parentId, String containerComponentType) { + return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceUuid, operationUuid, parentId, containerComponentType, true, false); } public Either, ResponseFormat> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType, ArtifactOperationInfo operation, String artifactId, ArtifactDefinition artifactInfo, - String origMd5, String originData, String interfaceName, String operationName, String parentId, String containerComponentType, boolean shouldLock, boolean inTransaction) { + String origMd5, String originData, String interfaceUuid, String operationUuid, String parentId, String containerComponentType, boolean shouldLock, boolean inTransaction) { // step 1 - detect auditing type AuditingActionEnum auditingAction = detectAuditingType(operation, origMd5); @@ -257,7 +277,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { } // step 8 - return validateAndHandleArtifact(componentId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName, operationName, user, component, + return validateAndHandleArtifact(componentId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceUuid, operationUuid, user, component, shouldLock, inTransaction, true); } @@ -269,7 +289,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { * @return */ public Either, ResponseFormat> validateAndHandleArtifact(String componentUniqueId, ComponentTypeEnum componentType, ArtifactOperationInfo operation, String artifactUniqueId, - ArtifactDefinition artifactDefinition, String origMd5, String originData, String interfaceName, String operationName, User user, Component component, boolean shouldLock, boolean inTransaction, boolean needUpdateGroup) { + ArtifactDefinition artifactDefinition, String origMd5, String originData, String interfaceUuid, String operationName, User user, Component component, boolean shouldLock, boolean inTransaction, boolean needUpdateGroup) { Component parent = component; Wrapper errorWrapper = new Wrapper<>(); @@ -279,7 +299,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { Either, ResponseFormat> result; if (errorWrapper.isEmpty()) { // step 10 - result = doAction(componentUniqueId, componentType, operation, artifactUniqueId, artifactDefinition, origMd5, originData, interfaceName, operationName, auditingAction, user, parent, shouldLock, inTransaction, needUpdateGroup); + result = doAction(componentUniqueId, componentType, operation, artifactUniqueId, artifactDefinition, origMd5, originData, interfaceUuid, operationName, auditingAction, user, parent, shouldLock, inTransaction, needUpdateGroup); } else { result = Either.right(errorWrapper.getInnerElement()); @@ -398,10 +418,10 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { private Either, ResponseFormat> doAction(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation, String artifactId, ArtifactDefinition artifactInfo, String origMd5, String originData, String interfaceName, String operationName, AuditingActionEnum auditingAction, User user, org.openecomp.sdc.be.model.Component parent, boolean shouldLock, boolean inTransaction, boolean needUpdateGroup) { - if (interfaceName != null && operationName != null) { + /*if (interfaceName != null && operationName != null) { interfaceName = interfaceName.toLowerCase(); operationName = operationName.toLowerCase(); - } + }*/ switch (operation.getArtifactOperationEnum()) { case DOWNLOAD: if (artifactGenerationRequired(parent, artifactInfo)) { @@ -1413,7 +1433,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { CassandraOperationStatus cassandraStatus = artifactCassandraDao.deleteArtifact(esId); if (cassandraStatus != CassandraOperationStatus.OK) { log.debug("Failed to delete the artifact {} from the database. ", artifactId); - responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(convertToStorageOperationStatus(cassandraStatus)), foundArtifact + responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(componentsUtils.convertToStorageOperationStatus(cassandraStatus)), foundArtifact .getArtifactDisplayName()); handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, responseFormat, componentType, null); resultOp = Either.right(responseFormat); @@ -1676,26 +1696,6 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { } } - private StorageOperationStatus convertToStorageOperationStatus(CassandraOperationStatus cassandraStatus) { - StorageOperationStatus result; - switch (cassandraStatus) { - case OK: - result = StorageOperationStatus.OK; - break; - case NOT_FOUND: - result = StorageOperationStatus.NOT_FOUND; - break; - case CLUSTER_NOT_CONNECTED: - case KEYSPACE_NOT_CONNECTED: - result = StorageOperationStatus.CONNECTION_FAILURE; - break; - default: - result = StorageOperationStatus.GENERAL_ERROR; - break; - } - return result; - } - private void resetMandatoryArtifactFields(ArtifactDefinition fetchedArtifact) { if (fetchedArtifact != null) { log.debug("Going to reset mandatory artifact {} fields. ", fetchedArtifact.getUniqueId()); @@ -2569,7 +2569,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { } private Either validateArtifactType(String userId, ArtifactDefinition artifactInfo, NodeTypeEnum parentType) { - if (artifactInfo.getArtifactType() == null || artifactInfo.getArtifactType().isEmpty()) { + if (Strings.isNullOrEmpty(artifactInfo.getArtifactType())) { BeEcompErrorManager.getInstance() .logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel"); log.debug("Missing artifact type for artifact {}", artifactInfo.getArtifactName()); @@ -2896,7 +2896,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { } private Either, ResponseFormat> updateArtifactFlow(org.openecomp.sdc.be.model.Component parent, String parentId, String artifactId, ArtifactDefinition artifactInfo, User user, byte[] decodedPayload, - ComponentTypeEnum componentType, AuditingActionEnum auditingAction, String interfaceType, String operationName) { + ComponentTypeEnum componentType, AuditingActionEnum auditingAction, String interfaceType, String operationUuid) { ESArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload); String prevArtifactId = null; String currArtifactId = artifactId; @@ -2904,28 +2904,19 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { Either, ResponseFormat> resultOp = null; Either insideEither = null; - if (artifactData == null) { - BeEcompErrorManager.getInstance().logBeDaoSystemError("Update Artifact"); - log.debug("Failed to create artifact object for ES."); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); - handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); - resultOp = Either.right(responseFormat); - return resultOp; - } log.trace("Try to update entry on graph"); String artifactUniqueId = null; ArtifactDefinition artifactDefinition = artifactInfo; StorageOperationStatus error; boolean isLeft; - if (!(interfaceType != null && operationName != null)) { - log.debug("Enty on graph is updated. Update artifact in ES"); + if (interfaceType == null || operationUuid == null) { + log.debug("Entity on graph is updated. Update artifact in ES"); boolean res = true; // Changing previous and current artifactId for auditing prevArtifactId = currArtifactId; currArtifactId = artifactDefinition.getUniqueId(); - NodeTypeEnum convertParentType = convertParentType(componentType); if (decodedPayload == null) { if (!artifactDefinition.getMandatory() || artifactDefinition.getEsId() != null) { @@ -2934,7 +2925,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { if (artifactFromCassandra.isRight()) { log.debug("Failed to get artifact data from ES for artifact id {}", artifactId); error = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactFromCassandra.right() - .value()); + .value()); ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(error)); handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); resultOp = Either.right(responseFormat); @@ -2944,15 +2935,15 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { artifactData.setData(artifactFromCassandra.left().value().getData()); artifactData.setId(artifactFromCassandra.left().value().getId()); } - } - else { + } else { if (artifactDefinition.getEsId() == null) { artifactDefinition.setEsId(artifactDefinition.getUniqueId()); artifactData.setId(artifactDefinition.getUniqueId()); } } - Either result = artifactToscaOperation.updateArifactOnResource(artifactInfo, parent + NodeTypeEnum convertParentType = convertParentType(componentType); + Either result = artifactToscaOperation.updateArtifactOnResource(artifactInfo, parent .getUniqueId(), artifactId, convertParentType, parentId); isLeft = result.isLeft(); if (isLeft) { @@ -2967,13 +2958,13 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { // need to update the generated id in heat env Map deploymentArtifacts = parent.getDeploymentArtifacts(); Optional> findFirst = deploymentArtifacts.entrySet() - .stream() - .filter(a -> a.getValue() - .getGeneratedFromId() != null && a - .getValue() - .getGeneratedFromId() - .equals(artifactId)) - .findFirst(); + .stream() + .filter(a -> a.getValue() + .getGeneratedFromId() != null && a + .getValue() + .getGeneratedFromId() + .equals(artifactId)) + .findFirst(); if (findFirst.isPresent()) { ArtifactDefinition artifactEnvInfo = findFirst.get().getValue(); artifactEnvInfo.setArtifactChecksum(null); @@ -2988,8 +2979,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { isLeft = false; } - } - else { + } else { error = result.right().value(); } if (isLeft) { @@ -3009,19 +2999,129 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { log.debug("Artifact saved into ES - {}", artifactUniqueId); ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); - } - else { + } else { BeEcompErrorManager.getInstance().logBeDaoSystemError("Update Artifact"); log.debug("Failed to save the artifact."); ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); resultOp = Either.right(responseFormat); } + } else { + return updateArtifactsFlowForInterfaceOperations(parent, parentId, artifactId, artifactInfo, user, + decodedPayload, componentType, auditingAction, operationUuid, artifactData, prevArtifactId, + currArtifactId, artifactDefinition); } return resultOp; } + private Either, ResponseFormat> updateArtifactsFlowForInterfaceOperations( + Component parent, String parentId, String artifactId, ArtifactDefinition artifactInfo, User user, + byte[] decodedPayload, ComponentTypeEnum componentType, AuditingActionEnum auditingAction, + String operationUuid, ESArtifactData artifactData, String prevArtifactId, String currArtifactId, + ArtifactDefinition artifactDefinition) { + StorageOperationStatus error; + Either, ResponseFormat> resultOp; + if (decodedPayload == null) { + if (!artifactDefinition.getMandatory() || artifactDefinition.getEsId() != null) { + Either artifactFromCassandra = artifactCassandraDao.getArtifact(artifactDefinition + .getEsId()); + if (artifactFromCassandra.isRight()) { + log.debug("Failed to get artifact data from ES for artifact id {}", artifactId); + error = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactFromCassandra.right() + .value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(error)); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); + resultOp = Either.right(responseFormat); + return resultOp; + } + // clone data to new artifact + artifactData.setData(artifactFromCassandra.left().value().getData()); + artifactData.setId(artifactFromCassandra.left().value().getId()); + } else { + // todo if not exist(first time) + } + + } else { + if (artifactDefinition.getEsId() == null) { + artifactDefinition.setEsId(artifactDefinition.getUniqueId()); + artifactData.setId(artifactDefinition.getUniqueId()); + } + } + NodeTypeEnum convertParentType = convertParentType(componentType); + // fetch the resource from storage + Either resourceStorageOperationStatusEither = + toscaOperationFacade.getToscaElement(parentId); + if (resourceStorageOperationStatusEither.isRight()) { + StorageOperationStatus errorStatus = resourceStorageOperationStatusEither.right().value(); + log.debug("Failed to fetch resource information by resource id, error {}", errorStatus); + return Either.right(componentsUtils + .getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus))); + } + Resource storedResource = resourceStorageOperationStatusEither.left().value(); + + String interfaceToscaName = InterfaceUtils.createInterfaceToscaResourceName( + storedResource.getName()); + //fetch the interface from storage + Optional interfaceDefinition = storedResource.getInterfaces().values() + .stream() + .filter(interfaceDef -> interfaceDef.getToscaResourceName() + .equals(interfaceToscaName)) + .findFirst(); + if (!interfaceDefinition.isPresent()) { + log.debug("Failed to get resource interface for resource Id {}", parentId); + ResponseFormat responseFormat = componentsUtils.getResponseFormat( + ActionStatus.INTERFACE_OPERATION_NOT_FOUND, parentId); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, + currArtifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + + //fetch the operation from storage + InterfaceDefinition gotInterface = interfaceDefinition.get(); + Map operationsMap = gotInterface.getOperationsMap(); + Optional optionalOperation = operationsMap.values() + .stream() + .filter(o -> o.getUniqueId().equals(operationUuid)) + .findFirst(); + if (!optionalOperation.isPresent()) { + log.debug("Failed to get resource interface operation for resource Id {} " + + " and operationId {}", parentId, operationUuid); + ResponseFormat responseFormat = componentsUtils.getResponseFormat( + ActionStatus.INTERFACE_OPERATION_NOT_FOUND, parentId); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, + currArtifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + + Operation operation = optionalOperation.get(); + ArtifactDefinition implementationArtifact = operation.getImplementationArtifact(); + implementationArtifact.setArtifactName(artifactInfo.getArtifactName()); + implementationArtifact.setDescription(artifactInfo.getDescription()); + implementationArtifact.setArtifactType(artifactInfo.getArtifactType()); + operation.setImplementation(implementationArtifact); + gotInterface.setOperationsMap(operationsMap); + Either interfaceDefinitionStorageOperationStatusEither = + interfaceOperation.updateInterface(storedResource.getUniqueId(), gotInterface); + if (interfaceDefinitionStorageOperationStatusEither.isRight()){ + StorageOperationStatus storageOperationStatus = interfaceDefinitionStorageOperationStatusEither.right().value(); + ActionStatus actionStatus = + componentsUtils.convertFromStorageResponseForDataType(storageOperationStatus); + return Either.right(componentsUtils.getResponseFormat(actionStatus)); + } + + String uniqueId = implementationArtifact.getUniqueId(); + artifactData.setId(uniqueId); + CassandraOperationStatus cassandraOperationStatus = artifactCassandraDao.saveArtifact(artifactData); + if(cassandraOperationStatus != CassandraOperationStatus.OK){ + log.debug("Failed to persist operation {} artifact, error is {}",operation.getName(),cassandraOperationStatus); + StorageOperationStatus storageStatus = DaoStatusConverter.convertCassandraStatusToStorageStatus(cassandraOperationStatus); + ActionStatus convertedFromStorageResponse = componentsUtils.convertFromStorageResponse(storageStatus); + return Either.right(componentsUtils.getResponseFormat(convertedFromStorageResponse)); + } + return Either.left(Either.left(implementationArtifact)); + } + private Either handlePayload(ArtifactDefinition artifactInfo, boolean isArtifactMetadataUpdate) { log.trace("Starting payload handling"); byte[] payload = artifactInfo.getPayloadData(); @@ -3995,7 +4095,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { if (oldCheckSum != null && oldCheckSum.equals(newCheckSum)) { artifactDefinition.setPayloadUpdateDate(payloadUpdateDateGen.get()); - updateArifactDefinitionStatus = artifactToscaOperation.updateArifactOnResource(artifactDefinition, component + updateArifactDefinitionStatus = artifactToscaOperation.updateArtifactOnResource(artifactDefinition, component .getUniqueId(), artifactDefinition.getUniqueId(), componentType.getNodeType(), instanceId); log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition .getArtifactType(), artifactDefinition.getEsId()); @@ -4018,7 +4118,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { artifactDefinition.setEsId(artifactDefinition.getUniqueId()); log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition .getArtifactType(), artifactDefinition.getEsId()); - updateArifactDefinitionStatus = artifactToscaOperation.updateArifactOnResource(artifactDefinition, component + updateArifactDefinitionStatus = artifactToscaOperation.updateArtifactOnResource(artifactDefinition, component .getUniqueId(), artifactDefinition.getUniqueId(), componentType.getNodeType(), instanceId); log.trace("Update Payload ", artifactDefinition.getEsId()); @@ -4263,7 +4363,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { currArtifact.setHeatParamsUpdateDate(System.currentTimeMillis()); currArtifact.setListHeatParameters(currentHeatEnvParams); - Either updateArifactRes = artifactToscaOperation.updateArifactOnResource(currArtifact, parent + Either updateArifactRes = artifactToscaOperation.updateArtifactOnResource(currArtifact, parent .getUniqueId(), currArtifact.getUniqueId(), componentType.getNodeType(), componentId); if (updateArifactRes.isRight()) { log.debug("Failed to update artifact on graph - {}", artifactId); @@ -4369,7 +4469,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { } if (!newHeatEnvParams.isEmpty()) { currHeatArtifact.setListHeatParameters(currentHeatEnvParams); - Either operationStatus = artifactToscaOperation.updateArifactOnResource(currHeatArtifact, parent + Either operationStatus = artifactToscaOperation.updateArtifactOnResource(currHeatArtifact, parent .getUniqueId(), currHeatArtifact.getUniqueId(), componentType.getNodeType(), componentId); if (operationStatus.isRight()) { @@ -4882,6 +4982,98 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { return updateArtifactResult; } + /** + * updates an artifact on a component by UUID + * + * @param data + * @param request + * @param componentType + * @param componentUuid + * @param artifactUUID + * @param additionalParams + * @param operation TODO + * @return + */ + public Either updateArtifactOnInterfaceOperationByResourceUUID( + String data, HttpServletRequest request, ComponentTypeEnum componentType, + String componentUuid, String artifactUUID, String operationUUID, + Map additionalParams, ArtifactOperationInfo operation) { + Wrapper errorWrapper = new Wrapper<>(); + Either updateArtifactResult; + Either, ResponseFormat> actionResult = null; + ArtifactDefinition updateArtifact = null; + String componentId = null; + ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class); + String origMd5 = request.getHeader(Constants.MD5_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + + Either getComponentRes = toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true); + if (getComponentRes.isRight()) { + StorageOperationStatus status = getComponentRes.right().value(); + log.debug("Could not fetch component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } + if (errorWrapper.isEmpty()) { + componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(); + String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName(); + if (!getComponentRes.left() + .value() + .getMetadataDataDefinition() + .getState() + .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) { + Component component = checkoutParentComponent(componentType, componentId, userId, errorWrapper); + if (component != null) { + componentId = component.getUniqueId(); + componentName = component.getName(); + } + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, componentName); + } + } + if (errorWrapper.isEmpty()) { + Either interfaceName = fetchInterfaceName(componentId); + if (interfaceName.isRight()) { + errorWrapper.setInnerElement(interfaceName.right().value()); + } + if (errorWrapper.isEmpty()) { + actionResult = handleArtifactRequest(componentId, userId, componentType, operation, + artifactUUID, artifactInfo, origMd5, data, interfaceName.left().value(), + operationUUID, null, null); + if (actionResult.isRight()) { + log.debug("Failed to upload artifact to component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, actionResult + .right() + .value()); + errorWrapper.setInnerElement(actionResult.right().value()); + } + } + } + if (errorWrapper.isEmpty()) { + updateArtifact = actionResult.left().value().left().value(); + updateArtifactResult = Either.left(updateArtifact); + + } + else { + updateArtifactResult = Either.right(errorWrapper.getInnerElement()); + } + updateAuditParametersWithArtifactDefinition(additionalParams, updateArtifact); + return updateArtifactResult; + } + + private Either fetchInterfaceName(String componentId) { + Either resourceStorageOperationStatusEither = + toscaOperationFacade.getToscaElement(componentId); + if (resourceStorageOperationStatusEither.isRight()) { + StorageOperationStatus errorStatus = resourceStorageOperationStatusEither.right().value(); + log.debug("Failed to fetch resource information by resource id, error {}", errorStatus); + return Either.right(componentsUtils + .getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus))); + } + Resource storedResource = resourceStorageOperationStatusEither.left().value(); + + return Either.left(InterfaceUtils.createInterfaceToscaResourceName( + storedResource.getName())); + } + + /** * deletes an artifact on a component by UUID * diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java index 05e7fe0941..c04eb2911d 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java @@ -19,9 +19,14 @@ package org.openecomp.sdc.be.components.impl; import com.google.common.collect.Sets; import fj.data.Either; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.tuple.Pair; import org.openecomp.sdc.be.components.validation.InterfaceOperationValidation; import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao; +import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; @@ -36,7 +41,6 @@ import org.openecomp.sdc.be.model.jsontitan.operations.InterfaceOperation; import org.openecomp.sdc.be.model.jsontitan.utils.InterfaceUtils; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; -import org.openecomp.sdc.be.user.Role; import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; import org.openecomp.sdc.common.api.ArtifactTypeEnum; import org.openecomp.sdc.exception.ResponseFormat; @@ -53,8 +57,6 @@ import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.UUID; -import java.util.stream.Collectors; -import java.util.stream.Stream; @Component("interfaceOperationBusinessLogic") public class InterfaceOperationBusinessLogic extends ComponentBusinessLogic{ @@ -68,6 +70,9 @@ public class InterfaceOperationBusinessLogic extends ComponentBusinessLogic{ @Autowired private InterfaceOperation interfaceOperation; + @Autowired + private ArtifactCassandraDao artifactCassandraDao; + public void setInterfaceOperation(InterfaceOperation interfaceOperation) { this.interfaceOperation = interfaceOperation; } @@ -82,19 +87,29 @@ public class InterfaceOperationBusinessLogic extends ComponentBusinessLogic{ } + public void setArtifactCassandraDao(ArtifactCassandraDao artifactCassandraDao) { + this.artifactCassandraDao = artifactCassandraDao; + } + public Either deleteInterfaceOperation(String resourceId, Set interfaceOperationToDelete, User user, boolean lock) { Resource resourceToDelete = initResourceToDeleteWFOp(resourceId, interfaceOperationToDelete); Either eitherDelete = validateUserAndRole(resourceToDelete, user, "deleteInterfaceOperation"); if (eitherDelete != null) return eitherDelete; + if (CollectionUtils.isEmpty(interfaceOperationToDelete)){ + LOGGER.debug("Invalid parameter interfaceOperationToDelete was empty"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY)); + } Either storageStatus = toscaOperationFacade.getToscaElement(resourceId); if (storageStatus.isRight()) { - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.RESOURCE),"")); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), + ComponentTypeEnum.RESOURCE), StringUtils.EMPTY)); } Resource resource = storageStatus.left().value(); if (lock) { - Either lockResult = lockComponent(resource.getUniqueId(), resource, "Delete interface Operation on a resource"); + Either lockResult = lockComponent(resource.getUniqueId(), resource, + "Delete interface Operation on a resource"); if (lockResult.isRight()) { LOGGER.debug("Failed to lock resource {}. Response is {}. ", resource.getName(), lockResult.right().value().getFormattedMessage()); titanDao.rollback(); @@ -110,14 +125,26 @@ public class InterfaceOperationBusinessLogic extends ComponentBusinessLogic{ return Either.right(sValue.right().value()); } InterfaceDefinition interfaceDefinition = sValue.left().value(); - Either deleteEither; for(String operationToDelete : interfaceOperationToDelete) { - deleteEither = deleteOperationFromInterface(interfaceDefinition, operationToDelete); + Either, ResponseFormat> deleteEither = deleteOperationFromInterface(interfaceDefinition, operationToDelete); if (deleteEither.isRight()){ return Either.right(deleteEither.right().value()); } - interfaceDefinition = deleteEither.left().value(); + + Operation deletedOperation = deleteEither.left().value().getValue(); + ArtifactDefinition implementationArtifact = deletedOperation.getImplementationArtifact(); + String artifactUUID = implementationArtifact.getArtifactUUID(); + CassandraOperationStatus cassandraStatus = artifactCassandraDao.deleteArtifact(artifactUUID); + if (cassandraStatus != CassandraOperationStatus.OK) { + LOGGER.debug("Failed to delete the artifact {} from the database. ", artifactUUID); + ResponseFormat responseFormatByArtifactId = componentsUtils.getResponseFormatByArtifactId( + componentsUtils.convertFromStorageResponse(componentsUtils.convertToStorageOperationStatus(cassandraStatus)), + implementationArtifact.getArtifactDisplayName()); + return Either.right(responseFormatByArtifactId); + } + + } Either interfaceUpdate = interfaceOperation.updateInterface(resource.getUniqueId(), interfaceDefinition); @@ -127,16 +154,14 @@ public class InterfaceOperationBusinessLogic extends ComponentBusinessLogic{ return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(interfaceUpdate.right().value(), ComponentTypeEnum.RESOURCE))); } - InterfaceDefinition interfaceDef = interfaceUpdate.left().value(); - if(interfaceDef.getOperationsMap().isEmpty()){ - Either, StorageOperationStatus> deleteInterface = interfaceOperation.deleteInterface(resource, Sets.newHashSet(interfaceDef.getUniqueId())); + if(interfaceDefinition.getOperationsMap().isEmpty()){ + Either, StorageOperationStatus> deleteInterface = interfaceOperation.deleteInterface(resource, Sets.newHashSet(interfaceDefinition.getUniqueId())); if (deleteInterface.isRight()) { LOGGER.debug("Failed to delete interface from resource {}. Response is {}. ", resource.getName(), deleteInterface.right().value()); titanDao.rollback(); return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteInterface.right().value(), ComponentTypeEnum.RESOURCE))); } } - titanDao.commit(); } catch (Exception e){ @@ -168,7 +193,7 @@ public class InterfaceOperationBusinessLogic extends ComponentBusinessLogic{ } } - private Either deleteOperationFromInterface(InterfaceDefinition interfaceDefinition, String operationId){ + private Either,ResponseFormat> deleteOperationFromInterface(InterfaceDefinition interfaceDefinition, String operationId){ Optional> operationToRemove = interfaceDefinition.getOperationsMap().entrySet().stream() .filter(entry -> entry.getValue().getUniqueId().equals(operationId)).findAny(); if (operationToRemove.isPresent()){ @@ -176,12 +201,13 @@ public class InterfaceOperationBusinessLogic extends ComponentBusinessLogic{ Map tempMap = interfaceDefinition.getOperationsMap(); tempMap.remove(stringOperationEntry.getKey()); interfaceDefinition.setOperationsMap(tempMap); - return Either.left(interfaceDefinition); + return Either.left(Pair.of(interfaceDefinition,stringOperationEntry.getValue())); } LOGGER.debug("Failed to delete interface operation"); return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND)); } + private Either addOperationToInterface(InterfaceDefinition interfaceDefinition, Operation interfaceOperation){ if(interfaceOperation.getUniqueId() == null) interfaceOperation.setUniqueId(UUID.randomUUID().toString()); @@ -230,6 +256,10 @@ public class InterfaceOperationBusinessLogic extends ComponentBusinessLogic{ return eitherCreator; Either resourceEither = getResourceDetails(resourceId); + if (resourceEither.isRight()){ + return resourceEither; + } + Resource storedResource = resourceEither.left().value(); Map interfaceOperations = InterfaceUtils @@ -386,13 +416,13 @@ public class InterfaceOperationBusinessLogic extends ComponentBusinessLogic{ @Override public Either, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, - ComponentTypeEnum componentTypeEnum, String userId, String searchText) { + ComponentTypeEnum componentTypeEnum, String userId, String searchText) { return null; } @Override public Either getUiComponentDataTransferByComponentId(String resourceId, - List dataParamsToReturn) { + List dataParamsToReturn) { ComponentParametersView paramsToRetuen = new ComponentParametersView(dataParamsToReturn); Either resourceResultEither = toscaOperationFacade.getToscaElement(resourceId, paramsToRetuen); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java index 3d3cca4ed2..439c8bd53a 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java @@ -204,25 +204,31 @@ public class InterfaceOperationValidation { } private Either validateInputParameters(Operation interfaceOperation, ResponseFormatManager responseFormatManager) { + if (isInputParameterNameEmpty(interfaceOperation)) { + LOGGER.error("Interface operation input parameter name can't be empty"); + ResponseFormat inputResponse = responseFormatManager.getResponseFormat(ActionStatus + .INTERFACE_OPERATION_INPUT_NAME_MANDATORY); + return Either.right(inputResponse); + } + Either> validateInputParametersUniqueResponse = isInputParametersUnique(interfaceOperation); if(validateInputParametersUniqueResponse.isRight()) { - LOGGER.error("Interface operation input parameter names {} are invalid, Input parameter names should be unique", + LOGGER.error("Interface operation input parameter names {} already in use", validateInputParametersUniqueResponse.right().value().toString()); ResponseFormat inputResponse = responseFormatManager.getResponseFormat(ActionStatus - .INTERFACE_OPERATION_INPUT_NAME_INVALID, validateInputParametersUniqueResponse.right().value().toString()); + .INTERFACE_OPERATION_INPUT_NAME_ALREADY_IN_USE, validateInputParametersUniqueResponse.right().value().toString()); return Either.right(inputResponse); } return Either.left(Boolean.TRUE); } private Either> isInputParametersUnique(Operation operationDataDefinition) { - Set inputParamNamesSet = new HashSet<>(); Set duplicateParamNamesToReturn = new HashSet<>(); operationDataDefinition.getInputs().getListToscaDataDefinition() .forEach(inputParam -> { - if(!inputParamNamesSet.add(inputParam.getName())) { - duplicateParamNamesToReturn.add(inputParam.getName()); + if(!inputParamNamesSet.add(inputParam.getName().trim())) { + duplicateParamNamesToReturn.add(inputParam.getName().trim()); } }); if(!duplicateParamNamesToReturn.isEmpty()) { @@ -231,6 +237,11 @@ public class InterfaceOperationValidation { return Either.left(Boolean.TRUE); } + private Boolean isInputParameterNameEmpty(Operation operationDataDefinition) { + return operationDataDefinition.getInputs().getListToscaDataDefinition().stream() + .anyMatch(inputParam -> inputParam.getName() == null || inputParam.getName().trim().equals(StringUtils.EMPTY)); + } + private boolean validateOperationTypeUniqueForUpdate(Operation interfaceOperation, Map operationTypes) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/InterfaceUIDataConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/InterfaceUIDataConverter.java index 7885ab1bd2..27b1b7ed9a 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/InterfaceUIDataConverter.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/InterfaceUIDataConverter.java @@ -36,7 +36,8 @@ public class InterfaceUIDataConverter { ListDataDefinition inputs = new ListDataDefinition<>(); if (inputParams != null) { List inputList = inputParams.getListToscaDataDefinition().stream() - .map(a -> new OperationInputDefinition(a.getParamName(), a.getParamId())).collect(Collectors.toList()); + .map(interfaceOperationParamDataDefinition -> new OperationInputDefinition(interfaceOperationParamDataDefinition.getParamName(), + interfaceOperationParamDataDefinition.getParamId())).collect(Collectors.toList()); inputList.forEach(inputs::add); } Operation operationData = new Operation(); @@ -51,7 +52,8 @@ public class InterfaceUIDataConverter { public static InterfaceOperationDataDefinition convertOperationDataToInterfaceData(Operation operationData){ ListDataDefinition inputs = operationData.getInputs(); - List inputParamList = inputs.getListToscaDataDefinition().stream().map(a -> new InterfaceOperationParamDataDefinition(a.getName(), a.getInputId())).collect( + List inputParamList = inputs.getListToscaDataDefinition().stream() + .map(a -> new InterfaceOperationParamDataDefinition(a.getName(), a.getInputId())).collect( Collectors.toList()); ListDataDefinition inputParams = new ListDataDefinition<>(); inputParamList.forEach(inputParams::add); @@ -61,7 +63,7 @@ public class InterfaceUIDataConverter { interfaceOperationDataDefinition.setOperationType(operationData.getName()); interfaceOperationDataDefinition.setDescription(operationData.getDescription()); interfaceOperationDataDefinition.setInputParams(inputParams); - interfaceOperationDataDefinition.setWorkflowId(operationData.getImplementation().getArtifactUUID()); + interfaceOperationDataDefinition.setArtifactUUID(operationData.getImplementation().getArtifactUUID()); return interfaceOperationDataDefinition; } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java index 70225c0dd2..b634abba82 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java @@ -56,6 +56,7 @@ 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.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.ByteArrayInputStream; @@ -82,6 +83,87 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { private static String startLog = "Start handle request of "; + @POST + @Path("/resources/{uuid}/interfaces/{operationUUID}/artifacts/{artifactUUID}") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "uploads of artifact to VF operation workflow", httpMethod = "POST", notes = "uploads of artifact to VF operation workflow") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Artifact uploaded", response = ArtifactDefinition.class), + @ApiResponse(code = 400, message = "Missing 'X-ECOMP-InstanceID' HTTP header - POL5001"), + @ApiResponse(code = 401, message = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"), + @ApiResponse(code = 403, message = "ECOMP component is not authorized - POL5003"), + @ApiResponse(code = 404, message = "Specified resource is not found - SVC4063"), + @ApiResponse(code = 405, message = "Method Not Allowed: Invalid HTTP method type used (PUT,DELETE,POST will be rejected) - POL4050"), + @ApiResponse(code = 500, message = "The GET request failed either due to internal SDC problem or Cambria Service failure. ECOMP Component should continue the attempts to get the needed information - POL5000"), + @ApiResponse(code = 400, message = "Invalid artifactType was defined as input - SVC4122"), + @ApiResponse(code = 400, message = "Artifact type (mandatory field) is missing in request - SVC4124"), + @ApiResponse(code = 400, message = "Artifact name given in input already exists in the context of the asset - SVC4125"), + @ApiResponse(code = 400, message = "Invalid MD5 header - SVC4127"), + @ApiResponse(code = 400, message = "Artifact name is missing in input - SVC4128"), + @ApiResponse(code = 400, message = "Asset is being edited by different user. Only one user can checkout and edit an asset on given time. The asset will be available for checkout after the other user will checkin the asset - SVC4086"), + @ApiResponse(code = 400, message = "Restricted Operation – the user provided does not have role of Designer or the asset is being used by another designer - SVC4301")}) + @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.model.ArtifactDefinition", paramType = "body", value = "json describe the artifact")}) + public Response uploadInterfaceOperationArtifact( + @ApiParam(value = "Determines the format of the body of the request", required = true) @HeaderParam(value = HttpHeaders.CONTENT_TYPE) String contenType, + @ApiParam(value = "The value for this header must be the MD5 checksum over the whole json body", required = true) @HeaderParam(value = Constants.MD5_HEADER) String checksum, + @ApiParam(value = "The user ID of the DCAE Designer. This user must also have Designer role in SDC", required = true) @HeaderParam(value = Constants.USER_ID_HEADER) final String userId, + @ApiParam(value = "X-ECOMP-RequestID header", required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @ApiParam(value = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, + @ApiParam(value = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept, + @ApiParam(value = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, + @ApiParam(value = "The uuid of the operation", required = true)@PathParam("operationUUID") final String operationUUID, + @ApiParam(value = "The uuid of the artifact", required = true)@PathParam("artifactUUID") final String artifactUUID, + String data) { + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat = null; + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("{} {}", startLog, url); + ComponentTypeEnum componentType = ComponentTypeEnum.RESOURCE; + String componentTypeValue = componentType.getValue(); + EnumMap additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_CURR_ARTIFACT_UUID, artifactUUID); + + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("updateArtifact: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { + log.debug("updateArtifact: Missing USER_ID"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_USER_ID); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + try { + if (responseWrapper.isEmpty()) { + ServletContext context = request.getSession().getServletContext(); + ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); + Either uploadArtifactEither = artifactsLogic.updateArtifactOnInterfaceOperationByResourceUUID(data, request, componentType, uuid, artifactUUID, operationUUID, + additionalParams, artifactsLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.UPDATE)); + if (uploadArtifactEither.isRight()) { + log.debug("failed to update artifact"); + responseFormat = uploadArtifactEither.right().value(); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5Base64EncodedByString((String) representation)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); + } + } + } catch (Exception e) { + final String message = "failed to update artifact on a resource or service"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } finally { + getComponentsUtils().auditExternalUpdateArtifact(responseFormat, componentTypeValue, request, additionalParams); + } + return responseWrapper.getInnerElement(); + } + /** * Uploads an artifact to resource or service * diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java index 566daec5e7..56027048aa 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java @@ -42,6 +42,7 @@ import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; import org.openecomp.sdc.be.components.impl.ResponseFormatManager; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; import org.openecomp.sdc.be.dao.graph.datatype.AdditionalInformationEnum; import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterInfo; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; @@ -1436,7 +1437,25 @@ public class ComponentsUtils { return responseFormat; } - + public StorageOperationStatus convertToStorageOperationStatus(CassandraOperationStatus cassandraStatus) { + StorageOperationStatus result; + switch (cassandraStatus) { + case OK: + result = StorageOperationStatus.OK; + break; + case NOT_FOUND: + result = StorageOperationStatus.NOT_FOUND; + break; + case CLUSTER_NOT_CONNECTED: + case KEYSPACE_NOT_CONNECTED: + result = StorageOperationStatus.CONNECTION_FAILURE; + break; + default: + result = StorageOperationStatus.GENERAL_ERROR; + break; + } + return result; + } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceInterfaceOperationServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceInterfaceOperationServlet.java index 49bce3bfe6..b51fc00cc1 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceInterfaceOperationServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceInterfaceOperationServlet.java @@ -27,7 +27,6 @@ import io.swagger.annotations.ApiResponses; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic; -import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.datamodel.utils.InterfaceUIDataConverter; diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java index 75810bd286..3c95539ec5 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.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. @@ -20,8 +20,11 @@ package org.openecomp.sdc.be.tosca; +import com.google.gson.Gson; +import fj.data.Either; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; +import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -32,6 +35,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -39,7 +43,6 @@ import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; - import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.output.ByteArrayOutputStream; @@ -58,11 +61,13 @@ import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao; import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; import org.openecomp.sdc.be.dao.cassandra.SdcSchemaFilesCassandraDao; +import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; 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.ComponentInstance; +import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.LifecycleStateEnum; import org.openecomp.sdc.be.model.Operation; import org.openecomp.sdc.be.model.Resource; @@ -76,6 +81,7 @@ import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter; import org.openecomp.sdc.be.resources.data.ESArtifactData; import org.openecomp.sdc.be.resources.data.SdcSchemaFilesData; import org.openecomp.sdc.be.tosca.model.ToscaTemplate; +import org.openecomp.sdc.be.tosca.utils.OperationArtifactUtil; import org.openecomp.sdc.be.utils.CommonBeUtils; import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; import org.openecomp.sdc.common.api.ArtifactTypeEnum; @@ -92,10 +98,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import com.google.gson.Gson; - -import fj.data.Either; - /** * @author tg851x @@ -103,6 +105,7 @@ import fj.data.Either; */ @org.springframework.stereotype.Component("csar-utils") public class CsarUtils { + private static final Logger log = LoggerFactory.getLogger(CsarUtils.class); @Autowired @@ -132,6 +135,8 @@ public class CsarUtils { public static final String RESOURCES_PATH = "Resources/"; public static final String INFORMATIONAL_ARTIFACTS = "Informational/"; public static final String DEPLOYMENT_ARTIFACTS = "Deployment/"; + public static final String WORKFLOW_ARTIFACT_DIR = "Workflows"+File.separator+"BPMN"+File.separator; + public static final String DEPLOYMENT_ARTIFACTS_DIR = "Deployment"+File.separator; public static final String DEFINITIONS_PATH = "Definitions/"; private static final String CSAR_META_VERSION = "1.0"; @@ -145,23 +150,23 @@ public class CsarUtils { private static String versionFirstThreeOctates; public static final String VFC_NODE_TYPE_ARTIFACTS_PATH_PATTERN = ARTIFACTS + DEL_PATTERN + - ImportUtils.Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX + - "([\\d\\w\\_\\-\\.\\s]+)" + DEL_PATTERN + - "([\\d\\w\\_\\-\\.\\s]+)" + DEL_PATTERN + - "([\\d\\w\\_\\-\\.\\s]+)" + DEL_PATTERN + - "([\\d\\w\\_\\-\\.\\s]+)"; + ImportUtils.Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX + + "([\\d\\w\\_\\-\\.\\s]+)" + DEL_PATTERN + + "([\\d\\w\\_\\-\\.\\s]+)" + DEL_PATTERN + + "([\\d\\w\\_\\-\\.\\s]+)" + DEL_PATTERN + + "([\\d\\w\\_\\-\\.\\s]+)"; public static final String VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN = ARTIFACTS + DEL_PATTERN+ - // Artifact Group (i.e Deployment/Informational) - "([\\w\\_\\-\\.\\s]+)" + DEL_PATTERN + - // Artifact Type - "([\\w\\_\\-\\.\\s]+)" + DEL_PATTERN + - // Artifact Any File Name - ".+"; + // Artifact Group (i.e Deployment/Informational) + "([\\w\\_\\-\\.\\s]+)" + DEL_PATTERN + + // Artifact Type + "([\\w\\_\\-\\.\\s]+)" + DEL_PATTERN + + // Artifact Any File Name + ".+"; public static final String VALID_ENGLISH_ARTIFACT_NAME = "([\\w\\_\\-\\.\\s]+)"; public static final String SERVICE_TEMPLATE_PATH_PATTERN = DEFINITION + DEL_PATTERN+ - // Service Template File Name - "([\\w\\_\\-\\.\\s]+)"; + // Service Template File Name + "([\\w\\_\\-\\.\\s]+)"; public static final String ARTIFACT_CREATED_FROM_CSAR = "Artifact created from csar"; @@ -214,7 +219,7 @@ public class CsarUtils { try ( ByteArrayOutputStream out = new ByteArrayOutputStream(); ZipOutputStream zip = new ZipOutputStream(out); - ){ + ){ zip.putNextEntry(new ZipEntry(CSAR_META_PATH_FILE_NAME)); zip.write(csarBlock0Byte); zip.putNextEntry(new ZipEntry(TOSCA_META_PATH_FILE_NAME)); @@ -277,11 +282,11 @@ public class CsarUtils { zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + fileName)); zip.write(mainYaml); - //US798487 - Abstraction of complex types - if (!ModelConverter.isAtomicComponent(component)){ - log.debug("Component {} is complex - generating abstract type for it..", component.getName()); - writeComponentInterface(component, zip, fileName); - } + //US798487 - Abstraction of complex types + if (!ModelConverter.isAtomicComponent(component)){ + log.debug("Component {} is complex - generating abstract type for it..", component.getName()); + writeComponentInterface(component, zip, fileName); + } generatorInputs.add(new ImmutablePair(component, mainYaml)); @@ -302,9 +307,9 @@ public class CsarUtils { if (dependencies != null && !dependencies.isEmpty()) { for (Triple d : dependencies) { - String cassandraId = d.getMiddle(); + String cassandraId = d.getMiddle(); Component childComponent = d.getRight(); - Either entryData = getEntryData(cassandraId, childComponent); + Either entryData = getEntryData(cassandraId, childComponent); if (entryData.isRight()) { ResponseFormat responseFormat = componentsUtils.getResponseFormat(entryData.right().value()); @@ -333,7 +338,7 @@ public class CsarUtils { if (entryData.isRight()) { ResponseFormat responseFormat = componentsUtils.getResponseFormat(entryData.right().value()); log.debug("Failed adding to zip component {}, error {}", innerComponentTriple.getLeft(), - entryData.right().value()); + entryData.right().value()); return Either.right(responseFormat); } byte[] content = entryData.left().value(); @@ -364,7 +369,7 @@ public class CsarUtils { // Artifact Generation if (component.getComponentType() == ComponentTypeEnum.SERVICE - && isInCertificationRequest) { + && isInCertificationRequest) { List aiiArtifactList; @@ -395,7 +400,7 @@ public class CsarUtils { return Either.right(collectedComponentCsarDefinition.right().value()); } - return writeAllFilesToScar(component, collectedComponentCsarDefinition.left().value(), zip, isInCertificationRequest); + return writeAllFilesToCsar(component, collectedComponentCsarDefinition.left().value(), zip, isInCertificationRequest); } private Either addSchemaFilesFromCassandra(ZipOutputStream zip, byte[] schemaFileZip){ @@ -405,8 +410,8 @@ public class CsarUtils { log.debug("Starting copy from Schema file zip to CSAR zip"); try (ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(schemaFileZip)); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - BufferedOutputStream bos = new BufferedOutputStream(out, initSize);) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + BufferedOutputStream bos = new BufferedOutputStream(out, initSize);) { ZipEntry entry = null; @@ -576,9 +581,9 @@ public class CsarUtils { Set componetInformationalArtifactLables = component.getArtifacts().keySet(); return artifactsFromAAI.stream() - .filter(e -> componetDeploymentArtifactLables.contains(e.getArtifactLabel()) || componetInformationalArtifactLables.contains(e.getArtifactLabel())) - .filter(e -> checkAaiForUpdate(component, e)) - .collect(Collectors.toList()); + .filter(e -> componetDeploymentArtifactLables.contains(e.getArtifactLabel()) || componetInformationalArtifactLables.contains(e.getArtifactLabel())) + .filter(e -> checkAaiForUpdate(component, e)) + .collect(Collectors.toList()); } private boolean checkAaiForUpdate(Component component, ArtifactDefinition artifactDefinition) { @@ -609,26 +614,26 @@ public class CsarUtils { private List getAAIArtifatcsForDelete(List artifactsFromAAI, Component component) { Set aaiLabels = artifactsFromAAI.stream() - .map(ArtifactDefinition::getArtifactLabel) - .collect(Collectors.toSet()); + .map(ArtifactDefinition::getArtifactLabel) + .collect(Collectors.toSet()); List artifactsForDeleteDeployment = component.getDeploymentArtifacts().values().stream() - // Filter Out Artifacts that are not contained in artifacts returned - // from AAI API - .filter(e -> !aaiLabels.contains(e.getArtifactLabel())) - .collect(Collectors.toList()); + // Filter Out Artifacts that are not contained in artifacts returned + // from AAI API + .filter(e -> !aaiLabels.contains(e.getArtifactLabel())) + .collect(Collectors.toList()); List artifactsForDeleteInformational = component.getArtifacts().values().stream() - // Filter Out Artifacts that are not contained in artifacts returned - // from AAI API - .filter(e -> !aaiLabels.contains(e.getArtifactLabel())) - .collect(Collectors.toList()); + // Filter Out Artifacts that are not contained in artifacts returned + // from AAI API + .filter(e -> !aaiLabels.contains(e.getArtifactLabel())) + .collect(Collectors.toList()); artifactsForDeleteDeployment.addAll(artifactsForDeleteInformational); return artifactsForDeleteDeployment.stream() - .filter(e -> (e.getGenerated() != null && e.getGenerated().equals(Boolean.TRUE)) || (e.getGenerated() == null && e.getArtifactLabel().toLowerCase().startsWith("aai"))) - .collect(Collectors.toList()); + .filter(e -> (e.getGenerated() != null && e.getGenerated().equals(Boolean.TRUE)) || (e.getGenerated() == null && e.getArtifactLabel().toLowerCase().startsWith("aai"))) + .collect(Collectors.toList()); } private List getAAIArtifatcsForCreate(List artifactsFromAAI, Component component) { @@ -639,8 +644,8 @@ public class CsarUtils { // If the artifact label does not exist in the service - // store the artifact (generate uuid and version, "generated" flag is TRUE) return artifactsFromAAI.stream() - .filter(e -> !componentDeploymentLabels.contains(e.getArtifactLabel()) && !componentInfoLabels.contains(e.getArtifactLabel())) - .collect(Collectors.toList()); + .filter(e -> !componentDeploymentLabels.contains(e.getArtifactLabel()) && !componentInfoLabels.contains(e.getArtifactLabel())) + .collect(Collectors.toList()); } private Either handleAAIArtifactsInDataModelByOperationType(Component component, List generatedArtifactsDefinitions, ArtifactOperationInfo operationType, User user, boolean shouldLock, @@ -748,7 +753,7 @@ public class CsarUtils { } else { Either fromCassandra = getFromCassandra(cassandraId); if (fromCassandra.isRight()) { - return Either.right(fromCassandra.right().value()); + return Either.right(fromCassandra.right().value()); } else { content = fromCassandra.left().value(); } @@ -766,7 +771,7 @@ public class CsarUtils { return Either.right(componentsUtils.getResponseFormat(convertedFromStorageResponse)); } - List listOfSchemas = specificSchemaFiles.left().value(); + List listOfSchemas = specificSchemaFiles.left().value(); if(listOfSchemas.isEmpty()){ log.debug("Failed to get the schema files SDC-Version: {} Conformance-Level {}", versionFirstThreeOctates, CONFORMANCE_LEVEL); @@ -867,10 +872,10 @@ public class CsarUtils { log.debug("************* Going to extract VFCs artifacts from Csar. "); Map>> collectedWarningMessages = new HashMap<>(); csar.entrySet().stream() - // filter CSAR entry by node type artifact path - .filter(e -> Pattern.compile(VFC_NODE_TYPE_ARTIFACTS_PATH_PATTERN).matcher(e.getKey()).matches()) - // extract ArtifactDefinition from CSAR entry for each entry with matching artifact path - .forEach(e -> addExtractedVfcArtifact(extractVfcArtifact(e, collectedWarningMessages), artifacts)); + // filter CSAR entry by node type artifact path + .filter(e -> Pattern.compile(VFC_NODE_TYPE_ARTIFACTS_PATH_PATTERN).matcher(e.getKey()).matches()) + // extract ArtifactDefinition from CSAR entry for each entry with matching artifact path + .forEach(e -> addExtractedVfcArtifact(extractVfcArtifact(e, collectedWarningMessages), artifacts)); // add counter suffix to artifact labels handleWarningMessages(collectedWarningMessages); @@ -885,10 +890,10 @@ public class CsarUtils { */ public static void handleWarningMessages(Map>> collectedWarningMessages) { collectedWarningMessages.entrySet().stream() - // for each vfc - .forEach(e -> e.getValue().stream() - // add each warning message to log - .forEach(args -> log.warn(e.getKey(), args.toArray()))); + // for each vfc + .forEach(e -> e.getValue().stream() + // add each warning message to log + .forEach(args -> log.warn(e.getKey(), args.toArray()))); } @@ -1092,16 +1097,16 @@ public class CsarUtils { if(artifactGroupType != null){ switch (artifactGroupType) { - case INFORMATIONAL: - resourceValidTypeArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration() - .getResourceInformationalArtifacts(); - break; - case DEPLOYMENT: - resourceValidTypeArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration() - .getResourceDeploymentArtifacts(); - break; - default: - break; + case INFORMATIONAL: + resourceValidTypeArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration() + .getResourceInformationalArtifacts(); + break; + case DEPLOYMENT: + resourceValidTypeArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration() + .getResourceDeploymentArtifacts(); + break; + default: + break; } } @@ -1126,20 +1131,20 @@ public class CsarUtils { return artifactType == null ? ArtifactTypeEnum.OTHER.getType() : artifactType.getType(); } - private Either writeAllFilesToScar(Component mainComponent, CsarDefinition csarDefinition, ZipOutputStream zipstream, boolean isInCertificationRequest) throws IOException{ + private Either writeAllFilesToCsar(Component mainComponent, CsarDefinition csarDefinition, ZipOutputStream zipstream, boolean isInCertificationRequest) throws IOException{ ComponentArtifacts componentArtifacts = csarDefinition.getComponentArtifacts(); - Either writeComponentArtifactsToSpecifiedtPath = writeComponentArtifactsToSpecifiedtPath(mainComponent, componentArtifacts, zipstream, ARTIFACTS_PATH, isInCertificationRequest); + Either writeComponentArtifactsToSpecifiedPath = writeComponentArtifactsToSpecifiedPath(mainComponent, componentArtifacts, zipstream, ARTIFACTS_PATH, isInCertificationRequest); - if(writeComponentArtifactsToSpecifiedtPath.isRight()){ - return Either.right(writeComponentArtifactsToSpecifiedtPath.right().value()); + if(writeComponentArtifactsToSpecifiedPath.isRight()){ + return Either.right(writeComponentArtifactsToSpecifiedPath.right().value()); } ComponentTypeArtifacts mainTypeAndCIArtifacts = componentArtifacts.getMainTypeAndCIArtifacts(); - writeComponentArtifactsToSpecifiedtPath = writeArtifactsInfoToSpecifiedtPath(mainComponent, mainTypeAndCIArtifacts.getComponentArtifacts(), zipstream, ARTIFACTS_PATH, isInCertificationRequest); + writeComponentArtifactsToSpecifiedPath = writeArtifactsInfoToSpecifiedtPath(mainComponent, mainTypeAndCIArtifacts.getComponentArtifacts(), zipstream, ARTIFACTS_PATH, isInCertificationRequest); - if(writeComponentArtifactsToSpecifiedtPath.isRight()){ - return Either.right(writeComponentArtifactsToSpecifiedtPath.right().value()); + if(writeComponentArtifactsToSpecifiedPath.isRight()){ + return Either.right(writeComponentArtifactsToSpecifiedPath.right().value()); } Map componentInstancesArtifacts = mainTypeAndCIArtifacts.getComponentInstancesArtifacts(); @@ -1149,17 +1154,80 @@ public class CsarUtils { for (String keyAssetName : keySet) { ArtifactsInfo artifactsInfo = componentInstancesArtifacts.get(keyAssetName); String pathWithAssetName = currentPath + keyAssetName + "/"; - writeComponentArtifactsToSpecifiedtPath = writeArtifactsInfoToSpecifiedtPath(mainComponent, artifactsInfo, zipstream, pathWithAssetName, isInCertificationRequest); + writeComponentArtifactsToSpecifiedPath = writeArtifactsInfoToSpecifiedtPath(mainComponent, artifactsInfo, zipstream, pathWithAssetName, isInCertificationRequest); - if(writeComponentArtifactsToSpecifiedtPath.isRight()){ - return Either.right(writeComponentArtifactsToSpecifiedtPath.right().value()); + if(writeComponentArtifactsToSpecifiedPath.isRight()){ + return Either.right(writeComponentArtifactsToSpecifiedPath.right().value()); } } + writeComponentArtifactsToSpecifiedPath = writeOperationsArtifactsToCsar(mainComponent, zipstream); + if (writeComponentArtifactsToSpecifiedPath.isRight()) { + return Either.right(writeComponentArtifactsToSpecifiedPath.right().value()); + } return Either.left(zipstream); } - private Either writeComponentArtifactsToSpecifiedtPath(Component mainComponent, ComponentArtifacts componentArtifacts, ZipOutputStream zipstream, + private Either writeOperationsArtifactsToCsar(Component component, + ZipOutputStream zipstream) { + if (component instanceof Service ) { + return Either.left(zipstream); + } + if (Objects.isNull(((Resource) component).getInterfaces())) { + log.debug("Component Name {}- no interfaces found", component.getNormalizedName()); + return Either.left(zipstream); + } + final Map interfaces = ((Resource) component).getInterfaces(); + + for (Map.Entry interfaceEntry : interfaces.entrySet()) { + for (OperationDataDefinition operation : interfaceEntry.getValue().getOperations().values()) { + try { + if (Objects.isNull(operation.getImplementation())) { + log.debug("Component Name {}, Interface Id {}, Operation Name {} - no Operation Implementation found", + component.getNormalizedName(), interfaceEntry.getValue().getUniqueId(), + operation.getName()); + continue; + } + if (Objects.isNull(operation.getImplementation().getArtifactName())) { + log.debug("Component Name {}, Interface Id {}, Operation Name {} - no artifact found", + component.getNormalizedName(), interfaceEntry.getValue().getUniqueId(), + operation.getName()); + continue; + } + + final String artifactUUID = operation.getImplementation().getArtifactUUID(); + + final Either artifactFromCassandra = getFromCassandra(artifactUUID); + final String artifactName = operation.getImplementation().getArtifactName(); + if (artifactFromCassandra.isRight()) { + log.error("ArtifactName {}, unique ID {}", artifactName, artifactUUID); + log.error("Failed to get {} payload from DB reason: {}", artifactName, + artifactFromCassandra.right().value()); + return Either.right(componentsUtils.getResponseFormat( + ActionStatus.ARTIFACT_PAYLOAD_NOT_FOUND_DURING_CSAR_CREATION, "Resource", + component.getUniqueId(), artifactName, artifactUUID)); + } + + final byte[] payloadData = artifactFromCassandra.left().value(); + zipstream.putNextEntry(new ZipEntry(OperationArtifactUtil.createOperationArtifactPath( + component.getNormalizedName(), interfaceEntry.getValue().getToscaResourceName(), operation))); + zipstream.write(payloadData); + + } catch (IOException e) { + log.error("Component Name {}, Interface Name {}, Operation Name {}", component.getNormalizedName(), + interfaceEntry.getKey(), operation.getName()); + log.error("Error while writing the operation's artifacts to the CSAR " + "{}", e); + return Either.right(componentsUtils + .getResponseFormat(ActionStatus.ERROR_DURING_CSAR_CREATION, "Resource", + component.getUniqueId())); + } + } + } + return Either.left(zipstream); + + } + + private Either writeComponentArtifactsToSpecifiedPath(Component mainComponent, ComponentArtifacts componentArtifacts, ZipOutputStream zipstream, String currentPath, boolean isInCertificationRequest) throws IOException { Map componentTypeArtifacts = componentArtifacts.getComponentTypeArtifacts(); //Keys are defined: @@ -1182,7 +1250,7 @@ public class CsarUtils { private Either writeArtifactsInfoToSpecifiedtPath(Component mainComponent, ArtifactsInfo currArtifactsInfo, ZipOutputStream zip, String path, boolean isInCertificationRequest) throws IOException { Map>> artifactsInfo = currArtifactsInfo - .getArtifactsInfo(); + .getArtifactsInfo(); Set groupTypeEnumKeySet = artifactsInfo.keySet(); for (ArtifactGroupTypeEnum artifactGroupTypeEnum : groupTypeEnumKeySet) { @@ -1214,9 +1282,9 @@ public class CsarUtils { for (ArtifactDefinition artifactDefinition : artifactDefinitionList) { if (!isInCertificationRequest && componentType == ComponentTypeEnum.SERVICE - && artifactDefinition.getArtifactType().equals(heatEnvType) || - //this is placeholder - (artifactDefinition.getEsId() == null && artifactDefinition.getMandatory())){ + && artifactDefinition.getArtifactType().equals(heatEnvType) || + //this is placeholder + (artifactDefinition.getEsId() == null && artifactDefinition.getMandatory())){ continue; } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/OperationArtifactUtil.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/OperationArtifactUtil.java new file mode 100644 index 0000000000..afb69748bb --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/OperationArtifactUtil.java @@ -0,0 +1,41 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * 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. + */ + +package org.openecomp.sdc.be.tosca.utils; + +import java.io.File; +import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; +import org.openecomp.sdc.be.tosca.CsarUtils; + +public class OperationArtifactUtil { + + /** + * This method assumes that operation.getImplementation() is not NULL ( it should be verified by the caller method) + * + * @param componentName component's normalized name + * @param interfaceType the specific interface name + * @param operation teh specific operation name + * @return the full path including file name for operation's artifacts + */ + + public static String createOperationArtifactPath(String componentName, String interfaceType, + OperationDataDefinition operation) { + return CsarUtils.ARTIFACTS + File.separator + componentName + File.separator + interfaceType + File.separator + + CsarUtils.DEPLOYMENT_ARTIFACTS_DIR + CsarUtils.WORKFLOW_ARTIFACT_DIR + operation + .getImplementation() + .getArtifactName(); + } +} diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml index b0f2e2107f..de5196e11e 100644 --- a/catalog-be/src/main/resources/config/error-configuration.yaml +++ b/catalog-be/src/main/resources/config/error-configuration.yaml @@ -2060,9 +2060,9 @@ errors: messageId: "SVC4698" } #---------SVC4699----------------------------- - INTERFACE_OPERATION_INPUT_NAME_INVALID: { + INTERFACE_OPERATION_INPUT_NAME_ALREADY_IN_USE: { code: 400, - message: "Error: Interface Operation input parameter names %1 are invalid ,Input parameters name should be unique", + message: "Error: Interface Operation input parameter names %1 already in use", messageId: "SVC4699" } #---------SVC4700----------------------------- @@ -2084,3 +2084,17 @@ errors: message: "Error: Failed to delete interface operation.", messageId: "SVC4702" } +#---------SVC4703----------------------------- +# %1 – asset type [service / resource ] +# %2 – main asset uuid + ERROR_DURING_CSAR_CREATION: { + code: 404, + message: "Error: CSAR packaging failed for %1 %2.", + messageId: "SVC4702" + } +#---------SVC46703----------------------------- + INTERFACE_OPERATION_INPUT_NAME_MANDATORY: { + code: 404, + message: "Error: Interface operation input parameter name should not be empty", + messageId: "SVC46703" + } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/InterfaceOperationTestUtils.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/InterfaceOperationTestUtils.java index 52b71c5743..18116a4d56 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/InterfaceOperationTestUtils.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/InterfaceOperationTestUtils.java @@ -58,7 +58,6 @@ public interface InterfaceOperationTestUtils { return operation; } - default Map createMockOperationMap() { Operation operation = new Operation(); @@ -69,6 +68,10 @@ public interface InterfaceOperationTestUtils { operation.setDefinition(false); operation.setName("CREATE"); operation.setUniqueId("uniqueId1"); + ArtifactDefinition implementation = new ArtifactDefinition(); + implementation.setUniqueId("uniqId"); + implementation.setArtifactUUID("artifactId"); + operation.setImplementation(implementation); Map operationMap = new HashMap<>(); operationMap.put("op1", operation); return operationMap; @@ -90,5 +93,5 @@ public interface InterfaceOperationTestUtils { return interfaceDefinitionMap; } - + } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactBusinessLogicTest.java index bebe29f13e..4ce0740887 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactBusinessLogicTest.java @@ -375,7 +375,7 @@ public class ArtifactBusinessLogicTest { artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.TOSCA); when(graphLockOperation.lockComponent(any(), any())).thenReturn(StorageOperationStatus.OK); - when(artifactsOperations.updateArifactOnResource(any(ArtifactDefinition.class), any(), any(), any(NodeTypeEnum.class) + when(artifactsOperations.updateArtifactOnResource(any(ArtifactDefinition.class), any(), any(), any(NodeTypeEnum.class) , any(String.class))).thenReturn(Either.left(artifactDefinition)); when(artifactCassandraDao.saveArtifact(any())).thenReturn(CassandraOperationStatus.OK); when(componentsUtils.getResponseFormat(any(ActionStatus.class))).thenReturn(new ResponseFormat()); @@ -394,7 +394,7 @@ public class ArtifactBusinessLogicTest { artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.TOSCA); when(graphLockOperation.lockComponent(any(), any())).thenReturn(StorageOperationStatus.OK); - when(artifactsOperations.updateArifactOnResource(any(ArtifactDefinition.class), any(), any(), any(NodeTypeEnum.class) + when(artifactsOperations.updateArtifactOnResource(any(ArtifactDefinition.class), any(), any(), any(NodeTypeEnum.class) , any(String.class))).thenReturn(Either.left(artifactDefinition)); when(artifactCassandraDao.saveArtifact(any())).thenReturn(CassandraOperationStatus.OK); when(componentsUtils.getResponseFormat(any(ActionStatus.class))).thenReturn(new ResponseFormat()); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactResolverTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactResolverTest.java index 18af7a035a..dc89156ee9 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactResolverTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactResolverTest.java @@ -25,10 +25,13 @@ import org.junit.Test; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.model.ArtifactDefinition; import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.Operation; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.Service; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import static org.junit.Assert.assertNotNull; @@ -68,6 +71,7 @@ public class ArtifactResolverTest { resource.setDeploymentArtifacts(artifact1Map); resource.setArtifacts(artifact2Map); + resource.setInterfaces(createInterfaceArtifact()); service.setDeploymentArtifacts(artifact1Map); service.setArtifacts(artifact2Map); @@ -77,6 +81,26 @@ public class ArtifactResolverTest { componentInstance.setArtifacts(artifact2Map); } + private Map createInterfaceArtifact() { + Operation operation = new Operation(); + ArtifactDefinition artifact4 = new ArtifactDefinition(); + artifact4.setUniqueId("a4"); + operation.setImplementation(artifact4); + HashMap operationsMap = new HashMap<>(); + operationsMap.put("operation", operation); + InterfaceDefinition interfaceDefinition = new InterfaceDefinition(); + interfaceDefinition.setOperationsMap(operationsMap); + Map interfaces = new HashMap<>(1); + interfaces.put("someKey", interfaceDefinition); + return interfaces; + } + + @Test + public void findArtifactOnComponent_resourceInterfaceOperation() throws Exception { + assertNull(testInstance.findArtifactOnComponent(resource, ComponentTypeEnum.RESOURCE, "someId")); + assertNotNull(testInstance.findArtifactOnComponent(resource, ComponentTypeEnum.RESOURCE, "a4")); + } + @Test public void findArtifactOnComponent_noArtifactsOnComponent() throws Exception { assertNull(testInstance.findArtifactOnComponent(noArtifactsResource, ComponentTypeEnum.RESOURCE, "someId")); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java index f51d06d53a..bde1bbb3a1 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java @@ -31,6 +31,8 @@ import org.openecomp.sdc.be.components.validation.InterfaceOperationValidation; import org.openecomp.sdc.be.components.validation.UserValidations; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao; +import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; import org.openecomp.sdc.be.dao.jsongraph.TitanDao; import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; @@ -108,7 +110,7 @@ public class InterfaceOperationBusinessLogicTest implements InterfaceOperationTe WebAppContextWrapper webAppContextWrapper = Mockito.mock(WebAppContextWrapper.class); UserValidations userValidations = Mockito.mock(UserValidations.class); WebApplicationContext webAppContext = Mockito.mock(WebApplicationContext.class); - + ArtifactCassandraDao artifactCassandraDao = Mockito.mock(ArtifactCassandraDao.class); InterfaceOperation interfaceOperation = Mockito.mock(InterfaceOperation.class); InterfaceOperationValidation operationValidator = Mockito.mock(InterfaceOperationValidation.class); @@ -208,6 +210,7 @@ public class InterfaceOperationBusinessLogicTest implements InterfaceOperationTe bl.setUserValidations(userValidations); bl.setInterfaceOperation(interfaceOperation); bl.setInterfaceOperationValidation(operationValidator); + bl.setArtifactCassandraDao(artifactCassandraDao); Resource resourceCsar = createResourceObjectCsar(true); setCanWorkOnResource(resourceCsar); Either oldResourceRes = Either.left(resourceCsar); @@ -240,6 +243,7 @@ public class InterfaceOperationBusinessLogicTest implements InterfaceOperationTe public void deleteInterfaceOperationTest() { validateUserRoles(Role.ADMIN, Role.DESIGNER); when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(createResourceForInterfaceOperation())); + when(artifactCassandraDao.deleteArtifact(any(String.class))).thenReturn(CassandraOperationStatus.OK); Set idsToDelete = new HashSet<>(); idsToDelete.add(operationId); @@ -257,6 +261,19 @@ public class InterfaceOperationBusinessLogicTest implements InterfaceOperationTe Assert.assertFalse(deleteResourceResponseFormatEither.isLeft()); } + + @Test + public void deleteInterfaceOperationFailToDeleteArtifactTest() { + when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(createResourceForInterfaceOperation())); + when(artifactCassandraDao.deleteArtifact(any(String.class))).thenReturn(CassandraOperationStatus.GENERAL_ERROR); + validateUserRoles(Role.ADMIN, Role.DESIGNER); + Set idsToDelete = new HashSet<>(); + idsToDelete.add(operationId); + + Either deleteResourceResponseFormatEither = bl.deleteInterfaceOperation(resourceId, idsToDelete, user, true); + Assert.assertTrue(deleteResourceResponseFormatEither.isRight()); + } + @Test public void interfaceOperationFailedScenarioTest() { validateUserRoles(Role.ADMIN, Role.DESIGNER); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java index 792521c484..7e8d1b2081 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java @@ -166,6 +166,19 @@ public class InterfaceOperationValidationTest implements InterfaceOperationTestU Assert.assertTrue(booleanResponseFormatEither.isLeft()); } + @Test + public void testInterfaceOperationeInputParamNameEmpty() { + operationInputDefinitionList.add(createMockOperationInputDefinition(" ")); + operationInputDefinitionList.add(createMockOperationInputDefinition("label1")); + Collection operations = createInterfaceOperationData("op2", + "interface operation2",new ArtifactDefinition(), operationInputDefinitionList,"update"); + + + Either booleanResponseFormatEither = interfaceOperationValidationUtilTest + .validateInterfaceOperations(operations, RESOURCE_ID, false); + Assert.assertTrue(booleanResponseFormatEither.isRight()); + } + private Set createInterfaceOperationData( String uniqueID, String description, ArtifactDefinition artifactDefinition, ListDataDefinition inputs, String name) { return Sets.newHashSet(createInterfaceOperation(uniqueID, description, artifactDefinition, inputs, name)); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/OperationArtifactUtilTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/OperationArtifactUtilTest.java new file mode 100644 index 0000000000..dc964be430 --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/OperationArtifactUtilTest.java @@ -0,0 +1,61 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * 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. + */ +package org.openecomp.sdc.be.tosca.utils; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.util.HashMap; +import org.junit.BeforeClass; +import org.junit.Test; +import org.openecomp.sdc.be.DummyConfigurationManager; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.Resource; + +public class OperationArtifactUtilTest { + + @BeforeClass + public static void setUp() throws Exception { + new DummyConfigurationManager(); + } + + @Test + public void testCorrectPathForOperationArtifacts() { + Component component = new Resource(); + component.setNormalizedName("normalizedComponentName"); + final InterfaceDefinition addedInterface = new InterfaceDefinition(); + final OperationDataDefinition op = new OperationDataDefinition(); + final ArtifactDataDefinition implementation = new ArtifactDataDefinition(); + implementation.setArtifactName("createBPMN.bpmn"); + op.setImplementation(implementation); + addedInterface.setOperations(new HashMap<>()); + addedInterface.getOperations().put("create", op); + final String interfaceType = "normalizedComponentName-interface"; + ((Resource) component).setInterfaces(new HashMap<>()); + ((Resource) component).getInterfaces().put(interfaceType, addedInterface); + final String actualArtifactPath = OperationArtifactUtil.createOperationArtifactPath(component.getNormalizedName(), interfaceType, op); + String expectedArtifactPath ="Artifacts"+ File.separator+"normalizedComponentName"+File.separator + +"normalizedComponentName-interface"+File.separator+"Deployment" + +File.separator+"Workflows"+File.separator+"BPMN" + +File.separator+"createBPMN.bpmn"; + + + assertEquals(expectedArtifactPath,actualArtifactPath); + } +} \ No newline at end of file diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java index afe3e21650..80c22022a1 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java @@ -76,7 +76,7 @@ public enum ActionStatus { GROUP_MEMBER_EMPTY, GROUP_TYPE_ALREADY_EXIST, GROUP_TYPE_ILLEGAL_PER_COMPONENT, // CSAR - MISSING_CSAR_UUID, CSAR_INVALID, CSAR_INVALID_FORMAT, CSAR_NOT_FOUND, YAML_NOT_FOUND_IN_CSAR, VSP_ALREADY_EXISTS, RESOURCE_LINKED_TO_DIFFERENT_VSP, RESOURCE_FROM_CSAR_NOT_FOUND, AAI_ARTIFACT_GENERATION_FAILED, ASSET_NOT_FOUND_DURING_CSAR_CREATION, ARTIFACT_PAYLOAD_NOT_FOUND_DURING_CSAR_CREATION, TOSCA_SCHEMA_FILES_NOT_FOUND, ARTIFACT_NAME_INVALID, + MISSING_CSAR_UUID, CSAR_INVALID, CSAR_INVALID_FORMAT, CSAR_NOT_FOUND, YAML_NOT_FOUND_IN_CSAR, VSP_ALREADY_EXISTS, RESOURCE_LINKED_TO_DIFFERENT_VSP, RESOURCE_FROM_CSAR_NOT_FOUND, AAI_ARTIFACT_GENERATION_FAILED, ASSET_NOT_FOUND_DURING_CSAR_CREATION, ARTIFACT_PAYLOAD_NOT_FOUND_DURING_CSAR_CREATION, TOSCA_SCHEMA_FILES_NOT_FOUND, ARTIFACT_NAME_INVALID,ERROR_DURING_CSAR_CREATION, // Group GROUP_HAS_CYCLIC_DEPENDENCY, GROUP_ALREADY_EXIST, GROUP_TYPE_IS_INVALID, GROUP_MISSING_GROUP_TYPE, GROUP_INVALID_COMPONENT_INSTANCE, GROUP_INVALID_TOSCA_NAME_OF_COMPONENT_INSTANCE, GROUP_IS_MISSING, GROUP_ARTIFACT_ALREADY_ASSOCIATED, GROUP_ARTIFACT_ALREADY_DISSOCIATED, GROUP_PROPERTY_NOT_FOUND, INVALID_VF_MODULE_NAME, INVALID_VF_MODULE_NAME_MODIFICATION, INVALID_VF_MODULE_TYPE, @@ -105,12 +105,12 @@ public enum ActionStatus { //External References Statuses EXT_REF_ALREADY_EXIST, EXT_REF_NOT_FOUND, - + POLICY_TARGET_DOES_NOT_EXIST, POLICY_TARGET_TYPE_DOES_NOT_EXIST, //InterfaceOperation INTERFACE_OPERATION_NOT_FOUND, INTERFACE_OPERATION_TYPE_ALREADY_IN_USE, INTERFACE_OPERATION_TYPE_MANDATORY, INTERFACE_OPERATION_TYPE_INVALID, - INTERFACE_OPERATION_DESCRIPTION_MAX_LENGTH, INTERFACE_OPERATION_INPUT_NAME_INVALID, INTERFACE_OPERATION_NOT_DELETED + INTERFACE_OPERATION_DESCRIPTION_MAX_LENGTH, INTERFACE_OPERATION_INPUT_NAME_ALREADY_IN_USE, INTERFACE_OPERATION_NOT_DELETED, INTERFACE_OPERATION_INPUT_NAME_MANDATORY ; } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ArtifactsOperations.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ArtifactsOperations.java index cbd612d024..4782851e26 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ArtifactsOperations.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ArtifactsOperations.java @@ -21,6 +21,7 @@ package org.openecomp.sdc.be.model.jsontitan.operations; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -40,13 +41,16 @@ import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition; import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; 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.datatypes.tosca.ToscaDataDefinition; import org.openecomp.sdc.be.model.ArtifactDefinition; import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; 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; @@ -88,7 +92,7 @@ public class ArtifactsOperations extends BaseOperation { } - public Either updateArifactOnResource(ArtifactDefinition artifactInfo, String id, String artifactId, NodeTypeEnum type, String instanceId) { + public Either updateArtifactOnResource(ArtifactDefinition artifactInfo, String id, String artifactId, NodeTypeEnum type, String instanceId) { Either status = updateArtifactOnGraph(id, artifactInfo, type, artifactId, instanceId, true, false); if (status.isRight()) { @@ -141,6 +145,10 @@ public class ArtifactsOperations extends BaseOperation { if (foundArtifact == null) { foundArtifact = getArtifactByLabelAndId(parentId, id, EdgeLabelEnum.SERVICE_API_ARTIFACTS); } + if (foundArtifact == null) { + foundArtifact = findInterfaceArtifact(parentId, id); + + } if (foundArtifact == null) { result = Either.right(StorageOperationStatus.NOT_FOUND); @@ -151,6 +159,47 @@ public class ArtifactsOperations extends BaseOperation { return Either.left(artifactDefResult); } + private ArtifactDataDefinition findInterfaceArtifact(String parentId, String id) { + Either, TitanOperationStatus> dataFromGraph = getDataFromGraph(parentId, EdgeLabelEnum.INTERFACE_ARTIFACTS); + if (dataFromGraph.isRight()){ + log.debug("failed to fetch interfaces {} for tosca element with id {}, error {}", id, parentId ,dataFromGraph.right().value()); + return null; + } + + Map interfaceDefinitionMap = dataFromGraph.left().value(); + if(interfaceDefinitionMap == null) { + return null; + } + Collection interfaces = interfaceDefinitionMap.values(); + if (interfaces == null){ + return null; + } + for (InterfaceDataDefinition interfaceDataDefinition : interfaces){ + Map operationsMap = interfaceDataDefinition.getOperations(); + if (operationsMap == null) { + return null; + } + ArtifactDataDefinition implementationArtifact = getArtifactDataDefinition(id, operationsMap); + if (implementationArtifact != null) + return implementationArtifact; + } + return null; + } + + private ArtifactDataDefinition getArtifactDataDefinition(String id, + Map operationsMap) { + for(OperationDataDefinition operationDataDefinition : operationsMap.values()){ + ArtifactDataDefinition implementationArtifact = operationDataDefinition.getImplementation(); + if(implementationArtifact != null){ + String uniqueId = implementationArtifact.getUniqueId(); + if (id.equals(uniqueId)) { + return implementationArtifact; + } + } + } + return null; + } + public Either removeArifactFromResource(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact) { Either status = removeArtifactOnGraph(id, artifactId, type, deleteMandatoryArtifact); @@ -336,7 +385,7 @@ public class ArtifactsOperations extends BaseOperation { if (envList != null && !envList.isEmpty()) { envList.forEach(a -> { a.setGeneratedFromId(newArtifactId); - updateArifactOnResource(a, id, a.getUniqueId(), type, instanceId); + updateArtifactOnResource(a, id, a.getUniqueId(), type, instanceId); }); @@ -345,7 +394,7 @@ public class ArtifactsOperations extends BaseOperation { } public Either updateHeatEnvPlaceholder(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type) { - return updateArifactOnResource(artifactInfo, parentId, artifactInfo.getUniqueId(), type, null); + return updateArtifactOnResource(artifactInfo, parentId, artifactInfo.getUniqueId(), type, null); } // public Either, StorageOperationStatus> getHeatParamsForEnv(ArtifactDefinition heatEnvArtifact, String parentId) { diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/InterfaceOperationDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/InterfaceOperationDataDefinition.java index 21c73e3ee8..0283f4ca46 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/InterfaceOperationDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/InterfaceOperationDataDefinition.java @@ -22,13 +22,14 @@ import java.io.Serializable; import com.fasterxml.jackson.annotation.JsonCreator; import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; +import static org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields.ARTIFACT_UUID; import static org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields.DESCRIPTION; -import static org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields.IO_WORKFLOW_ID; import static org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields.TOSCA_RESOURCE_NAME; import static org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields.UNIQUE_ID; import static org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields.IO_INPUT_PARAMETERS; import static org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields.IO_OPERATION_TYPE; import static org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields.IO_OUTPUT_PARAMETERS; + public class InterfaceOperationDataDefinition extends ToscaDataDefinition implements Serializable { @JsonCreator @@ -44,7 +45,7 @@ public class InterfaceOperationDataDefinition extends ToscaDataDefinition implem setDescription(iodd.getDescription()); setToscaResourceName(iodd.getToscaResourceName()); setOperationType(iodd.getOperationType()); - setWorkflowId(iodd.getWorkflowId()); + setArtifactUUID(iodd.getArtifactUUID()); } public ListDataDefinition getInputParams() { @@ -93,10 +94,10 @@ public class InterfaceOperationDataDefinition extends ToscaDataDefinition implem setToscaPresentationValue(TOSCA_RESOURCE_NAME, toscaResourceName); } - public String getWorkflowId() { - return (String) getToscaPresentationValue(IO_WORKFLOW_ID); + public String getArtifactUUID() { + return (String) getToscaPresentationValue(ARTIFACT_UUID); } - public void setWorkflowId(String workflowId) { - setToscaPresentationValue(IO_WORKFLOW_ID, workflowId); + public void setArtifactUUID(String artifactUUID) { + setToscaPresentationValue(ARTIFACT_UUID, artifactUUID); } } -- cgit 1.2.3-korg