Delete workflow artifact and add artifact to CSAR 91/44091/10
authorshrek2000 <orenkle@amdocs.com>
Tue, 24 Apr 2018 13:46:33 +0000 (16:46 +0300)
committerVitaly Emporopulo <Vitaliy.Emporopulo@amdocs.com>
Wed, 25 Apr 2018 14:22:16 +0000 (14:22 +0000)
Added delete artifact codes, add artifact to CSAR and refactored  operation Business logic.

Change-Id: Iaad3f26795633076d1362bfd33631acc9fcf7aa1
Issue-ID: SDC-1060
Signed-off-by: shrek2000 <orenkle@amdocs.com>
21 files changed:
catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarArtifactsAndGroupsBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactResolverImpl.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java
catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/InterfaceUIDataConverter.java
catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java
catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java
catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceInterfaceOperationServlet.java
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/OperationArtifactUtil.java [new file with mode: 0644]
catalog-be/src/main/resources/config/error-configuration.yaml
catalog-be/src/test/java/org/openecomp/sdc/be/components/InterfaceOperationTestUtils.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactBusinessLogicTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactResolverTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/OperationArtifactUtilTest.java [new file with mode: 0644]
catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ArtifactsOperations.java
common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/InterfaceOperationDataDefinition.java

