Service Workflow changes 50/73350/2
authorsiddharth0905 <siddharth.singh4@amdocs.com>
Thu, 22 Nov 2018 08:07:31 +0000 (13:37 +0530)
committersiddharth0905 <siddharth.singh4@amdocs.com>
Fri, 23 Nov 2018 07:18:21 +0000 (12:48 +0530)
Service workflow change with few bug fixes

Change-Id: Ice2376565bf46fb8d86fb6062654ec54bb2daa43
Issue-ID: SDC-1937
Signed-off-by: siddharth0905 <siddharth.singh4@amdocs.com>
23 files changed:
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/externalapi/servlet/ArtifactExternalServlet.java
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/OperationArtifactUtil.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/InterfacesOperationsToscaUtilTest.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/InterfaceOperation.java
catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.html
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.less
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.ts
catalog-ui/src/app/ng2/services/component-services/component.service.ts
catalog-ui/src/app/ng2/services/workflow.service.ts
openecomp-bdd/features/InterfaceOperation/TestResourceInterfaceOperation.feature
openecomp-bdd/features/InterfaceOperation/TestServiceInterfaceOperation.feature
openecomp-bdd/resources/json/operation/createOperation-with-workflow.json [new file with mode: 0644]
openecomp-bdd/stepDefinitions/InterfaceOperationSteps.js

index c7f92d2..2b23c52 100644 (file)
@@ -54,20 +54,20 @@ public class ArtifactResolverImpl implements ArtifactsResolver {
         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, InterfaceDefinition> interfaces = 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, interfaceArtifacts, serviceApiArtifacts);
     }
 
index fc4a739..65a87d4 100644 (file)
@@ -3100,24 +3100,23 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic {
         }
         NodeTypeEnum convertParentType = convertParentType(componentType);
         // fetch the resource from storage
-        Either<Resource, StorageOperationStatus> resourceStorageOperationStatusEither =
+        Either<Component, StorageOperationStatus> componentStorageOperationStatusEither =
                 toscaOperationFacade.getToscaElement(parentId);
-        if (resourceStorageOperationStatusEither.isRight()) {
-            StorageOperationStatus errorStatus = resourceStorageOperationStatusEither.right().value();
+        if (componentStorageOperationStatusEither.isRight()) {
+            StorageOperationStatus errorStatus = componentStorageOperationStatusEither.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();
+        Component storedComponent = componentStorageOperationStatusEither.left().value();
 
         String interfaceToscaName = InterfaceUtils.createInterfaceToscaResourceName(
-                storedResource.getName());
+                storedComponent.getName());
         //fetch the interface from storage
-        Optional<InterfaceDefinition> interfaceDefinition = storedResource.getInterfaces().values()
-                                                                          .stream()
-                                                                          .filter(interfaceDef -> interfaceDef.getToscaResourceName()
-                        .equals(interfaceToscaName))
-                                                                          .findFirst();
+        Optional<InterfaceDefinition> interfaceDefinition =
+                storedComponent.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(
@@ -3154,7 +3153,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic {
         operation.setImplementation(implementationArtifact);
         gotInterface.setOperationsMap(operationsMap);
         Either<InterfaceDefinition, StorageOperationStatus> interfaceDefinitionStorageOperationStatusEither =
-                interfaceOperation.updateInterface(storedResource.getUniqueId(), gotInterface);
+                interfaceOperation.updateInterface(storedComponent.getUniqueId(), gotInterface);
         if (interfaceDefinitionStorageOperationStatusEither.isRight()){
             StorageOperationStatus storageOperationStatus = interfaceDefinitionStorageOperationStatusEither.right().value();
             ActionStatus actionStatus =
@@ -3163,16 +3162,6 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic {
         }
 
         String uniqueId = implementationArtifact.getUniqueId();
-        Either<Long, CassandraOperationStatus> artifactCount = artifactCassandraDao.getCountOfArtifactById(uniqueId);
-        if(artifactCount.isLeft()){
-            CassandraOperationStatus cassandraOperationStatus = artifactCassandraDao.deleteArtifact(uniqueId);
-            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));
-            }
-        }
         artifactData.setId(uniqueId);
         CassandraOperationStatus cassandraOperationStatus = artifactCassandraDao.saveArtifact(artifactData);
         if(cassandraOperationStatus != CassandraOperationStatus.OK){
@@ -3647,23 +3636,25 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic {
                 }
             }
         }
