Batch delete keyboard shorcut on canvas 41/70641/8
authorSindhuri.A <arcot.sindhuri@huawei.com>
Wed, 17 Oct 2018 07:55:27 +0000 (13:25 +0530)
committerTal Gitelman <tal.gitelman@att.com>
Sat, 3 Nov 2018 13:54:27 +0000 (13:54 +0000)
Keyboard Shortcut for batch delete (multiple select nodes and delete) on Composition page canvas

Issue-ID: SDC-1734

Change-Id: I7de5d95a1ca6ea27cdd257b20bfdc1ed9b0ce102
Signed-off-by: Sindhuri.A <arcot.sindhuri@huawei.com>
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentInstanceServletTest.java

index 1f4eb53..e5e8486 100644 (file)
@@ -1094,10 +1094,72 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
 
     }
 
-    public Either<RequirementCapabilityRelDef, ResponseFormat> dissociateRIFromRI(String componentId, String userId, RequirementCapabilityRelDef requirementDef, ComponentTypeEnum componentTypeEnum) {
+    /**
+     * @param componentId
+     * @param userId
+     * @param requirementDefList
+     * @param componentTypeEnum
+     * @return
+     */
+    public List<RequirementCapabilityRelDef> batchDissociateRIFromRI(
+            String componentId,
+            String userId,
+            List<RequirementCapabilityRelDef> requirementDefList,
+            ComponentTypeEnum componentTypeEnum) {
+
+        List<RequirementCapabilityRelDef> delOkResult = new ArrayList<>();
+        Either<Component, ResponseFormat> validateResponse = validateDissociateRI(componentId, userId, componentTypeEnum);
+        if (validateResponse.isRight()) {
+
+            return delOkResult;
+        }
+        Component containerComponent = validateResponse.left().value();
+        Either<Boolean, ResponseFormat> lockComponent = lockComponent(containerComponent, "associateRIToRI");
+        if (lockComponent.isRight()) {
+            return delOkResult;
+        }
+        try {
+            for (RequirementCapabilityRelDef requirementDef : requirementDefList) {
+                Either<RequirementCapabilityRelDef, ResponseFormat> actionResponse = dissociateRIFromRI(
+                        componentId, requirementDef, containerComponent);
+
+                if (actionResponse.isLeft()) {
+                    delOkResult.add(actionResponse.left().value());
+                }
+            }
+        } finally {
+            unlockComponent(validateResponse, containerComponent);
+        }
+        return delOkResult;
+    }
+
+    public Either<RequirementCapabilityRelDef, ResponseFormat> dissociateRIFromRI(
+            String componentId, String userId, RequirementCapabilityRelDef requirementDef, ComponentTypeEnum componentTypeEnum) {
+        Either<Component, ResponseFormat> validateResponse = validateDissociateRI(componentId,  userId,  componentTypeEnum);
+        if(validateResponse.isRight())
+        {
+            return Either.right(validateResponse.right().value());
+        }
+        Either<RequirementCapabilityRelDef, ResponseFormat> actionResponse = null;
+        Component containerComponent = validateResponse.left().value();
+        Either<Boolean, ResponseFormat> lockComponent = lockComponent(containerComponent, "associateRIToRI");
+        if (lockComponent.isRight()) {
+            return Either.right(lockComponent.right().value());
+        }
+        try {
+            actionResponse = dissociateRIFromRI(
+                    componentId, requirementDef,containerComponent);
+        } finally {
+            unlockComponent(validateResponse, containerComponent);
+        }
+        return actionResponse;
+    }
+
+    private Either<Component, ResponseFormat> validateDissociateRI(
+            String componentId, String userId, ComponentTypeEnum componentTypeEnum) {
         validateUserExists(userId, "dissociate RI From RI", false);
 
-        Either<RequirementCapabilityRelDef, ResponseFormat> resultOp = null;
+
         Either<org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponentExists = validateComponentExists(componentId, componentTypeEnum, null);
         if (validateComponentExists.isRight()) {
             return Either.right(validateComponentExists.right().value());
@@ -1108,45 +1170,49 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         if (validateCanWorkOnComponent.isRight()) {
             return Either.right(validateCanWorkOnComponent.right().value());
         }
-        Either<Boolean, ResponseFormat> lockComponent = lockComponent(containerComponent, "associateRIToRI");
+        return Either.left(containerComponent);
 
-        if (lockComponent.isRight()) {
-            return Either.right(lockComponent.right().value());
-        }
-        try {
-            log.debug("Try to create entry on graph");
-            Either<RequirementCapabilityRelDef, StorageOperationStatus> result = toscaOperationFacade.dissociateResourceInstances(componentId, requirementDef);
-            if (result.isLeft()) {
-                log.debug("Enty on graph is created.");
-                RequirementCapabilityRelDef requirementCapabilityRelDef = result.left().value();
-                resultOp = Either.left(requirementCapabilityRelDef);
-                return resultOp;
+    }
+    private Either<RequirementCapabilityRelDef, ResponseFormat> dissociateRIFromRI(
+            String componentId, RequirementCapabilityRelDef requirementDef, Component containerComponent) {
 
-            } else {
+        Either<RequirementCapabilityRelDef, ResponseFormat> resultOp = null;
+        log.debug("Try to create entry on graph");
+        Either<RequirementCapabilityRelDef, StorageOperationStatus> result = toscaOperationFacade.dissociateResourceInstances(
+                componentId, requirementDef);
+        if (result.isLeft()) {
+            log.debug("Enty on graph is created.");
+            RequirementCapabilityRelDef requirementCapabilityRelDef = result.left().value();
+            resultOp = Either.left(requirementCapabilityRelDef);
+            return resultOp;
 
-                log.debug("Failed to dissocaite node  {} from node {}", requirementDef.getFromNode(), requirementDef.getToNode());
-                String fromNameOrId = "";
-                String toNameOrId = "";
-                Either<ComponentInstance, StorageOperationStatus> fromResult = getResourceInstanceById(containerComponent, requirementDef.getFromNode());
-                Either<ComponentInstance, StorageOperationStatus> toResult = getResourceInstanceById(containerComponent, requirementDef.getToNode());
+        } else {
 
-                toNameOrId = requirementDef.getFromNode();
-                fromNameOrId = requirementDef.getFromNode();
-                if (fromResult.isLeft()) {
-                    fromNameOrId = fromResult.left().value().getName();
-                }
-                if (toResult.isLeft()) {
-                    toNameOrId = toResult.left().value().getName();
-                }
+            log.debug("Failed to dissocaite node  {} from node {}", requirementDef.getFromNode(), requirementDef.getToNode());
+            String fromNameOrId = "";
+            String toNameOrId = "";
+            Either<ComponentInstance, StorageOperationStatus> fromResult = getResourceInstanceById(
+                    containerComponent, requirementDef.getFromNode());
+            Either<ComponentInstance, StorageOperationStatus> toResult = getResourceInstanceById(
+                    containerComponent, requirementDef.getToNode());
 
-                resultOp = Either
-                        .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponseForResourceInstance(result.right().value(), true), fromNameOrId, toNameOrId, requirementDef.getRelationships().get(0).getRelation().getRequirement()));
-                return resultOp;
+            toNameOrId = requirementDef.getFromNode();
+            fromNameOrId = requirementDef.getFromNode();
+            if (fromResult.isLeft()) {
+                fromNameOrId = fromResult.left().value().getName();
             }
-        } finally {
-            unlockComponent(resultOp, containerComponent);
+            if (toResult.isLeft()) {
+                toNameOrId = toResult.left().value().getName();
+            }
+
+            resultOp = Either
+                    .right(componentsUtils.getResponseFormat(
+                            componentsUtils.convertFromStorageResponseForResourceInstance(
+                                    result.right().value(), true), fromNameOrId, toNameOrId, requirementDef.getRelationships().get(0).getRelation().getRequirement()));
+            return resultOp;
         }
     }
+
     /**
      * Allows to get relation contained in specified component according to received Id
      * @param componentId
@@ -2820,7 +2886,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
 
                             sourceAttribute.setUniqueId(
                                     UniqueIdBuilder.buildResourceInstanceUniuqeId(
-                                    "attribute" , destComponentInstanceId.split("\\.")[1] , sourceAttributeName));
+                                            "attribute" , destComponentInstanceId.split("\\.")[1] , sourceAttributeName));
 
                             Either<ComponentInstanceProperty, ResponseFormat> updateAttributeValueEither =
                                     createOrUpdateAttributeValueForCopyPaste(ComponentTypeEnum.SERVICE,
@@ -2989,4 +3055,97 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         return Either.right(componentsUtils.getResponseFormat(
                 ActionStatus.USER_DEFINED, "Failed to paste component instance to the canvas"));
     }
+
+    /**
+     * Method to delete selected nodes and edges on composition page
+     * @param containerComponentType
+     * @param componentId
+     * @param componentInstanceIdList
+     * @param userId
+     * @return
+     */
+    public Map<String, List<String>> batchDeleteComponentInstance(String containerComponentType,
+                                                                  String componentId,
+                                                                  List<String> componentInstanceIdList,
+                                                                  String userId) {
+
+        List<String> deleteErrorIds = new ArrayList<>();
+        Map<String, List<String>> deleteErrorMap = new HashMap<>();
+        Either<Component, ResponseFormat> validateResponse = validateUser(containerComponentType, componentId, userId);
+        if (validateResponse.isRight()) {
+            deleteErrorMap.put("deleteFailedIds", componentInstanceIdList);
+            return deleteErrorMap;
+        }
+        Component containerComponent = validateResponse.left().value();
+
+        Either<Boolean, ResponseFormat> lockComponent = lockComponent(
+                containerComponent, "batchDeleteComponentInstance");
+        if (lockComponent.isRight()) {
+            log.error("Failed to lockComponent containerComponent");
+            deleteErrorMap.put("deleteFailedIds", componentInstanceIdList);
+            return deleteErrorMap;
+        }
+
+        try {
+            for (String eachInstanceId : componentInstanceIdList) {
+                Either<ComponentInstance, ResponseFormat> actionResponse = batchDeleteComponentInstance(
+                        containerComponent, containerComponentType, componentId, eachInstanceId);
+                log.debug("batchDeleteResourceInstances actionResponse is {}", actionResponse);
+                if (actionResponse.isRight()) {
+                    log.error("Failed to delete ComponentInstance [{}]", eachInstanceId);
+                    deleteErrorIds.add(eachInstanceId);
+                }
+            }
+            //sending the ids of the error nodes that were not deleted to UI
+            deleteErrorMap.put("deleteFailedIds", deleteErrorIds);
+            return deleteErrorMap;
+        } finally {
+            unlockComponent(validateResponse, containerComponent);
+        }
+    }
+
+    private Either<Component, ResponseFormat> validateUser(String containerComponentParam,
+                                                           String containerComponentId,
+                                                           String userId) {
+        validateUserExists(userId, "delete Component Instance", false);
+        Either<ComponentTypeEnum, ResponseFormat> validateComponentType = validateComponentType(containerComponentParam);
+        if (validateComponentType.isRight()) {
+            log.error("ComponentType[{}] doesn't support", containerComponentParam);
+            return Either.right(validateComponentType.right().value());
+        }
+
+        final ComponentTypeEnum containerComponentType = validateComponentType.left().value();
+        Either<Component, ResponseFormat> validateComponentExists = validateComponentExists(
+                containerComponentId, containerComponentType, null);
+        if (validateComponentExists.isRight()) {
+            log.error("Component Id[{}] doesn't exist", containerComponentId);
+            return Either.right(validateComponentExists.right().value());
+        }
+
+        Component containerComponent = validateComponentExists.left().value();
+        Either<Boolean, ResponseFormat> validateCanWorkOnComponent = validateCanWorkOnComponent(containerComponent, userId);
+        if (validateCanWorkOnComponent.isRight()) {
+            return Either.right(validateCanWorkOnComponent.right().value());
+        }
+        return Either.left(containerComponent);
+    }
+
+    private Either<ComponentInstance, ResponseFormat> batchDeleteComponentInstance(Component containerComponent,
+                                                                                   String containerComponentType,
+                                                                                   String containerComponentId,
+                                                                                   String componentInstanceId) {
+
+        Either<ComponentInstance, ResponseFormat> resultOp;
+        final ComponentTypeEnum containerComponentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
+
+        resultOp = deleteComponentInstance(containerComponent, componentInstanceId, containerComponentTypeEnum);
+
+        if (resultOp.isRight()) {
+            log.error("Failed to deleteComponentInstance with instanceId[{}]", componentInstanceId);
+            return Either.right(resultOp.right().value());
+        }
+
+        log.info("Successfully deleted instance with id {}", componentInstanceId);
+        return Either.left(resultOp.left().value());
+    }
 }
index 3195727..042303e 100644 (file)
@@ -1244,9 +1244,138 @@ public class ComponentInstanceServlet extends AbstractValidationsServlet {
             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
                     copyComponentInstance.left().value());
         } catch (Exception e) {
-            log.error("Failed to convert json to Map { }, error: { }", data, e);
+            log.error("Failed to convert json to Map { }", data, e);
             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.USER_DEFINED,
                     "Failed to get the copied component instance information"));
         }
     }