index 0ee2dab..8c6b7dd 100644 (file)
@@ -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<ArtifactDefinition, StorageOperationStatus> 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<ArtifactDefinition, StorageOperationStatus> updateArifactOnResource = artifactToscaOperation
-                    .updateArifactOnResource(currentInfo, resource.getUniqueId(), currentInfo.getUniqueId(),
+                    .updateArtifactOnResource(currentInfo, resource.getUniqueId(), currentInfo.getUniqueId(),
                             null, null);
             if (updateArifactOnResource.isRight()) {
                 log.debug(
index fcaf5cd..e79efbc 100644 (file)
 
 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<ArtifactDefinition> getAllComponentsArtifacts(Component component, ComponentTypeEnum componentType) {
         Map<String, ArtifactDefinition> deploymentArtifacts = Optional.ofNullable(component.getDeploymentArtifacts()).orElse(Collections.emptyMap());
         Map<String, ArtifactDefinition> artifacts = Optional.ofNullable(component.getArtifacts()).orElse(Collections.emptyMap());
+        Map<String, ArtifactDefinition> interfaceArtifacts= Collections.emptyMap();
+        if (componentType == ComponentTypeEnum.RESOURCE) {
+            Map<String, InterfaceDefinition> 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<String, ArtifactDefinition> 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<ArtifactDefinition> getAllInstanceArtifacts(ComponentInstance instance) {
index 39ad806..c9250ae 100644 (file)
@@ -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<Either<ArtifactDefinition, Operation>, 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<Either<ArtifactDefinition, Operation>, 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<Either<ArtifactDefinition, Operation>, 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<ResponseFormat> errorWrapper = new Wrapper<>();
 
@@ -279,7 +299,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic {
         Either<Either<ArtifactDefinition, Operation>, 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<Either<ArtifactDefinition, Operation>, 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<ActionStatus, ResponseFormat> 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<Either<ArtifactDefinition, Operation>, 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<Either<ArtifactDefinition, Operation>, ResponseFormat> resultOp = null;
         Either<ArtifactDefinition, Operation> 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<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation.updateArifactOnResource(artifactInfo, parent
+            NodeTypeEnum convertParentType = convertParentType(componentType);
+            Either<ArtifactDefinition, StorageOperationStatus> 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<String, ArtifactDefinition> deploymentArtifacts = parent.getDeploymentArtifacts();
                     Optional<Entry<String, ArtifactDefinition>> 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<Either<ArtifactDefinition, Operation>, 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<Either<ArtifactDefinition, Operation>, ResponseFormat> resultOp;
+        if (decodedPayload == null) {
+            if (!artifactDefinition.getMandatory() || artifactDefinition.getEsId() != null) {
+                Either<ESArtifactData, CassandraOperationStatus> 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<Resource, StorageOperationStatus> 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> 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<String, Operation> operationsMap = gotInterface.getOperationsMap();
+        Optional<Operation> 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<InterfaceDefinition, StorageOperationStatus> 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<byte[], ResponseFormat> 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<ArtifactDefinition, StorageOperationStatus> updateArifactRes = artifactToscaOperation.updateArifactOnResource(currArtifact, parent
+            Either<ArtifactDefinition, StorageOperationStatus> 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<ArtifactDefinition, StorageOperationStatus> operationStatus = artifactToscaOperation.updateArifactOnResource(currHeatArtifact, parent
+                Either<ArtifactDefinition, StorageOperationStatus> 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<ArtifactDefinition, ResponseFormat> updateArtifactOnInterfaceOperationByResourceUUID(
+            String data, HttpServletRequest request, ComponentTypeEnum componentType,
+            String componentUuid, String artifactUUID, String operationUUID,
+            Map<AuditingFieldsKeysEnum, Object> additionalParams, ArtifactOperationInfo operation) {
+        Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
+        Either<ArtifactDefinition, ResponseFormat> updateArtifactResult;
+        Either<Either<ArtifactDefinition, Operation>, 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<ComponentMetadataData, StorageOperationStatus> 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<String, ResponseFormat> 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<String, ResponseFormat> fetchInterfaceName(String componentId) {
+        Either<Resource, StorageOperationStatus> 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
      *
index 05e7fe0..c04eb29 100644 (file)
@@ -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<Resource, ResponseFormat> deleteInterfaceOperation(String resourceId, Set<String> interfaceOperationToDelete, User user, boolean lock) {
         Resource resourceToDelete = initResourceToDeleteWFOp(resourceId, interfaceOperationToDelete);
         Either<Resource, ResponseFormat> 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<Resource, StorageOperationStatus> 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<Boolean, ResponseFormat> lockResult = lockComponent(resource.getUniqueId(), resource, "Delete interface Operation on a resource");
+            Either<Boolean, ResponseFormat> 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<InterfaceDefinition, ResponseFormat> deleteEither;
 
             for(String operationToDelete : interfaceOperationToDelete) {
-                deleteEither = deleteOperationFromInterface(interfaceDefinition, operationToDelete);
+                Either<Pair<InterfaceDefinition, Operation>, 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<InterfaceDefinition, StorageOperationStatus> 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<Set<String>, StorageOperationStatus> deleteInterface = interfaceOperation.deleteInterface(resource, Sets.newHashSet(interfaceDef.getUniqueId()));
+            if(interfaceDefinition.getOperationsMap().isEmpty()){
+                Either<Set<String>, 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<InterfaceDefinition,ResponseFormat> deleteOperationFromInterface(InterfaceDefinition interfaceDefinition, String operationId){
+    private Either<Pair<InterfaceDefinition, Operation>,ResponseFormat> deleteOperationFromInterface(InterfaceDefinition interfaceDefinition, String operationId){
         Optional<Map.Entry<String, Operation>> 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<String, Operation> 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<InterfaceDefinition,ResponseFormat> 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<Resource, ResponseFormat> resourceEither = getResourceDetails(resourceId);
+        if (resourceEither.isRight()){
+            return resourceEither;
+        }
+
         Resource storedResource = resourceEither.left().value();
 
         Map<String, Operation> interfaceOperations = InterfaceUtils
@@ -386,13 +416,13 @@ public class InterfaceOperationBusinessLogic extends ComponentBusinessLogic{
 
     @Override
     public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId,
-                                                      ComponentTypeEnum componentTypeEnum, String userId, String searchText) {
+                                                                                                              ComponentTypeEnum componentTypeEnum, String userId, String searchText) {
         return null;
     }
 
     @Override
     public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String resourceId,
-                                                                    List<String> dataParamsToReturn) {
+                                                                                                   List<String> dataParamsToReturn) {
         ComponentParametersView paramsToRetuen = new ComponentParametersView(dataParamsToReturn);
         Either<Resource, StorageOperationStatus> resourceResultEither = toscaOperationFacade.getToscaElement(resourceId,
                 paramsToRetuen);
index 3d3cca4..439c8bd 100644 (file)
@@ -204,25 +204,31 @@ public class InterfaceOperationValidation {
     }
     private Either<Boolean, ResponseFormat> 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<Boolean, Set<String>> 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<Boolean, Set<String>> isInputParametersUnique(Operation operationDataDefinition) {
-
         Set<String> inputParamNamesSet = new HashSet<>();
         Set<String> 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<String, String> operationTypes) {
index 7885ab1..27b1b7e 100644 (file)
@@ -36,7 +36,8 @@ public class InterfaceUIDataConverter {
     ListDataDefinition<OperationInputDefinition> inputs = new ListDataDefinition<>();
     if (inputParams != null) {
       List<OperationInputDefinition> 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<OperationInputDefinition> inputs = operationData.getInputs();
-    List<InterfaceOperationParamDataDefinition> inputParamList = inputs.getListToscaDataDefinition().stream().map(a -> new InterfaceOperationParamDataDefinition(a.getName(), a.getInputId())).collect(
+    List<InterfaceOperationParamDataDefinition> inputParamList = inputs.getListToscaDataDefinition().stream()
+            .map(a -> new InterfaceOperationParamDataDefinition(a.getName(), a.getInputId())).collect(
             Collectors.toList());
     ListDataDefinition<InterfaceOperationParamDataDefinition> 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;
   }
index 70225c0..b634abb 100644 (file)
@@ -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<Response> 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<AuditingFieldsKeysEnum, Object> 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<ArtifactDefinition, ResponseFormat> 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<String, String> 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
      *
index 566daec..5602704 100644 (file)
@@ -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;
+    }
 
 
 }
index 49bce3b..b51fc00 100644 (file)
@@ -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;
index ed3a246..060e7dc 100644 (file)
@@ -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.
 
 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, byte[]>(component, mainYaml));
 
@@ -302,9 +307,9 @@ public class CsarUtils {
 
         if (dependencies != null && !dependencies.isEmpty()) {
             for (Triple<String, String, Component> d : dependencies) {
-                    String cassandraId = d.getMiddle();
+                String cassandraId = d.getMiddle();
                 Component childComponent = d.getRight();
-                    Either<byte[], ActionStatus> entryData = getEntryData(cassandraId, childComponent);
+                Either<byte[], ActionStatus> 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<ArtifactDefinition> 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<ZipOutputStream, ResponseFormat> 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<String> 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<ArtifactDefinition> getAAIArtifatcsForDelete(List<ArtifactDefinition> artifactsFromAAI, Component component) {
 
         Set<String> aaiLabels = artifactsFromAAI.stream()
-                .map(ArtifactDefinition::getArtifactLabel)
-                .collect(Collectors.toSet());
+                                                .map(ArtifactDefinition::getArtifactLabel)
+                                                .collect(Collectors.toSet());
 
         List<ArtifactDefinition> 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<ArtifactDefinition> 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<ArtifactDefinition> getAAIArtifatcsForCreate(List<ArtifactDefinition> 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<ActionStatus, ResponseFormat> handleAAIArtifactsInDataModelByOperationType(Component component, List<ArtifactDefinition> generatedArtifactsDefinitions, ArtifactOperationInfo operationType, User user, boolean shouldLock,
@@ -748,7 +753,7 @@ public class CsarUtils {
         } else {
             Either<byte[], ActionStatus> 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<SdcSchemaFilesData> listOfSchemas = specificSchemaFiles.left().value();
+        List<SdcSchemaFilesData> 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<String, Set<List<String>>> 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<String, Set<List<String>>> 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<ZipOutputStream, ResponseFormat> writeAllFilesToScar(Component mainComponent, CsarDefinition csarDefinition, ZipOutputStream zipstream, boolean isInCertificationRequest) throws IOException{
+    private Either<ZipOutputStream, ResponseFormat> writeAllFilesToCsar(Component mainComponent, CsarDefinition csarDefinition, ZipOutputStream zipstream, boolean isInCertificationRequest) throws IOException{
         ComponentArtifacts componentArtifacts = csarDefinition.getComponentArtifacts();
 
-        Either<ZipOutputStream, ResponseFormat> writeComponentArtifactsToSpecifiedtPath = writeComponentArtifactsToSpecifiedtPath(mainComponent, componentArtifacts, zipstream, ARTIFACTS_PATH, isInCertificationRequest);
+        Either<ZipOutputStream, ResponseFormat> 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<String, ArtifactsInfo> componentInstancesArtifacts = mainTypeAndCIArtifacts.getComponentInstancesArtifacts();
@@ -1149,17 +1154,77 @@ 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<ZipOutputStream, ResponseFormat> writeComponentArtifactsToSpecifiedtPath(Component mainComponent, ComponentArtifacts componentArtifacts, ZipOutputStream zipstream,
+    private Either<ZipOutputStream, ResponseFormat> writeOperationsArtifactsToCsar(Component component,
+            ZipOutputStream zipstream) {
+        if (Objects.isNull(((Resource) component).getInterfaces())) {
+            log.debug("Component Name {}- no interfaces found", component.getNormalizedName());
+            return Either.left(zipstream);
+        }
+        final Map<String, InterfaceDefinition> interfaces = ((Resource) component).getInterfaces();
+
+        for (Map.Entry<String, InterfaceDefinition> 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<byte[], ActionStatus> 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<ZipOutputStream, ResponseFormat> writeComponentArtifactsToSpecifiedPath(Component mainComponent, ComponentArtifacts componentArtifacts, ZipOutputStream zipstream,
             String currentPath, boolean isInCertificationRequest) throws IOException {
         Map<String, ComponentTypeArtifacts> componentTypeArtifacts = componentArtifacts.getComponentTypeArtifacts();
         //Keys are defined:
@@ -1182,7 +1247,7 @@ public class CsarUtils {
 
     private Either<ZipOutputStream, ResponseFormat> writeArtifactsInfoToSpecifiedtPath(Component mainComponent, ArtifactsInfo currArtifactsInfo, ZipOutputStream zip, String path, boolean isInCertificationRequest) throws IOException {
         Map<ArtifactGroupTypeEnum, Map<ArtifactTypeEnum, List<ArtifactDefinition>>> artifactsInfo = currArtifactsInfo
-                .getArtifactsInfo();
+                                                                                                            .getArtifactsInfo();
         Set<ArtifactGroupTypeEnum> groupTypeEnumKeySet = artifactsInfo.keySet();
 
         for (ArtifactGroupTypeEnum artifactGroupTypeEnum : groupTypeEnumKeySet) {
@@ -1214,9 +1279,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 (file)
index 0000000..5dd7487
--- /dev/null
@@ -0,0 +1,25 @@
+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();
+    }
+}
index b0f2e21..de5196e 100644 (file)
@@ -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"
+    }
index 52b71c5..18116a4 100644 (file)
@@ -58,7 +58,6 @@ public interface InterfaceOperationTestUtils {
         return operation;
     }
 
-    
 
     default Map<String, Operation> 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<String, Operation> operationMap = new HashMap<>();
         operationMap.put("op1", operation);
         return operationMap;
@@ -90,5 +93,5 @@ public interface InterfaceOperationTestUtils {
 
         return interfaceDefinitionMap;
     }
-    
+
 }
index bebe29f..4ce0740 100644 (file)
@@ -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());
index 18af7a0..dc89156 100644 (file)
@@ -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<String, InterfaceDefinition> createInterfaceArtifact() {
+        Operation operation = new Operation();
+        ArtifactDefinition artifact4 = new ArtifactDefinition();
+        artifact4.setUniqueId("a4");
+        operation.setImplementation(artifact4);
+        HashMap<String, Operation> operationsMap = new HashMap<>();
+        operationsMap.put("operation", operation);
+        InterfaceDefinition interfaceDefinition = new InterfaceDefinition();
+        interfaceDefinition.setOperationsMap(operationsMap);
+        Map<String, InterfaceDefinition> 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"));
index f51d06d..bde1bbb 100644 (file)
@@ -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<Component, StorageOperationStatus> 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<String> 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<String> idsToDelete = new HashSet<>();
+        idsToDelete.add(operationId);
+
+        Either<Resource, ResponseFormat> deleteResourceResponseFormatEither = bl.deleteInterfaceOperation(resourceId, idsToDelete, user, true);
+        Assert.assertTrue(deleteResourceResponseFormatEither.isRight());
+    }
+
     @Test
     public void interfaceOperationFailedScenarioTest() {
         validateUserRoles(Role.ADMIN, Role.DESIGNER);
index 792521c..7e8d1b2 100644 (file)
@@ -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<Operation> operations = createInterfaceOperationData("op2",
+                "interface operation2",new ArtifactDefinition(), operationInputDefinitionList,"update");
+
+
+        Either<Boolean, ResponseFormat> booleanResponseFormatEither = interfaceOperationValidationUtilTest
+                .validateInterfaceOperations(operations, RESOURCE_ID, false);
+        Assert.assertTrue(booleanResponseFormatEither.isRight());
+    }
+
     private Set<Operation> createInterfaceOperationData( String uniqueID, String description, ArtifactDefinition artifactDefinition,
                                                          ListDataDefinition<OperationInputDefinition> 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 (file)
index 0000000..c44d50d
--- /dev/null
@@ -0,0 +1,46 @@
+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
index afe3e21..80c2202 100644 (file)
@@ -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
 
     ;
 }
index cbd612d..4782851 100644 (file)
@@ -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<ArtifactDefinition, StorageOperationStatus> updateArifactOnResource(ArtifactDefinition artifactInfo, String id, String artifactId, NodeTypeEnum type, String instanceId) {
+       public Either<ArtifactDefinition, StorageOperationStatus> updateArtifactOnResource(ArtifactDefinition artifactInfo, String id, String artifactId, NodeTypeEnum type, String instanceId) {
 
                Either<ArtifactDataDefinition, StorageOperationStatus> 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<Map<String, InterfaceDefinition>, 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<String, InterfaceDefinition> interfaceDefinitionMap = dataFromGraph.left().value();
+               if(interfaceDefinitionMap == null) {
+                       return null;
+               }
+               Collection<InterfaceDefinition> interfaces = interfaceDefinitionMap.values();
+               if (interfaces == null){
+                       return null;
+               }
+               for (InterfaceDataDefinition interfaceDataDefinition : interfaces){
+                       Map<String, OperationDataDefinition> 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<String, OperationDataDefinition> 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<ArtifactDefinition, StorageOperationStatus> removeArifactFromResource(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact) {
                Either<ArtifactDefinition, StorageOperationStatus> 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<ArtifactDefinition, StorageOperationStatus> 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<List<HeatParameterDefinition>, StorageOperationStatus> getHeatParamsForEnv(ArtifactDefinition heatEnvArtifact, String parentId) {
index 21c73e3..0283f4c 100644 (file)
@@ -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<InterfaceOperationParamDataDefinition> 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);
     }
 }