-        switch (component.getComponentType()) {
-            case RESOURCE:
-                Map<String, InterfaceDefinition> interfaces = ((Resource) component).getInterfaces();
-                if (!found && interfaces != null) {
-                    for (Map.Entry<String, InterfaceDefinition> entry : interfaces.entrySet()) {
-                        Map<String, Operation> operations = entry.getValue().getOperationsMap();
-                        for (Map.Entry<String, Operation> entryOp : operations.entrySet()) {
-                            if (entryOp.getValue().getImplementation() != null && entryOp.getValue()
-                                                                                         .getImplementation()
-                                                                                         .getUniqueId()
-                                                                                         .equals(artifactId)) {
-                                found = true;
-                                break;
-                            }
-                        }
+
+        Map<String, InterfaceDefinition> interfaces = component.getInterfaces();
+        if (!found && interfaces != null) {
+            for (Map.Entry<String, InterfaceDefinition> entry : interfaces.entrySet()) {
+                Map<String, Operation> operations = entry.getValue().getOperationsMap();
+                for (Map.Entry<String, Operation> entryOp : operations.entrySet()) {
+                    if (entryOp.getValue().getImplementation() != null && entryOp.getValue()
+                            .getImplementation()
+                            .getUniqueId()
+                            .equals(artifactId)) {
+                        found = true;
+                        break;
                     }
                 }
+            }
+        }
+
+        switch (component.getComponentType()) {
+            case RESOURCE:
                 break;
             case SERVICE:
                 Map<String, ArtifactDefinition> apiArtifacts = ((Service) component).getServiceApiArtifacts();
@@ -5106,18 +5097,18 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic {
     }
 
     private Either<String, ResponseFormat> fetchInterfaceName(String componentId) {
-        Either<Resource, StorageOperationStatus> resourceStorageOperationStatusEither =
+        Either<Component, StorageOperationStatus> componentStorageOperationStatusEither =
                 toscaOperationFacade.getToscaElement(componentId);
-        if (resourceStorageOperationStatusEither.isRight()) {
-            StorageOperationStatus errorStatus = resourceStorageOperationStatusEither.right().value();
-            log.debug("Failed to fetch resource information by resource id, error {}", errorStatus);
+        if (componentStorageOperationStatusEither.isRight()) {
+            StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
+            log.debug("Failed to fetch component information by component id, error {}", errorStatus);
             return Either.right(componentsUtils
                     .getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
         }
-        Resource storedResource = resourceStorageOperationStatusEither.left().value();
+        Component storedComponent = componentStorageOperationStatusEither.left().value();
 
         return Either.left(InterfaceUtils.createInterfaceToscaResourceName(
-                storedResource.getName()));
+                storedComponent.getName()));
     }
 
 
index 26e256f..fed2cac 100644 (file)
@@ -208,7 +208,7 @@ public class InterfaceOperationBusinessLogic extends BaseBusinessLogic {
                 if (getOperationEither.isRight()){
                     return Either.right(getOperationEither.right().value());
                 }
-                operation.setImplementation(getOperationEither.left().value().getImplementation());
+                updateExistingOperation(operation, getOperationEither.left().value().getImplementation().getArtifactUUID());
                 result = interfaceOperation.updateInterfaceOperation(componentId, interfaceDefinition, operation);
             }
 
@@ -265,6 +265,15 @@ public class InterfaceOperationBusinessLogic extends BaseBusinessLogic {
         operation.setImplementation(artifactDefinition);
     }
 
+    private void updateExistingOperation(Operation operation, String artifactUUID){
+        ArtifactDefinition artifactDefinition = new ArtifactDefinition();
+        artifactDefinition.setArtifactUUID(artifactUUID);
+        artifactDefinition.setUniqueId(artifactUUID);
+        artifactDefinition.setArtifactType(ArtifactTypeEnum.WORKFLOW.getType());
+        artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
+        operation.setImplementation(artifactDefinition);
+    }
+
     private Either<Boolean, ResponseFormat> lockComponentResult(boolean lock, org.openecomp.sdc.be.model.Component component, String action){
         if (lock) {
             Either<Boolean, ResponseFormat> lockResult = lockComponent(component.getUniqueId(), component, action);
index 8c90501..7b650e4 100644 (file)
 
 package org.openecomp.sdc.be.components.validation;
 
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
 import fj.data.Either;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
@@ -33,17 +44,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
 
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
 @Component("interfaceOperationValidation")
 public class InterfaceOperationValidation {
 
@@ -279,8 +279,8 @@ public class InterfaceOperationValidation {
             .anyMatch(inputParam -> inputParam.getName() == null || inputParam.getName().trim().equals(StringUtils.EMPTY));
     }
     private Boolean isOutputParameterNameEmpty(Operation operationDataDefinition) {
-        return operationDataDefinition.getInputs().getListToscaDataDefinition().stream()
-            .anyMatch(inputParam -> inputParam.getName() == null || inputParam.getName().trim().equals(StringUtils.EMPTY));
+        return operationDataDefinition.getOutputs().getListToscaDataDefinition().stream()
+            .anyMatch(outputParam -> outputParam.getName() == null || outputParam.getName().trim().equals(StringUtils.EMPTY));
     }
 
     private  Either<Boolean, ResponseFormat> validateInputPropertyExistInComponent(Operation operation,
@@ -305,7 +305,10 @@ public class InterfaceOperationValidation {
 
     private boolean validateInputExistsInComponent(OperationInputDefinition input,
                                                    List<InputDefinition> inputs) {
-        return inputs.stream().anyMatch(inp -> inp.getUniqueId().equals(input.getInputId()));
+        return inputs.stream().anyMatch(inp -> inp.getUniqueId().equals(input.getInputId()))
+                || ((input.getInputId().contains(".")
+                && inputs.stream().anyMatch(inp -> inp.getUniqueId().equals(
+                    input.getInputId().substring(0, input.getInputId().lastIndexOf(".")))))) ;
     }
 
     private ResponseFormatManager getResponseFormatManager() {
index c53e343..03c5e0f 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.externalapi.servlet;
 
 import com.jcabi.aspects.Loggable;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Map;
+
 import fj.data.Either;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
@@ -65,11 +73,12 @@ import javax.ws.rs.core.Response;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.EnumMap;
 import java.util.HashMap;
 import java.util.Map;
 /**
  * This Servlet serves external users operations on artifacts.
- * 
+ *
  * @author mshitrit
  *
  */
@@ -89,7 +98,7 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet {
     private static String startLog = "Start handle request of ";
 
     @POST
-    @Path("/resources/{uuid}/interfaces/{operationUUID}/artifacts/{artifactUUID}")
+    @Path("/{assetType}/{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 = {
@@ -116,6 +125,7 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet {
             @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 = "Asset type") @PathParam("assetType") String assetType,
             @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,
@@ -125,9 +135,7 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet {
         String requestURI = request.getRequestURI();
         String url = request.getMethod() + " " + requestURI;
         log.debug("{} {}", startLog, url);
-        ComponentTypeEnum componentType = ComponentTypeEnum.RESOURCE;
-        String componentTypeValue = componentType.getValue();
-        ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentTypeValue);
+        ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(assetType);
         ArtifactDefinition artifactDefinition = null;
 
         if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) {
@@ -144,7 +152,9 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet {
             if (responseWrapper.isEmpty()) {
                 ServletContext context = request.getSession().getServletContext();
                 ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context);
-                Either<ArtifactDefinition, ResponseFormat> uploadArtifactEither = artifactsLogic.updateArtifactOnInterfaceOperationByResourceUUID(data, request, componentType, uuid, artifactUUID, operationUUID,
+                Either<ArtifactDefinition, ResponseFormat> uploadArtifactEither = artifactsLogic
+                        .updateArtifactOnInterfaceOperationByResourceUUID(data, request, ComponentTypeEnum
+                                        .findByParamName(assetType), uuid,  artifactUUID, operationUUID,
                         resourceCommonInfo, artifactsLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.UPDATE));
                 if (uploadArtifactEither.isRight()) {
                     log.debug(FAILED_TO_UPDATE_ARTIFACT);
index c3628df..7afad74 100644 (file)
@@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -181,9 +182,13 @@ public class InterfacesOperationsToscaUtil {
         for (OperationInputDefinition input : operation.getInputs().getListToscaDataDefinition()) {
             ToscaProperty toscaInput = new ToscaProperty();
             toscaInput.setDescription(input.getDescription());
-            String mappedPropertyName = getLastPartOfName(input.getInputId());
-            toscaInput.setType(input.getType());
+            String mappedPropertyName = null;
+            if (Objects.nonNull(input.getInputId())) {
+                mappedPropertyName = input.getInputId().substring(input.getInputId().indexOf(DOT) + 1);
+            }
             toscaInput.setDefaultp(createDefaultValue(mappedPropertyName));
+
+            toscaInput.setType(input.getType());
             toscaInput.setRequired(input.isRequired());
             toscaInputs.put(input.getName(), toscaInput);
         }
@@ -195,13 +200,15 @@ public class InterfacesOperationsToscaUtil {
         Map<String, List<String>> getPropertyMap = new HashMap<>();
         List<String> values = new ArrayList<>();
         values.add(SELF);
-        values.add(propertyName);
+        if (Objects.nonNull(propertyName) && !propertyName.isEmpty()) {
+            values.addAll(Arrays.asList(propertyName.split("\\.")));
+        }
+
         getPropertyMap.put(GET_PROPERTY, values);
 
         return getPropertyMap;
     }
 
-
     private static Map<String, Object> getObjectAsMap(Object obj) {
         ObjectMapper objectMapper = new ObjectMapper();
         if (obj instanceof ToscaInterfaceDefinition) {
index b70ae90..0d772cf 100644 (file)
@@ -33,6 +33,7 @@ import org.openecomp.sdc.be.model.Component;
 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 org.openecomp.sdc.be.tosca.CsarUtils;
 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
@@ -53,7 +54,7 @@ public class OperationArtifactUtil {
      */
     static String createOperationArtifactPath(Component component, OperationDataDefinition operation,
                                                      boolean isAssociatedResourceComponent) {
-        if (!(component instanceof Resource)) {
+        if (!(component instanceof Resource || component instanceof Service)) {
             return null;
         }
         if (isAssociatedResourceComponent) {
index e8a698f..4227e5d 100644 (file)
@@ -55,6 +55,7 @@ import org.openecomp.sdc.be.impl.ComponentsUtils;
 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
+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;
@@ -88,7 +89,7 @@ public class InterfaceOperationBusinessLogicTest {
     private final String operationId = "uniqueId1";
     private Operation operation;
 
-    private static final String RESOURCE_NAME = "My-Resource_Name with   space";
+    private static final String RESOURCE_NAME = "Resource1";
 
     private final ServletContext servletContext = Mockito.mock(ServletContext.class);
     private final TitanDao mockTitanDao = Mockito.mock(TitanDao.class);
@@ -175,13 +176,6 @@ public class InterfaceOperationBusinessLogicTest {
 
         //InterfaceOperation
         when(operationValidator.validateInterfaceOperations(anyCollection(), anyObject(), anyBoolean())).thenReturn(Either.left(true));
-        when(interfaceOperation.addInterface(anyString(), anyObject())).thenReturn(Either.left(InterfaceOperationTestUtils.mockInterfaceDefinitionToReturn(RESOURCE_NAME)));
-        when(interfaceOperation.updateInterface(anyString(), anyObject())).thenReturn(Either.left(InterfaceOperationTestUtils.mockInterfaceDefinitionToReturn(RESOURCE_NAME)));
-        when(interfaceOperation.addInterfaceOperation(anyObject(), anyObject(), anyObject())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn()));
-        when(interfaceOperation.updateInterfaceOperation(anyObject(), anyObject(), anyObject())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn()));
-        when(interfaceOperation.deleteInterfaceOperation(anyObject(), anyObject(), anyObject())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn()));
-        when(interfaceOperation.deleteInterfaceOperation(any(),any(), any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn()));
-        when(interfaceOperation.updateInterface(any(),any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockInterfaceDefinitionToReturn(RESOURCE_NAME)));
         when(mockTitanDao.commit()).thenReturn(TitanOperationStatus.OK);
 
         // BL object
@@ -211,12 +205,57 @@ public class InterfaceOperationBusinessLogicTest {
         validateUserRoles(Role.ADMIN, Role.DESIGNER);
         when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource));
         operation = InterfaceOperationTestUtils.createMockOperation();
+        when(interfaceOperation.addInterfaceOperation(any(), any(), any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn()));
+
         Either<Operation, ResponseFormat> interfaceOperation = bl.createInterfaceOperation(resourceId, operation, user, true);
         Assert.assertTrue(interfaceOperation.isLeft());
         Assert.assertNotNull(interfaceOperation.left().value().getWorkflowId());
         Assert.assertNotNull(interfaceOperation.left().value().getWorkflowVersionId());
     }
 
+    @Test
+    public void createInterfaceOperationWithoutInterfaceTest() {
+        Resource resource = createResourceObjectCsar(true);
+        resource.setComponentType(ComponentTypeEnum.RESOURCE);
+        resource.setInterfaces(new HashMap<>());
+        validateUserRoles(Role.ADMIN, Role.DESIGNER);
+        when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource));
+        operation = InterfaceOperationTestUtils.createMockOperation();
+        when(interfaceOperation.addInterfaceOperation(any(), any(), any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn()));
+        when(interfaceOperation.addInterface(anyString(), any())).thenReturn(Either.left(new InterfaceDefinition()));
+
+        Either<Operation, ResponseFormat> interfaceOperation = bl.createInterfaceOperation(resourceId, operation, user, true);
+        Assert.assertTrue(interfaceOperation.isLeft());
+
+    }
+
+    @Test
+    public void shouldFailCreateInterfaceOperationWhenCreateOperationFailedTest() {
+        Resource resource = createResourceObjectCsar(true);
+        resource.setInterfaces(new HashMap<>());
+        validateUserRoles(Role.ADMIN, Role.DESIGNER);
+        when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource));
+        operation = InterfaceOperationTestUtils.createMockOperation();
+        when(interfaceOperation.addInterfaceOperation(any(), any(), any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn()));
+        when(interfaceOperation.addInterface(anyString(), any())).thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR));
+
+        Either<Operation, ResponseFormat> interfaceOperation = bl.createInterfaceOperation(resourceId, operation, user, true);
+        Assert.assertTrue(interfaceOperation.isRight());
+
+    }
+
+    @Test()
+    public void shouldFailWhenCreateInterfaceOperationFailedTest() {
+        Resource resource = createResourceForInterfaceOperation();
+        resource.setComponentType(ComponentTypeEnum.RESOURCE);
+        validateUserRoles(Role.ADMIN, Role.DESIGNER);
+        when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource));
+        operation = InterfaceOperationTestUtils.createMockOperation();
+
+        when(interfaceOperation.addInterfaceOperation(any(), any(), any())).thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+       Assert.assertTrue(bl.createInterfaceOperation(resourceId, operation, user, true).isRight());
+    }
+
     @Test
     public void updateInterfaceOperationTest() {
         validateUserRoles(Role.ADMIN, Role.DESIGNER);
@@ -224,21 +263,47 @@ public class InterfaceOperationBusinessLogicTest {
         Resource resource = createResourceForInterfaceOperation();
         resource.setComponentType(ComponentTypeEnum.RESOURCE);
         when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource));
+        when(interfaceOperation.updateInterfaceOperation(any(), any(), any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn()));
+
         Either<Operation, ResponseFormat> interfaceOperation = bl.updateInterfaceOperation(resourceId, operation, user, true);
         Assert.assertTrue(interfaceOperation.isLeft());
     }
 
+    @Test()
+    public void shouldFailWhenFailedToUpdateInterfaceOperationTest() {
+        validateUserRoles(Role.ADMIN, Role.DESIGNER);
+        operation = InterfaceOperationTestUtils.createMockOperation();
+        Resource resource = createResourceForInterfaceOperation();
+        resource.setComponentType(ComponentTypeEnum.RESOURCE);
+        when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource));
+        when(interfaceOperation.addInterfaceOperation(any(), any(), any())).thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR));
+        Either<Operation, ResponseFormat> interfaceOperation = bl.updateInterfaceOperation(resourceId, operation, user, true);
+        Assert.assertTrue(interfaceOperation.isRight());
+    }
+
     @Test
     public void deleteInterfaceOperationTest() {
         Resource resource = createResourceForInterfaceOperation();
         resource.setComponentType(ComponentTypeEnum.RESOURCE);
         validateUserRoles(Role.ADMIN, Role.DESIGNER);
         when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource));
+        when(interfaceOperation.deleteInterfaceOperation(any(),any(), any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn()));
         when(artifactCassandraDao.deleteArtifact(any(String.class))).thenReturn(CassandraOperationStatus.OK);
         Either<Operation, ResponseFormat> deleteResourceResponseFormatEither = bl.deleteInterfaceOperation(resourceId, operationId, user, true);
         Assert.assertTrue(deleteResourceResponseFormatEither.isLeft());
     }
 
+    @Test()
+    public void shouldFailWhenDeleteInterfaceOperationFailedTest() {
+        Resource resource = createResourceForInterfaceOperation();
+        resource.setComponentType(ComponentTypeEnum.RESOURCE);
+        validateUserRoles(Role.ADMIN, Role.DESIGNER);
+        when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource));
+        when(interfaceOperation.deleteInterfaceOperation(any(),any(), any())).thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR));
+        when(artifactCassandraDao.deleteArtifact(any(String.class))).thenReturn(CassandraOperationStatus.OK);
+        Assert.assertTrue(bl.deleteInterfaceOperation(resourceId, operationId, user, true).isRight());
+
+    }
     @Test
     public void getInterfaceOperationTest() {
         Resource resource = createResourceForInterfaceOperation();
@@ -249,6 +314,37 @@ public class InterfaceOperationBusinessLogicTest {
         Assert.assertTrue(getResourceResponseFormatEither.isLeft());
     }
 
+    @Test
+    public void updateToscaResourceNameWhenComponentNameChanged() {
+        Component newComponent = new Resource();
+        newComponent.setName("newComponent");
+        Component  oldComponent  = createResourceForInterfaceOperation();
+        validateUserRoles(Role.ADMIN, Role.DESIGNER);
+        when(interfaceOperation.updateInterface(anyString(), any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockInterfaceDefinitionToReturn(RESOURCE_NAME)));
+        Assert.assertTrue(bl.validateComponentNameAndUpdateInterfaces(oldComponent, newComponent).isLeft());
+    }
+
+    @Test
+    public void shouldFailWhenComponentNameChangedButUpdateOperationFailed() {
+        Component newComponent = new Resource();
+        newComponent.setName("newComponent");
+        Component  oldComponent  = createResourceForInterfaceOperation();
+        validateUserRoles(Role.ADMIN, Role.DESIGNER);
+        when(interfaceOperation.updateInterface(anyString(), anyObject())).thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+
+        Assert.assertTrue(bl.validateComponentNameAndUpdateInterfaces(oldComponent, newComponent).isRight());
+    }
+
+    @Test(expected = Exception.class)
+    public void shouldThrowExceptionWhenComponentNameChangedButUpdateOperationFailed() {
+        Component newComponent = new Resource();
+        newComponent.setName("newComponent");
+        Component  oldComponent  = createResourceForInterfaceOperation();
+        validateUserRoles(Role.ADMIN, Role.DESIGNER);
+        when(interfaceOperation.updateInterface(anyString(), anyObject())).thenThrow(new Exception());
+        bl.validateComponentNameAndUpdateInterfaces(oldComponent, newComponent).isRight();
+    }
+
     private void validateUserRoles(Role... roles) {
         List<Role> listOfRoles = Stream.of(roles).collect(Collectors.toList());
     }
index 6fe2f13..1a112c5 100644 (file)
@@ -66,7 +66,7 @@ public class InterfaceOperationValidationTest {
     }
 
     @Test
-    public void testValidInterfaceOperation() {
+    public void shouldPassOperationValidationForHappyScenario() {
         operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1"));
         operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1"));
         Collection<Operation> operations = createInterfaceOperationData("op2",
@@ -78,7 +78,7 @@ public class InterfaceOperationValidationTest {
     }
 
     @Test
-    public void testInterfaceOperationDescriptionLength() {
+    public void shouldFailWhenOperationOperationDescriptionLengthInvalid() {
         operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1"));
         operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1"));
         Collection<Operation> operations = createInterfaceOperationData("op2",
@@ -94,7 +94,7 @@ public class InterfaceOperationValidationTest {
 
 
     @Test
-    public void testInterfaceOperationForEmptyType() {
+    public void shouldFailWhenOperationNameIsEmpty() {
         operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1"));
         operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1"));
         Collection<Operation> operations = createInterfaceOperationData("op2",
@@ -106,19 +106,7 @@ public class InterfaceOperationValidationTest {
     }
 
     @Test
-    public void testInterfaceOperationForEmptyInputParam() {
-        operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1"));
-        operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1"));
-        Collection<Operation> operations = createInterfaceOperationData("op2",
-                "interface operation2",new ArtifactDefinition(), operationInputDefinitionList,
-                operationOutputDefinitionList,"input2");
-        Either<Boolean, ResponseFormat> booleanResponseFormatEither = interfaceOperationValidationUtilTest
-                .validateInterfaceOperations(operations, component, false);
-        Assert.assertTrue(booleanResponseFormatEither.isRight());
-    }
-
-    @Test
-    public void testInterfaceOperationForNonUniqueType() {
+    public void shouldFailWhenOperationNamesAreNotUnique() {
         operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1"));
         operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1"));
         Collection<Operation> operations = createInterfaceOperationData("op2",
@@ -130,7 +118,7 @@ public class InterfaceOperationValidationTest {
     }
 
     @Test
-    public void testInterfaceOperationTypeLength() {
+    public void shouldFailWhenOperationNameLengthIsInvalid() {
         operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1"));
         operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1"));
         Collection<Operation> operations = createInterfaceOperationData("op2",
@@ -146,7 +134,7 @@ public class InterfaceOperationValidationTest {
 
 
     @Test
-    public void testInterfaceOperationUniqueInputParamNameInvalid() {
+    public void shouldFailWhenOperationInputParamNamesAreNotUnique() {
         operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1"));
         operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1"));
         operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label2"));
@@ -162,7 +150,7 @@ public class InterfaceOperationValidationTest {
     }
 
     @Test
-    public void testInterfaceOperationUniqueInputParamNameValid() {
+    public void shouldPassWhenOperationInputParamNamesAreUnique() {
         operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1"));
         operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label2"));
         operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1"));
@@ -170,14 +158,28 @@ public class InterfaceOperationValidationTest {
                 "interface operation2",new ArtifactDefinition(), operationInputDefinitionList,
                 operationOutputDefinitionList,"update");
 
+        Either<Boolean, ResponseFormat> booleanResponseFormatEither = interfaceOperationValidationUtilTest
+                .validateInterfaceOperations(operations, component, false);
+        Assert.assertTrue(booleanResponseFormatEither.isLeft());
+    }
 
+    @Test
+    public void shouldPassWhenOperationInputParamNamesHasSubProperty() {
+        operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1"));
+        operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label2"));
+        operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1"));
+        Collection<Operation> operations = createInterfaceOperationData("op2",
+                "interface operation2",new ArtifactDefinition(), operationInputDefinitionList,
+                operationOutputDefinitionList,"update");
+        operationInputDefinitionList.getListToscaDataDefinition().get(0).setInputId(operationInputDefinitionList
+                .getListToscaDataDefinition().get(0).getInputId().concat(".subproperty"));
         Either<Boolean, ResponseFormat> booleanResponseFormatEither = interfaceOperationValidationUtilTest
                 .validateInterfaceOperations(operations, component, false);
         Assert.assertTrue(booleanResponseFormatEither.isLeft());
     }
 
     @Test
-    public void testInterfaceOperationInputParamNameEmpty() {
+    public void shouldFailWhenOperationInputParamNameEmpty() {
         operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("  "));
         operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1"));
         operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1"));
@@ -185,6 +187,48 @@ public class InterfaceOperationValidationTest {
                 "interface operation2",new ArtifactDefinition(), operationInputDefinitionList,
                 operationOutputDefinitionList,"update");
 
+        Either<Boolean, ResponseFormat> booleanResponseFormatEither = interfaceOperationValidationUtilTest
+                .validateInterfaceOperations(operations, component, false);
+        Assert.assertTrue(booleanResponseFormatEither.isRight());
+    }
+
+    @Test
+    public void shouldFailWhenOperationOutputParamNameEmpty() {
+        operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("inputParam"));
+        operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1"));
+        operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(" "));
+        Collection<Operation> operations = createInterfaceOperationData("op2",
+                "interface operation2",new ArtifactDefinition(), operationInputDefinitionList,
+                operationOutputDefinitionList,"update");
+
+        Either<Boolean, ResponseFormat> booleanResponseFormatEither = interfaceOperationValidationUtilTest
+                .validateInterfaceOperations(operations, component, false);
+        Assert.assertTrue(booleanResponseFormatEither.isRight());
+    }
+
+    @Test
+    public void shouldPassWhenInterfaceOperationOutputParamNamesUnique() {
+        operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1"));
+        operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1"));
+        operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label2"));
+        Collection<Operation> operations = createInterfaceOperationData("op2",
+                "interface operation2",new ArtifactDefinition(), operationInputDefinitionList,
+                operationOutputDefinitionList,"update");
+
+        Either<Boolean, ResponseFormat> booleanResponseFormatEither = interfaceOperationValidationUtilTest
+                .validateInterfaceOperations(operations, component, false);
+        Assert.assertTrue(booleanResponseFormatEither.isLeft());
+    }
+
+    @Test
+    public void shouldFailWhenOperationOutputParamNamesAreNotUnique() {
+        operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("inputParam1"));
+        operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("outParam1"));
+        operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("outParam2"));
+        operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("outParam2"));
+        Collection<Operation> operations = createInterfaceOperationData("op2",
+                "interface operation2",new ArtifactDefinition(), operationInputDefinitionList,
+                operationOutputDefinitionList,"update");
 
         Either<Boolean, ResponseFormat> booleanResponseFormatEither = interfaceOperationValidationUtilTest
                 .validateInterfaceOperations(operations, component, false);
index ac53a6d..8f34e0e 100644 (file)
@@ -146,7 +146,7 @@ public class InterfacesOperationsToscaUtilTest {
         component.setInterfaces(new HashMap<>());
         component.getInterfaces().put(interfaceType, addedInterface);
         ToscaNodeType nodeType = new ToscaNodeType();
-        InterfacesOperationsToscaUtil.addInterfaceDefinitionElement(component, nodeType, true);
+        InterfacesOperationsToscaUtil.addInterfaceDefinitionElement(component, nodeType, false);
 
         ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null);
         ToscaTemplate template = new ToscaTemplate("testService");
index 916a34c..f9f2ce9 100644 (file)
@@ -17,6 +17,7 @@
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
 import fj.data.Either;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -93,6 +94,17 @@ public class InterfaceOperation extends BaseOperation {
     Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
     Either<GraphVertex, TitanOperationStatus> getToscaElementInt;
 
+    if(isUpdateAction && operation.getImplementationArtifact() != null){
+      String artifactUUID = operation.getImplementationArtifact().getArtifactUUID();
+      Either<Long, CassandraOperationStatus> artifactCount = artifactCassandraDao.getCountOfArtifactById(artifactUUID);
+      if(artifactCount.isLeft()){
+        CassandraOperationStatus cassandraStatus = artifactCassandraDao.deleteArtifact(artifactUUID);
+        if (cassandraStatus != CassandraOperationStatus.OK) {
+          return Either.right(DaoStatusConverter.convertCassandraStatusToStorageStatus(cassandraStatus));
+        }
+      }
+    }
+
     getToscaElementRes = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
     if (getToscaElementRes.isRight()) {
       TitanOperationStatus status = getToscaElementRes.right().value();
@@ -139,6 +151,21 @@ public class InterfaceOperation extends BaseOperation {
       return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getInterfaceVertex.right().value()));
     }
 
+      if (!interfaceDef.getOperationsMap().isEmpty()) {
+          Either<GraphVertex, TitanOperationStatus> getInterfaceOpVertex =
+                  titanDao.getChildVertex(getInterfaceVertex.left().value(), EdgeLabelEnum.INTERFACE_OPERATION,
+                          JsonParseFlagEnum.NoParse);
+          if (getInterfaceOpVertex.isRight()) {
+              List<ToscaDataDefinition> toscaDataList = new ArrayList<>(interfaceDef.getOperationsMap().values());
+              StorageOperationStatus statusRes =
+                      addToscaDataToToscaElement(getInterfaceVertex.left().value(), EdgeLabelEnum.INTERFACE_OPERATION,
+                              VertexTypeEnum.INTERFACE_OPERATION, toscaDataList, JsonPresentationFields.UNIQUE_ID);
+              if (!statusRes.equals(StorageOperationStatus.OK)) {
+                  return Either.right(statusRes);
+              }
+          }
+      }
+
     Optional<Entry<String, Operation>> operationToRemove = interfaceDef.getOperationsMap().entrySet().stream()
         .filter(entry -> entry.getValue().getUniqueId().equals(operationToDelete)).findAny();
     if (operationToRemove.isPresent()){
index da9cf5f..e19d345 100644 (file)
@@ -174,12 +174,11 @@ export class InterfaceOperationComponent {
             this.operationList.sort((a, b) => a.operationType.localeCompare(b.operationType));
 
             if (response.workflowId && operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXISTING) {
-                const resourceId = this.component.uuid;
                 const operationId = response.uniqueId;
                 const workflowId = response.workflowId;
                 const versionId = response.workflowVersionId;
                 const artifactId = response.artifactUUID;
-                this.WorkflowServiceNg2.associateWorkflowArtifact(resourceId, operationId, workflowId, versionId, artifactId).subscribe();
+                this.WorkflowServiceNg2.associateWorkflowArtifact(this.component, operationId, workflowId, versionId, artifactId).subscribe();
             } else if (operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.NEW) {
                 this.$state.go('workspace.plugins', { path: 'workflowDesigner' });
             }
@@ -193,13 +192,12 @@ export class InterfaceOperationComponent {
             this.operationList.splice(index, 1, newOperation);
             this.component.interfaceOperations = this.operationList;
 
-            if (newOperation.workflowId) {
-                const resourceId = this.component.uuid;
+            if (newOperation.workflowId && operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXISTING) {
                 const operationId = newOperation.uniqueId;
                 const workflowId = newOperation.workflowId;
                 const versionId = newOperation.workflowVersionId;
                 const artifactId = newOperation.artifactUUID;
-                this.WorkflowServiceNg2.associateWorkflowArtifact(resourceId, operationId, workflowId, versionId, artifactId).subscribe();
+                this.WorkflowServiceNg2.associateWorkflowArtifact(this.component, operationId, workflowId, versionId, artifactId).subscribe();
             }
         });
     }
index 982cbb2..6010bca 100644 (file)
             <param-row
                 *ngFor="let param of tableParameters"
                 class="data-row"
-                [isInputParam]="currentTab == TYPE_INPUT"
+                [isInputParam]="currentTab === TYPE_INPUT"
                 [isAssociateWorkflow]="isUsingExistingWF()"
                 [param]="param"
                 [inputProps]="inputProperties"
-                [propTypes]="inputPropertyTypes"
                 [onRemoveParam]="onRemoveParam"
                 [readonly]="readonly">
             </param-row>
index 5d3b027..a6c1fb1 100644 (file)
@@ -18,7 +18,6 @@ export interface OperationCreatorInput {
     isService: boolean
 }
 
-
 @Component({
     selector: 'operation-creator',
     templateUrl: './operation-creator.component.html',
@@ -33,7 +32,7 @@ export class OperationCreatorComponent {
 
     workflows: Array<DropdownValue> = [];
     workflowVersions: Array<DropdownValue> = [];
-    inputProperties: Array<DropdownValue> = [];
+    inputProperties: Array<InputBEModel> = [];
     inputPropertyTypes: { [key: string]: string };
 
     inputParameters: Array<OperationParameter> = [];
@@ -76,19 +75,10 @@ export class OperationCreatorComponent {
     }
 
     ngOnInit() {
-
         this.readonly = this.input.readonly;
         this.isService = this.input.isService;
-        this.enableWorkflowAssociation = this.input.enableWorkflowAssociation && !this.isService;
-
-        this.inputProperties = _.map(this.input.inputProperties,
-            (input: InputBEModel) => new DropdownValue(input.uniqueId, input.name)
-        );
-
-        this.inputPropertyTypes = {};
-        _.forEach(this.input.inputProperties, (input: InputBEModel) => {
-            this.inputPropertyTypes[input.uniqueId] = input.type;
-        });
+        this.enableWorkflowAssociation = this.input.enableWorkflowAssociation;
+        this.inputProperties = this.input.inputProperties;
 
         const inputOperation = this.input.operation;
         this.operation = new OperationModel(inputOperation || {});
@@ -108,13 +98,12 @@ export class OperationCreatorComponent {
         } else {
             this.reconstructOperation();
         }
-
     }
 
     reconstructOperation = () => {
         const inputOperation = this.input.operation;
         if (inputOperation) {
-            if (!this.enableWorkflowAssociation || !inputOperation.workflowVersionId || this.isService) {
+            if (!this.enableWorkflowAssociation || !inputOperation.workflowVersionId) {
                 this.inputParameters = this.noAssignInputParameters;
                 this.outputParameters = this.noAssignOutputParameters;
                 this.buildParams();
index 94d2fce..9a5c101 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-  ~ Copyright Â© 2016-2018 European Support Limited
+  ~ Copyright ï¿½ 2016-2018 European Support Limited
   ~
   ~ Licensed under the Apache License, Version 2.0 (the "License");
   ~ you may not use this file except in compliance with the License.
 
 <div class="cell field-property" *ngIf="isInputParam">
     <ui-element-dropdown
-        *ngIf="filteredInputProps.length > 0 || !isAssociateWorkflow"
+        *ngIf="filteredInputProps.length || !isAssociateWorkflow"
         data-tests-id="paramProperty"
         [values]="filteredInputProps"
         [(value)]="param.property"
         [readonly]="readonly">
     </ui-element-dropdown>
     <span
-        *ngIf="filteredInputProps.length == 0 && isAssociateWorkflow"
+        *ngIf="!filteredInputProps.length && isAssociateWorkflow"
         class="no-properties-error">
         No available properties of this type.
     </span>
index 28932eb..2c2625d 100644 (file)
@@ -38,7 +38,7 @@
         }
 
         .no-properties-error {
-            color: red;
+            color: @func_color_q;
             font-style: italic;
         }
     }
index 8844cf6..de795eb 100644 (file)
@@ -1,6 +1,6 @@
 import {Component, Input} from '@angular/core';
 import {DataTypeService} from "app/ng2/services/data-type.service";
-import {OperationParameter} from 'app/models';
+import {OperationParameter, InputBEModel} from 'app/models';
 import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component";
 
 @Component({
@@ -11,8 +11,7 @@ import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-e
 
 export class ParamRowComponent {
     @Input() param: OperationParameter;
-    @Input() inputProps: Array<DropdownValue>;
-    @Input() propTypes: { [key: string]: string };
+    @Input() inputProps: Array<InputBEModel>;
     @Input() onRemoveParam: Function;
     @Input() isAssociateWorkflow: boolean;
     @Input() readonly: boolean;
@@ -21,14 +20,61 @@ export class ParamRowComponent {
     propTypeEnum: Array<String> = [];
     filteredInputProps: Array<DropdownValue> = [];
 
+    constructor(private dataTypeService: DataTypeService) {}
+
     ngOnInit() {
-        this.propTypeEnum = _.uniq(_.toArray(this.propTypes));
+        this.propTypeEnum = _.uniq(
+            _.map(
+                this.getPrimitiveSubtypes(),
+                prop => prop.type
+            )
+        );
+        console.log(this.dataTypeService.getAllDataTypes());
         this.onChangeType();
     }
 
     onChangeType() {
-        this.filteredInputProps = _.filter(this.inputProps, prop => {
-            return this.propTypes[prop.value] === this.param.type;
+        this.filteredInputProps = _.map(
+            _.filter(
+                this.getPrimitiveSubtypes(),
+                prop => prop.type === this.param.type
+            ),
+            prop => new DropdownValue(prop.uniqueId, prop.name)
+        );
+    }
+
+    getPrimitiveSubtypes(): Array<InputBEModel> {
+        const flattenedProps: Array<any> = [];
+        const dataTypes = this.dataTypeService.getAllDataTypes();
+        _.forEach(this.inputProps, prop => {
+            const type = _.find(
+                _.toArray(dataTypes),
+                (type: any) => type.name === prop.type
+            );
+            if (!type.properties) {
+                flattenedProps.push(prop);
+            } else {
+                _.forEach(type.properties, subType => {
+                    if (this.isTypePrimitive(subType.type)) {
+                        flattenedProps.push({
+                            type: subType.type,
+                            name: `${prop.name}.${subType.name}`,
+                            uniqueId: `${prop.uniqueId}.${subType.name}`
+                        });
+                    }
+                });
+            }
         });
+
+        return flattenedProps;
+    }
+
+    isTypePrimitive(type): boolean {
+        return (
+            type === 'string' ||
+            type === 'integer' ||
+            type === 'float' ||
+            type === 'boolean'
+        );
     }
 }
index 3546ebd..26b0291 100644 (file)
@@ -128,9 +128,7 @@ export class ComponentServiceNg2 {
 
     getInterfaceOperation(component:Component, operation:OperationModel):Observable<OperationModel> {
         return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations/' + operation.uniqueId)
-            .map((res:Response) => {
-                return res.json();
-            });
+            .map((res:Response) => res.json());
     }
 
     createInterfaceOperation(component:Component, operation:OperationModel):Observable<CreateOperationResponse> {
@@ -140,9 +138,7 @@ export class ComponentServiceNg2 {
             }
         };
         return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations', operationList)
-            .map((res:Response) => {
-                return res.json();
-            });
+            .map((res:Response) => res.json());
     }
 
     updateInterfaceOperation(component:Component, operation:OperationModel):Observable<CreateOperationResponse> {
@@ -152,16 +148,12 @@ export class ComponentServiceNg2 {
             }
         };
         return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations', operationList)
-            .map((res:Response) => {
-                return res.json();
-            });
+            .map((res:Response) => res.json());
     }
 
     deleteInterfaceOperation(component:Component, operation:OperationModel):Observable<OperationModel> {
         return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations/' + operation.uniqueId)
-            .map((res:Response) => {
-                return res.json();
-            });
+            .map((res:Response) => res.json());
     }
 
     getCapabilitiesAndRequirements(componentType: string, componentId:string):Observable<ComponentGenericResponse> {
@@ -189,7 +181,6 @@ export class ComponentServiceNg2 {
 
 
     deleteInput(component:Component, input:InputBEModel):Observable<InputBEModel> {
-
         return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/delete/' + input.uniqueId + '/input')
             .map((res:Response) => {
                 return new InputBEModel(res.json());
@@ -197,7 +188,6 @@ export class ComponentServiceNg2 {
     }
 
     updateComponentInputs(component:Component, inputs:InputBEModel[]):Observable<InputBEModel[]> {
-
         return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/update/inputs', inputs)
             .map((res:Response) => {
                 return res.json().map((input) => new InputBEModel(input));
index ae06a39..24ba882 100644 (file)
@@ -3,6 +3,7 @@ import { Response } from "@angular/http";
 import { Observable } from "rxjs/Observable";
 import { HttpService } from "./http.service";
 import { SdcConfigToken, ISdcConfig } from "../config/sdc-config.config";
+import { Component } from "app/models";
 
 @Injectable()
 export class WorkflowServiceNg2 {
@@ -12,11 +13,21 @@ export class WorkflowServiceNg2 {
 
     VERSION_STATE_CERTIFIED = 'CERTIFIED';
 
-    constructor(private http: HttpService, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) {
+    constructor(private http: HttpService, @Inject(SdcConfigToken) sdcConfig: ISdcConfig) {
         this.baseUrl = sdcConfig.api.workflow_root;
         this.catalogBaseUrl = sdcConfig.api.POST_workflow_artifact;
     }
 
+    public associateWorkflowArtifact(component: Component, operationId: string, workflowId: string, workflowVersionId: string, artifactUuid: string): Observable<any> {
+        return this.http.post(this.baseUrl + '/workflows/' + workflowId + '/versions/' + workflowVersionId + '/artifact-deliveries', {
+                endpoint: this.catalogBaseUrl + '/' + component.getTypeUrl() + component.uuid + '/interfaces/' + operationId + '/artifacts/' + artifactUuid,
+                method: 'POST'
+            })
+            .map((res:Response) => {
+                return res.json();
+            });
+    }
+
     public getWorkflows(filterCertified: boolean = true): Observable<any> {
         return this.http.get(this.baseUrl + '/workflows' + (filterCertified ? '?versionState=' + this.VERSION_STATE_CERTIFIED : ''))
             .map((res:Response) => {
@@ -38,14 +49,4 @@ export class WorkflowServiceNg2 {
             });
     }
 
-    public associateWorkflowArtifact(resourceUuid, operationId, workflowId, workflowVersionId, artifactUuid): Observable<any> {
-        return this.http.post(this.baseUrl + '/workflows/' + workflowId + '/versions/' + workflowVersionId + '/artifact-deliveries', {
-                endpoint: this.catalogBaseUrl + '/resources/' + resourceUuid + '/interfaces/' + operationId + '/artifacts/' + artifactUuid,
-                method: 'POST'
-            })
-            .map((res:Response) => {
-                return res.json();
-            });
-    }
-
 }
index 9f3cd54..ed09f2f 100644 (file)
@@ -7,7 +7,7 @@ Feature: Interface Operation Feature
     #Create Operations
   When I want to create an Operation
   Then I want to check property "uniqueId" exists
-  And  I want to create an Operation
+  And  I want to create an Operation with workflow
   Then I want to check property "uniqueId" exists
   And  I want to create an Operation
   Then I want to check property "uniqueId" exists
index 1ad2377..1ff0ba3 100644 (file)
@@ -7,7 +7,7 @@ Feature: Interface Operation Feature
    #Create Operations
   When I want to create an Operation
   Then I want to check property "uniqueId" exists
-  And  I want to create an Operation
+  And  I want to create an Operation with workflow
   Then I want to check property "uniqueId" exists
   And  I want to create an Operation
   Then I want to check property "uniqueId" exists
diff --git a/openecomp-bdd/resources/json/operation/createOperation-with-workflow.json b/openecomp-bdd/resources/json/operation/createOperation-with-workflow.json
new file mode 100644 (file)
index 0000000..e9693ad
--- /dev/null
@@ -0,0 +1,30 @@
+{
+  "interfaceOperations": {
+    "operation": {
+      "description": "abcd description",
+      "inputParams": {
+        "listToscaDataDefinition": [
+          {
+            "name": "inp1",
+            "type": "string",
+            "property": "97477d27-8fe2-45a1-83cb-83368ef2a402.nf_naming_code",
+            "mandatory": true
+          }
+        ]
+      },
+      "outputParams": {
+        "listToscaDataDefinition": [
+          {
+            "name": "op",
+            "mandatory": true,
+            "type": "String"
+          }
+        ]
+      },
+      "operationType": "create",
+      "workflowAssociationType": "EXISTING",
+      "workflowId" : "workflowId",
+      "workflowVersionId" : "workflowVersionId"
+    }
+  }
+}
\ No newline at end of file
index f4a81d6..408db9e 100644 (file)
@@ -26,7 +26,7 @@ When('I want to create a VF', function()  {
 
     var type = "resources";
     let path = '/catalog/' + type;
-    return util.request(this.context, 'POST', path,  inputData, false, 'vf').then(result => {
+    return util.request(this.context, 'POST', path,  inputData, false, 'catalog').then(result => {
         this.context.component = {uniqueId : result.data.uniqueId, type : type, id : result.data.inputs[0].uniqueId};
 });
 });
@@ -39,7 +39,7 @@ When('I want to create a Service', function()  {
 
     var type = "services";
     let path = '/catalog/' + type;
-    return util.request(this.context, 'POST', path,  inputData, false, 'vf').then(result => {
+    return util.request(this.context, 'POST', path,  inputData, false, 'catalog').then(result => {
         this.context.component = {uniqueId : result.data.uniqueId, type : type, id : result.data.inputs[0].uniqueId};
 });
 });
@@ -64,33 +64,48 @@ When('I want to create an Operation with input output', function()  {
     inputData.interfaceOperations.operation.operationType = makeType();
     inputData.interfaceOperations.operation.description = makeType();
 
-    return util.request(this.context, 'POST', path, inputData, false, 'vf').then(result => {
-    this.context.operation = {uniqueId : result.data.uniqueId, operationType : result.data.operationType};
+    return util.request(this.context, 'POST', path, inputData, false, 'catalog').then(result => {
+        this.context.operation = {uniqueId : result.data.uniqueId, operationType : result.data.operationType};
 });
 });
 
-
 When('I want to create an Operation', function()  {
     let path = '/catalog/' + this.context.component.type + '/' + this.context.component.uniqueId + '/interfaceOperations';
-       let inputData  = util.getJSONFromFile('resources/json/operation/createOperation.json');
+    let inputData  = util.getJSONFromFile('resources/json/operation/createOperation.json');
     inputData.interfaceOperations.operation.operationType = makeType();
     inputData.interfaceOperations.operation.description = makeType();
 
-    return util.request(this.context, 'POST', path, inputData, false, 'vf').then(result => {
+    return util.request(this.context, 'POST', path, inputData, false, 'catalog').then(result => {
         this.context.operation = {uniqueId : result.data.uniqueId, operationType : result.data.operationType};
 });
 });
 
+When('I want to create an Operation with workflow', function()  {
+    let path = '/catalog/' + this.context.component.type + '/' + this.context.component.uniqueId + '/interfaceOperations';
+    let inputData = util.getJSONFromFile('resources/json/operation/createOperation-with-workflow.json');
+
+    inputData.interfaceOperations.operation.inputParams.listToscaDataDefinition[0].name = util.random();
+    inputData.interfaceOperations.operation.inputParams.listToscaDataDefinition[0].property = this.context.component.id;
+    inputData.interfaceOperations.operation.outputParams.listToscaDataDefinition[0].name = util.random();
+    inputData.interfaceOperations.operation.operationType = makeType();
+    inputData.interfaceOperations.operation.description = makeType();
+    inputData.interfaceOperations.operation.workflowId = makeType();
+    inputData.interfaceOperations.operation.workflowVersionId = makeType();
+
+    return util.request(this.context, 'POST', path, inputData, false, 'catalog').then(result => {
+        this.context.operation = {uniqueId : result.data.uniqueId, operationType : result.data.operationType};
+});
+});
 
 When('I want to list Operations', function () {
     let path = '/catalog/'+ this.context.component.type + '/' + this.context.component.uniqueId + '/filteredDataByParams?include=interfaces';
-    return util.request(this.context, 'GET', path, null, false, 'vf').then((result)=> {
+    return util.request(this.context, 'GET', path, null, false, 'catalog').then((result)=> {
     });
 });
 
 When('I want to get an Operation by Id', function () {
     let path = '/catalog/'+ this.context.component.type + '/' + this.context.component.uniqueId + '/interfaceOperations/' + this.context.operation.uniqueId;
-    return util.request(this.context, 'GET', path, null, false, 'vf').then((result)=> {
+    return util.request(this.context, 'GET', path, null, false, 'catalog').then((result)=> {
     this.context.operation = {uniqueId : result.data.uniqueId, operationType : result.data.operationType};
 });
 });
@@ -103,7 +118,7 @@ When('I want to update an Operation', function () {
     inputData.interfaceOperations.operation.inputParams.listToscaDataDefinition[0].name = util.random();
     inputData.interfaceOperations.operation.inputParams.listToscaDataDefinition[0].property = this.context.component.id;
     inputData.interfaceOperations.operation.outputParams.listToscaDataDefinition[0].name = util.random();
-    return util.request(this.context, 'PUT', path, inputData, false, 'vf').then((result)=> {
+    return util.request(this.context, 'PUT', path, inputData, false, 'catalog').then((result)=> {
     this.context.operation = {uniqueId : result.data.uniqueId, operationType : result.data.operationType};
 });
 });
@@ -111,14 +126,14 @@ When('I want to update an Operation', function () {
 
 When('I want to delete an Operation', function()  {
     let path = '/catalog/'+ this.context.component.type + '/'+ this.context.component.uniqueId +'/interfaceOperations/' + this.context.operation.uniqueId;
-    return util.request(this.context, 'DELETE', path, null, false, 'vf');
+    return util.request(this.context, 'DELETE', path, null, false, 'catalog');
 });
 
 
 When('I want to checkin this component', function () {
     let path = '/catalog/'+ this.context.component.type + '/' + this.context.component.uniqueId + '/lifecycleState/CHECKIN' ;
     let inputData = {userRemarks: 'checkin'};
-    return util.request(this.context, 'POST', path, inputData, false, 'vf').then((result)=> {
+    return util.request(this.context, 'POST', path, inputData, false, 'catalog').then((result)=> {
     this.context.component = {uniqueId : result.data.uniqueId, type : this.context.component.type};
 });
 });
@@ -127,15 +142,15 @@ When('I want to checkin this component', function () {
 Then('I want to submit this component', function () {
     let path = '/catalog/'+ this.context.component.type + '/' + this.context.component.uniqueId + '/lifecycleState/certificationRequest' ;
     let inputData = {userRemarks: 'submit'};
-    return util.request(this.context, 'POST', path, inputData, false, 'vf').then((result)=> {
-    this.context.vf = {uniqueId : result.data.uniqueId};
+    return util.request(this.context, 'POST', path, inputData, false, 'catalog').then((result)=> {
+    this.context.component = {uniqueId : result.data.uniqueId};
 });
 });
 
 Then('I want to certify this component', function () {
     let path = '/catalog/'+ this.context.component.type +'/' + this.context.component.uniqueId + '/lifecycleState/certify' ;
     let inputData = {userRemarks: 'certify'};
-    return util.request(this.context, 'POST', path, inputData, false, 'vf').then((result)=> {
+    return util.request(this.context, 'POST', path, inputData, false, 'catalog').then((result)=> {
     this.context.component = {uniqueId : result.data.uniqueId};
 });
 });
\ No newline at end of file