+
+    @POST
+    @Path("/{containerComponentType}/{componentId}/batchDeleteResourceInstances/")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @ApiOperation(value = "Batch Delete ResourceInstances", httpMethod = "POST")
+    @ApiResponses(value = {
+            @ApiResponse(code = 203, message = "ResourceInstances deleted"),
+            @ApiResponse(code = 403, message = "Restricted Operation"),
+            @ApiResponse(code = 400, message = "Invalid Content / Missing Content")
+    })
+    public Response batchDeleteResourceInstances(
+            @ApiParam(value = "valid values: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," +
+                    ComponentTypeEnum.PRODUCT_PARAM_NAME)
+            @PathParam("containerComponentType") final String containerComponentType,
+            @PathParam("componentId") final String componentId,
+            @Context final HttpServletRequest request,
+            @ApiParam(value = "Component Instance Id List", required = true) final String componentInstanceIdLisStr) {
+        ServletContext context = request.getSession().getServletContext();
+        try {
+            if (componentInstanceIdLisStr == null || componentInstanceIdLisStr.isEmpty()) {
+                log.error("Empty JSON List was sent",componentInstanceIdLisStr);
+                return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
+            }
+
+
+            ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context);
+            if (componentInstanceLogic == null) {
+                log.error("Unsupported component type {}", containerComponentType);
+                return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
+            }
+
+            Either<List<String>, ResponseFormat> convertResponse = convertToStringList(componentInstanceIdLisStr);
+
+            if (convertResponse.isRight()) {
+                BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - batchDeleteResourceInstances");
+                log.error("Failed to convert received data to BE format.");
+                return buildErrorResponse(convertResponse.right().value());
+            }
+
+            String userId = request.getHeader(Constants.USER_ID_HEADER);
+            List<String> componentInstanceIdList = convertResponse.left().value();
+            log.debug("batchDeleteResourceInstances componentInstanceIdList is {}", componentInstanceIdList);
+            Map<String, List<String>> deleteErrorMap = componentInstanceLogic.batchDeleteComponentInstance(containerComponentType,
+                    componentId, componentInstanceIdList, userId);
+
+            return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), deleteErrorMap);
+        } catch (Exception e) {
+            BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Batch Delete ResourceInstances");
+            log.error("batch delete resource instances with exception" , e);
+            return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+        }
+
+    }
+
+    @PUT
+    @Path("/{containerComponentType}/{componentId}/resourceInstance/batchDissociate")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @ApiOperation(value = "Batch Dissociate RI from RI", httpMethod = "PUT", notes = "Returns deleted RelationShip Info", response = Response.class)
+    @ApiResponses(value = {
+            @ApiResponse(code = 201, message = "Relationship deleted"),
+            @ApiResponse(code = 403, message = "Missing Information"),
+            @ApiResponse(code = 400, message = "Invalid Content / Missing Content")
+    })
+    public Response batchDissociateRIFromRI(
+            @ApiParam(value = "allowed values are resources/services/products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true)
+            @PathParam("containerComponentType") final String containerComponentType,
+            @ApiParam(value = "unique id of the container component")
+            @PathParam("componentId") final String componentId,
+            @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
+            @ApiParam(value = "RelationshipInfo", required = true) String data,
+            @Context final HttpServletRequest request) {
+        ServletContext context = request.getSession().getServletContext();
+
+        try {
+            if (data == null || data.length() == 0) {
+                log.info("Empty JSON list was sent");
+                return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
+            }
+
+            ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType);
+            ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context);
+
+            if (componentInstanceLogic == null) {
+                log.debug("Unsupported component type {}", containerComponentType);
+                return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType));
+            }
+
+            Either<List<RequirementCapabilityRelDef>, ResponseFormat> regInfoWs = convertToRequirementCapabilityRelDefList(data);
+
+            if (regInfoWs.isRight()) {
+                BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - batch dissociateRIFromRI");
+                log.debug("Failed to convert received data to BE format");
+                return buildErrorResponse(regInfoWs.right().value());
+            }
+
+            List<RequirementCapabilityRelDef> requirementDefList = regInfoWs.left().value();
+            List<RequirementCapabilityRelDef> delOkResult = componentInstanceLogic.batchDissociateRIFromRI(
+                    componentId, userId, requirementDefList, componentTypeEnum);
+
+            return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), delOkResult);
+        } catch (Exception e) {
+            BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Batch Dissociate Resource Instance");
+            log.debug("batch dissociate resource instance from service failed with exception", e);
+            return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+        }
+    }
+
+    private Either<List<String>, ResponseFormat> convertToStringList(String datalist) {
+        Either<String[], ResponseFormat> convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(datalist, new User(), String[].class, null, null);
+
+        if (convertStatus.isRight()) {
+            return Either.right(convertStatus.right().value());
+        }
+
+        return Either.left(Arrays.asList(convertStatus.left().value()));
+    }
+
+    private Either<List<RequirementCapabilityRelDef>, ResponseFormat> convertToRequirementCapabilityRelDefList(String data) {
+        Either<RequirementCapabilityRelDef[], ResponseFormat> convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, new User(), RequirementCapabilityRelDef[].class, null, null);
+
+        if (convertStatus.isRight()) {
+            return Either.right(convertStatus.right().value());
+        }
+
+        return Either.left(Arrays.asList(convertStatus.left().value()));
+    }
+
 }
index 929bb97..b5d937e 100644 (file)
@@ -1,3 +1,22 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
 package org.openecomp.sdc.be.components.impl;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -47,12 +66,10 @@ import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anySet;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.when;
 
 import static org.mockito.ArgumentMatchers.*;
-import static org.mockito.Mockito.when;
 
 /**
  * The test suite designed for test functionality of ComponentInstanceBusinessLogic class
@@ -98,7 +115,7 @@ public class ComponentInstanceBusinessLogicTest {
     private ArtifactsBusinessLogic artifactBusinessLogic;
     @Mock
     private GraphLockOperation graphLockOperation;
-    
+
     private Component service;
     private Component resource;
     private ComponentInstance toInstance;
@@ -170,7 +187,7 @@ public class ComponentInstanceBusinessLogicTest {
         when(toscaOperationFacade.getToscaFullElement(eq(new_Comp_UID))).thenReturn(Either.left(component2));
 
         Either<Set<String>, ResponseFormat> resultOp = componentInstanceBusinessLogic.forwardingPathOnVersionChange
-            (containerComponentParam,containerComponentID,componentInstanceID,newComponentInstance);
+                (containerComponentParam,containerComponentID,componentInstanceID,newComponentInstance);
         assertEquals(1,resultOp.left().value().size());
         assertEquals("FP-ID-1",resultOp.left().value().iterator().next());
 
@@ -185,7 +202,7 @@ public class ComponentInstanceBusinessLogicTest {
         String componentInstanceID = "NodeA1";
         Service component = new Service();
         component.setComponentInstances(Arrays.asList(createComponentIstance("NodeA2"),createComponentIstance("NodeB2"),
-            createComponentIstance(componentInstanceID)));
+                createComponentIstance(componentInstanceID)));
 
         component.addForwardingPath(createPath("path1", componentInstanceID, "NodeB1",  "1"));
         component.addForwardingPath(createPath("Path2", "NodeA2","NodeB2", "2"));
@@ -195,7 +212,7 @@ public class ComponentInstanceBusinessLogicTest {
         final ComponentInstance ci = new ComponentInstance();
         ci.setName(componentInstanceID);
         Either<ComponentInstance, ResponseFormat> responseFormatEither = componentInstanceBusinessLogic.deleteForwardingPathsRelatedTobeDeletedComponentInstance(
-            containerComponentID, containerComponentType, Either.left(ci));
+                containerComponentID, containerComponentType, Either.left(ci));
         assertThat(responseFormatEither.isLeft()).isEqualTo(true);
 
     }
@@ -228,18 +245,18 @@ public class ComponentInstanceBusinessLogicTest {
         forwardingPath.setDestinationPortNumber("DestinationPortNumber");
         forwardingPath.setUniqueId("FP-ID-1");
         ListDataDefinition<ForwardingPathElementDataDefinition> forwardingPathElementListDataDefinition =
-            new ListDataDefinition<>();
+                new ListDataDefinition<>();
         forwardingPathElementListDataDefinition.add(
-            new ForwardingPathElementDataDefinition(componentInstanceID, "nodeB", "nodeA_FORWARDER_CAPABILITY",
-                "nodeBcpType" , "nodeDcpName",
-                "nodeBcpName"));
+                new ForwardingPathElementDataDefinition(componentInstanceID, "nodeB", "nodeA_FORWARDER_CAPABILITY",
+                        "nodeBcpType" , "nodeDcpName",
+                        "nodeBcpName"));
         forwardingPath.setPathElements(forwardingPathElementListDataDefinition);
         Map<String, ForwardingPathDataDefinition> forwardingPaths = new HashMap<>();
         forwardingPaths.put("1122", forwardingPath);
         return forwardingPaths;
     }
 
-  @SuppressWarnings("unchecked")
+    @SuppressWarnings("unchecked")
     private void getServiceRelationByIdSuccess(Component component){
         Either<Component, StorageOperationStatus> getComponentRes = Either.left(component);
         when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))).thenReturn(getComponentRes);
@@ -534,8 +551,8 @@ public class ComponentInstanceBusinessLogicTest {
     }
 
     @Ignore("test failing skipping for now")
-       @Test
-       public void testCreateComponentInstanceOnGraph2()  {
+    @Test
+    public void testCreateComponentInstanceOnGraph2()  {
         ComponentInstanceBusinessLogic testSubject;
         createResource();
         resource.setName("name");
@@ -552,7 +569,7 @@ public class ComponentInstanceBusinessLogicTest {
         // default test
         testSubject=createTestSubject();
         result=Deencapsulation.invoke(testSubject, "createComponentInstanceOnGraph", new Object[]{resource, resource, toInstance, user});
-       }
+    }
 
     @Test
     public void testUpdateComponentInstanceMetadata()  {
@@ -1174,7 +1191,7 @@ public class ComponentInstanceBusinessLogicTest {
         when(toscaOperationFacade
                 .addInformationalArtifactsToInstance(eq(resource.getUniqueId()), eq(inputComponentInstance),
                         isNull(Map.class))).thenReturn(artStatus);
-        
+
         result = componentInstanceBusinessLogic
                 .copyComponentInstance(inputComponentInstance, containerComponentId, componentInstanceId, USER_ID);
 
@@ -1269,6 +1286,169 @@ public class ComponentInstanceBusinessLogicTest {
         assertEquals(result.left().value(), defaultValue);
     }
 
+    @Test
+    public void testBatchDeleteComponentInstanceFailureWrongType() {
+        Map<String, List<String>> result;
+        List<String> componentInstanceIdList = new ArrayList<>();
+        String containerComponentParam = "WRONG_TYPE";
+        String containerComponentId = "containerComponentId";
+        String componentInstanceId = "componentInstanceId";
+        componentInstanceIdList.add(componentInstanceId);
+        String userId = USER_ID;
+        Map<String, List<String>> deleteErrorMap = new HashMap<>();
+        List<String> deleteErrorIds = new ArrayList<>();
+        deleteErrorIds.add(componentInstanceId);
+        deleteErrorMap.put("deleteFailedIds", deleteErrorIds);
+
+        result = componentInstanceBusinessLogic
+                .batchDeleteComponentInstance(containerComponentParam, containerComponentId, componentInstanceIdList,
+                        userId);
+
+        assertEquals(deleteErrorMap, result);
+    }
+
+    @Test
+    public void testBatchDeleteComponentInstanceFailureCompIds() {
+        Map<String, List<String>> result;
+        String containerComponentParam = ComponentTypeEnum.SERVICE_PARAM_NAME;
+        String containerComponentId = "containerComponentId";
+        String componentInstanceId = "componentInstanceId";
+        List<String> componentInstanceIdList = new ArrayList<>();
+        componentInstanceIdList.add(componentInstanceId);
+        String userId = USER_ID;
+        Map<String, List<String>> deleteErrorMap = new HashMap<>();
+        List<String> deleteErrorIds = new ArrayList<>();
+        deleteErrorIds.add(componentInstanceId);
+        deleteErrorMap.put("deleteFailedIds", deleteErrorIds);
+
+        Either<Component, StorageOperationStatus> err = Either.right(StorageOperationStatus.GENERAL_ERROR);
+        when(toscaOperationFacade.getToscaElement(eq(containerComponentId), any(ComponentParametersView.class)))
+                .thenReturn(err);
+
+        result = componentInstanceBusinessLogic
+                .batchDeleteComponentInstance(containerComponentParam, containerComponentId, componentInstanceIdList,
+                        userId);
+
+        assertEquals(deleteErrorMap, result);
+    }
+
+    @Test
+    public void testBatchDeleteComponentInstanceSuccess() {
+        Map<String, List<String>> result;
+        String containerComponentParam = ComponentTypeEnum.SERVICE_PARAM_NAME;
+        LifecycleStateEnum oldLifeCycleState = service.getLifecycleState();
+        String oldLastUpdatedUserId = service.getLastUpdaterUserId();
+        service.setLastUpdaterUserId(USER_ID);
+        service.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+        String containerComponentId = service.getUniqueId();
+        String componentInstanceId = TO_INSTANCE_ID;
+        String userId = USER_ID;
+        List<String> componentInstanceIdList = new ArrayList<>();
+        componentInstanceIdList.add(componentInstanceId);
+        Map<String, List<String>> deleteErrorMap = new HashMap<>();
+        List<String> deleteErrorIds = new ArrayList<>();
+        deleteErrorMap.put("deleteFailedIds", deleteErrorIds);
+
+        Either<Component, StorageOperationStatus> cont = Either.left(service);
+        when(graphLockOperation.unlockComponent(Mockito.anyString(), eq(NodeTypeEnum.Service)))
+                .thenReturn(StorageOperationStatus.OK);
+        when(graphLockOperation.lockComponent(Mockito.anyString(), eq(NodeTypeEnum.Service)))
+                .thenReturn(StorageOperationStatus.OK);
+        ImmutablePair<Component, String> pair = new ImmutablePair<>(resource, TO_INSTANCE_ID);
+        Either<ImmutablePair<Component, String>, StorageOperationStatus> result2 = Either.left(pair);
+        when(toscaOperationFacade.deleteComponentInstanceFromTopologyTemplate(service, componentInstanceId))
+                .thenReturn(result2);
+        when(toscaOperationFacade.getToscaElement(eq(service.getUniqueId()), any(ComponentParametersView.class)))
+                .thenReturn(cont);
+        when(titanDao.commit()).thenReturn(TitanOperationStatus.OK);
+
+        result = componentInstanceBusinessLogic
+                .batchDeleteComponentInstance(containerComponentParam, containerComponentId, componentInstanceIdList, userId);
+
+        service.setLastUpdaterUserId(oldLastUpdatedUserId);
+        service.setLifecycleState(oldLifeCycleState);
+        assertEquals(deleteErrorMap,result);
+    }
+
+    @Test
+    public void testDissociateRIFromRIFailDissociate() {
+
+        List<RequirementCapabilityRelDef> result;
+        RequirementCapabilityRelDef ref = new RequirementCapabilityRelDef();
+        ref.setFromNode(FROM_INSTANCE_ID);
+        ref.setToNode(TO_INSTANCE_ID);
+        List<CapabilityRequirementRelationship> relationships = new ArrayList<>();
+        CapabilityRequirementRelationship relationship = new CapabilityRequirementRelationship();
+        RelationshipInfo ri = new RelationshipInfo();
+        ri.setRequirement(REQUIREMENT_NAME);
+        relationship.setRelation(ri);
+        relationships.add(relationship);
+        ref.setRelationships(relationships);
+        List<RequirementCapabilityRelDef> requirementDefList = new ArrayList<>();
+        requirementDefList.add(ref);
+        ComponentTypeEnum componentTypeEnum = service.getComponentType();
+        String componentId = service.getUniqueId();
+        String userId = USER_ID;
+        LifecycleStateEnum oldLifeCycleState = service.getLifecycleState();
+        String oldLastUpdatedUserId = service.getLastUpdaterUserId();
+        service.setLastUpdaterUserId(USER_ID);
+        service.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+
+        Either<Component, StorageOperationStatus> cont = Either.left(service);
+        when(toscaOperationFacade.getToscaElement(eq(service.getUniqueId()), any(ComponentParametersView.class)))
+                .thenReturn(cont);
+        when(graphLockOperation.unlockComponent(Mockito.anyString(), eq(NodeTypeEnum.Service)))
+                .thenReturn(StorageOperationStatus.OK);
+        when(graphLockOperation.lockComponent(Mockito.anyString(), eq(NodeTypeEnum.Service)))
+                .thenReturn(StorageOperationStatus.OK);
+        Either<RequirementCapabilityRelDef, StorageOperationStatus> resultEither;
+        resultEither = Either.right(StorageOperationStatus.OK);
+        when(toscaOperationFacade.dissociateResourceInstances(componentId, ref)).thenReturn(resultEither);
+
+        result = componentInstanceBusinessLogic
+                .batchDissociateRIFromRI(componentId, userId, requirementDefList, componentTypeEnum);
+
+        service.setLastUpdaterUserId(oldLastUpdatedUserId);
+        service.setLifecycleState(oldLifeCycleState);
+
+        assertEquals(new ArrayList<>(), result);
+    }
+
+    @Test
+    public void testDissociateRIFromRISuccess() {
+
+        List<RequirementCapabilityRelDef> result;
+        RequirementCapabilityRelDef ref = new RequirementCapabilityRelDef();
+        List<RequirementCapabilityRelDef> requirementDefList = new ArrayList<>();
+        requirementDefList.add(ref);
+        ComponentTypeEnum componentTypeEnum = service.getComponentType();
+        String componentId = service.getUniqueId();
+        String userId = USER_ID;
+        LifecycleStateEnum oldLifeCycleState = service.getLifecycleState();
+        String oldLastUpdatedUserId = service.getLastUpdaterUserId();
+        service.setLastUpdaterUserId(USER_ID);
+        service.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+
+        Either<Component, StorageOperationStatus> cont = Either.left(service);
+        when(toscaOperationFacade.getToscaElement(eq(service.getUniqueId()), any(ComponentParametersView.class)))
+                .thenReturn(cont);
+        when(graphLockOperation.unlockComponent(Mockito.anyString(), eq(NodeTypeEnum.Service)))
+                .thenReturn(StorageOperationStatus.OK);
+        when(graphLockOperation.lockComponent(Mockito.anyString(), eq(NodeTypeEnum.Service)))
+                .thenReturn(StorageOperationStatus.OK);
+        Either<RequirementCapabilityRelDef, StorageOperationStatus> resultEither;
+        resultEither = Either.left(ref);
+        when(toscaOperationFacade.dissociateResourceInstances(componentId, ref)).thenReturn(resultEither);
+
+        result = componentInstanceBusinessLogic
+                .batchDissociateRIFromRI(componentId, userId, requirementDefList, componentTypeEnum);
+
+        service.setLastUpdaterUserId(oldLastUpdatedUserId);
+        service.setLifecycleState(oldLifeCycleState);
+
+        assertEquals(requirementDefList, result);
+    }
+
     private ComponentInstance createComponetInstanceFromComponent(Component component) {
         ComponentInstance componentInst = new ComponentInstance();
         componentInst.setUniqueId(component.getUniqueId());
index d8e7896..7d05c69 100644 (file)
@@ -4,6 +4,7 @@ import fj.data.Either;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.ArrayList;
 import javax.ws.rs.client.Entity;
 import org.eclipse.jetty.http.HttpStatus;
 import org.glassfish.hk2.utilities.binding.AbstractBinder;
@@ -12,6 +13,7 @@ import org.glassfish.jersey.test.JerseyTest;
 import org.glassfish.jersey.test.TestProperties;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.mockito.ArgumentMatchers;
 import org.mockito.Mockito;
 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
 import org.openecomp.sdc.be.config.SpringConfig;
@@ -29,6 +31,8 @@ import org.openecomp.sdc.exception.ResponseFormat;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.web.context.WebApplicationContext;
+import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
+import org.openecomp.sdc.be.model.User;
 
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
@@ -37,10 +41,11 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.when;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.nullable;
 
 /**
  * The test suite designed for test functionality of ComponentInstanceServlet class
@@ -132,6 +137,111 @@ public class ComponentInstanceServletTest extends JerseyTest {
         assertEquals(response.getStatus(), HttpStatus.OK_200);
     }
 
+    @Test
+    public void testBatchDeleteResourceInstancesSuccess() {
+
+        String componentId = "componentId";
+        String containerComponentType = ComponentTypeEnum.SERVICE_PARAM_NAME;
+        String compId1 = "compId1";
+        String[] delCompIds = new String[1];
+        delCompIds[0] = compId1;
+        List<ComponentInstance> compInsts = new ArrayList<ComponentInstance>();
+        String path = "/v1/catalog/" + containerComponentType + "/" + componentId + "/batchDeleteResourceInstances";
+
+        ComponentInstance compInst = new ComponentInstance();
+        compInst.setName(compId1);
+        compInst.setUniqueId(compId1);
+        compInst.setComponentUid(compId1);
+        compInst.setInvariantName(compId1);
+        compInsts.add(compInst);
+
+        when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
+        when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
+        Either<String[], ResponseFormat> convertStatusEither = Either.left(delCompIds);
+        when(componentsUtils
+                .convertJsonToObjectUsingObjectMapper(anyString(), any(User.class), ArgumentMatchers.<Class<String[]>>any(),
+                        nullable(AuditingActionEnum.class), nullable(ComponentTypeEnum.class))).thenReturn(convertStatusEither);
+        when(componentInstanceBusinessLogic
+                .batchDeleteComponentInstance(eq(containerComponentType), eq(componentId), any(List.class),
+                        eq(USER_ID))).thenReturn(Mockito.mock(Map.class));
+
+        Response response = target()
+                .path(path)
+                .request(MediaType.APPLICATION_JSON)
+                .header("USER_ID", USER_ID)
+                .post(Entity.json(compInsts));
+
+        assertEquals(HttpStatus.OK_200, response.getStatus());
+    }
+
+    @Test
+    public void testBatchDeleteResourceInstancesFailure() {
+
+        String componentId = "componentId";
+        String containerComponentType = ComponentTypeEnum.SERVICE_PARAM_NAME;
+        String path = "/v1/catalog/" + containerComponentType + "/" + componentId + "/batchDeleteResourceInstances";
+
+        when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
+        when(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)).thenReturn(responseFormat);
+
+        Response response = target()
+                .path(path)
+                .request(MediaType.APPLICATION_JSON)
+                .header("USER_ID", USER_ID)
+                .post(Entity.json(""));
+
+        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR_500, response.getStatus());
+    }
+
+    @Test
+    public void testBatchDissociateRIFromRISuccess() {
+
+        String componentId = "componentId";
+        String containerComponentType = ComponentTypeEnum.SERVICE_PARAM_NAME;
+        String path = "/v1/catalog/" + containerComponentType + "/" + componentId + "/resourceInstance/batchDissociate";
+        RequirementCapabilityRelDef[] refs = new RequirementCapabilityRelDef[1];
+        RequirementCapabilityRelDef ref = new RequirementCapabilityRelDef();
+        refs[0] = ref;
+
+        when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200);
+        when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat);
+        Either<RequirementCapabilityRelDef[], ResponseFormat> convertReqEither = Either.left(refs);
+        when(componentsUtils.convertJsonToObjectUsingObjectMapper(anyString(), any(User.class),
+                ArgumentMatchers.<Class<RequirementCapabilityRelDef[]>>any(),
+                nullable(AuditingActionEnum.class), nullable(ComponentTypeEnum.class))).thenReturn(convertReqEither);
+        Either<RequirementCapabilityRelDef, ResponseFormat> actionResponseEither = Either.left(ref);
+        when(componentInstanceBusinessLogic
+                .dissociateRIFromRI(componentId, USER_ID, ref, ComponentTypeEnum.findByParamName(containerComponentType)))
+                .thenReturn(actionResponseEither);
+
+        Response response = target()
+                .path(path)
+                .request(MediaType.APPLICATION_JSON)
+                .header("USER_ID", USER_ID)
+                .put(Entity.json(refs));
+
+        assertEquals(HttpStatus.OK_200, response.getStatus());
+    }
+
+    @Test
+    public void testBatchDissociateRIFromRIFailure() {
+
+        String componentId = "componentId";
+        String containerComponentType = ComponentTypeEnum.SERVICE_PARAM_NAME;
+        String path = "/v1/catalog/" + containerComponentType + "/" + componentId + "/resourceInstance/batchDissociate";
+
+        when(responseFormat.getStatus()).thenReturn(HttpStatus.INTERNAL_SERVER_ERROR_500);
+        when(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)).thenReturn(responseFormat);
+
+        Response response = target()
+                .path(path)
+                .request(MediaType.APPLICATION_JSON)
+                .header("USER_ID", USER_ID)
+                .put(Entity.json(""));
+
+        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR_500, response.getStatus());
+    }
+
     @Override
     protected ResourceConfig configure() {
         forceSet(TestProperties.CONTAINER_PORT, "0");