Fixed Review Comments - operation Business logic 91/41891/4
authormojahidi <mojahidul.islam@amdocs.com>
Tue, 10 Apr 2018 07:02:47 +0000 (12:32 +0530)
committerAvi Gaffa <avi.gaffa@amdocs.com>
Sun, 22 Apr 2018 08:45:17 +0000 (08:45 +0000)
Added interface operation Business logic and  amended validation logic

Change-Id: Ia98c625d732a31b03dec2d24504ecabb367e0582
Issue-ID: SDC-1060
Signed-off-by: mojahidi <mojahidul.islam@amdocs.com>
15 files changed:
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java
catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java
catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RepresentationUtils.java
catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceInterfaceOperationServlet.java [new file with mode: 0644]
catalog-be/src/main/resources/config/error-configuration.yaml
catalog-be/src/test/java/org/openecomp/sdc/be/components/InterfaceOperationTestUtils.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java [new file with mode: 0644]
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/TopologyTemplate.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java
catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceDataTransfer.java

diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java
new file mode 100644 (file)
index 0000000..05e7fe0
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.openecomp.sdc.be.components.impl;
+
+import com.google.common.collect.Sets;
+import fj.data.Either;
+import org.apache.commons.collections.MapUtils;
+import org.openecomp.sdc.be.components.validation.InterfaceOperationValidation;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.model.ArtifactDefinition;
+import org.openecomp.sdc.be.model.ComponentInstance;
+import org.openecomp.sdc.be.model.ComponentParametersView;
+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.User;
+import org.openecomp.sdc.be.model.jsontitan.operations.InterfaceOperation;
+import org.openecomp.sdc.be.model.jsontitan.utils.InterfaceUtils;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
+import org.openecomp.sdc.be.user.Role;
+import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
+import org.openecomp.sdc.common.api.ArtifactTypeEnum;
+import org.openecomp.sdc.exception.ResponseFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@Component("interfaceOperationBusinessLogic")
+public class InterfaceOperationBusinessLogic extends ComponentBusinessLogic{
+    private static final Logger LOGGER = LoggerFactory.getLogger(ResourceBusinessLogic.class);
+    @Autowired
+    private InterfaceOperationValidation interfaceOperationValidation;
+
+    @Autowired
+    private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
+
+    @Autowired
+    private InterfaceOperation interfaceOperation;
+
+    public void setInterfaceOperation(InterfaceOperation interfaceOperation) {
+        this.interfaceOperation = interfaceOperation;
+    }
+
+    public InterfaceOperationValidation getInterfaceOperationValidation() {
+        return interfaceOperationValidation;
+    }
+
+    public void setInterfaceOperationValidation(
+            InterfaceOperationValidation interfaceOperationValidation) {
+        this.interfaceOperationValidation = interfaceOperationValidation;
+    }
+
+
+    public Either<Resource, ResponseFormat> deleteInterfaceOperation(String resourceId, Set<String> interfaceOperationToDelete, User user, boolean lock) {
+        Resource resourceToDelete = initResourceToDeleteWFOp(resourceId, interfaceOperationToDelete);
+        Either<Resource, ResponseFormat> eitherDelete = validateUserAndRole(resourceToDelete, user, "deleteInterfaceOperation");
+        if (eitherDelete != null)
+            return eitherDelete;
+
+        Either<Resource, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(resourceId);
+        if (storageStatus.isRight()) {
+            return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.RESOURCE),""));
+        }
+        Resource resource = storageStatus.left().value();
+        if (lock) {
+            Either<Boolean, ResponseFormat> lockResult = lockComponent(resource.getUniqueId(), resource, "Delete interface Operation on a resource");
+            if (lockResult.isRight()) {
+                LOGGER.debug("Failed to lock resource {}. Response is {}. ", resource.getName(), lockResult.right().value().getFormattedMessage());
+                titanDao.rollback();
+                return Either.right(lockResult.right().value());
+            }
+        }
+
+        try {
+            Optional<InterfaceDefinition> optionalInterface = InterfaceUtils
+                    .getInterfaceDefinitionFromToscaName(resource.getInterfaces().values(), resource.getName());
+            Either<InterfaceDefinition, ResponseFormat> sValue = getInterfaceDefinition(resource, optionalInterface.orElse(null));
+            if (sValue.isRight()) {
+                return Either.right(sValue.right().value());
+            }
+            InterfaceDefinition interfaceDefinition = sValue.left().value();
+            Either<InterfaceDefinition, ResponseFormat> deleteEither;
+
+            for(String operationToDelete : interfaceOperationToDelete) {
+                deleteEither = deleteOperationFromInterface(interfaceDefinition, operationToDelete);
+                if (deleteEither.isRight()){
+                    return Either.right(deleteEither.right().value());
+                }
+                interfaceDefinition = deleteEither.left().value();
+            }
+
+            Either<InterfaceDefinition, StorageOperationStatus> interfaceUpdate = interfaceOperation.updateInterface(resource.getUniqueId(), interfaceDefinition);
+            if (interfaceUpdate.isRight()) {
+                LOGGER.debug("Failed to delete interface operation from resource {}. Response is {}. ", resource.getName(), interfaceUpdate.right().value());
+                titanDao.rollback();
+                return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(interfaceUpdate.right().value(), ComponentTypeEnum.RESOURCE)));
+            }
+
+            InterfaceDefinition interfaceDef = interfaceUpdate.left().value();
+            if(interfaceDef.getOperationsMap().isEmpty()){
+                Either<Set<String>, StorageOperationStatus> deleteInterface = interfaceOperation.deleteInterface(resource, Sets.newHashSet(interfaceDef.getUniqueId()));
+                if (deleteInterface.isRight()) {
+                    LOGGER.debug("Failed to delete interface from resource {}. Response is {}. ", resource.getName(), deleteInterface.right().value());
+                    titanDao.rollback();
+                    return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteInterface.right().value(), ComponentTypeEnum.RESOURCE)));
+                }
+            }
+
+            titanDao.commit();
+
+        } catch (Exception e){
+            LOGGER.error("Exception occurred during delete interface operation : {}", e.getMessage(), e);
+            titanDao.rollback();
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+        } finally {
+            graphLockOperation.unlockComponent(resource.getUniqueId(), NodeTypeEnum.Resource);
+        }
+        return Either.left(resource);
+    }
+
+    public Either<InterfaceDefinition, ResponseFormat> getInterfaceDefinition(Resource resource,
+                                                                              InterfaceDefinition interfaceDef) {
+        if (interfaceDef != null){
+            return Either.left(interfaceDef);
+        } else {
+            InterfaceDefinition interfaceDefinition = new InterfaceDefinition();
+            interfaceDefinition.setToscaResourceName(InterfaceUtils.createInterfaceToscaResourceName(resource.getName()));
+            Either<InterfaceDefinition, StorageOperationStatus> interfaceCreateEither = interfaceOperation
+                    .addInterface(resource.getUniqueId(), interfaceDefinition);
+            if (interfaceCreateEither.isRight()){
+                StorageOperationStatus sValue = interfaceCreateEither.right().value();
+                return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(sValue,
+                        ComponentTypeEnum.RESOURCE), ""));
+
+            }
+            return Either.left(interfaceCreateEither.left().value());
+        }
+    }
+
+    private Either<InterfaceDefinition,ResponseFormat> deleteOperationFromInterface(InterfaceDefinition interfaceDefinition, String operationId){
+        Optional<Map.Entry<String, Operation>> operationToRemove = interfaceDefinition.getOperationsMap().entrySet().stream()
+                .filter(entry -> entry.getValue().getUniqueId().equals(operationId)).findAny();
+        if (operationToRemove.isPresent()){
+            Map.Entry<String, Operation> stringOperationEntry = operationToRemove.get();
+            Map<String, Operation> tempMap = interfaceDefinition.getOperationsMap();
+            tempMap.remove(stringOperationEntry.getKey());
+            interfaceDefinition.setOperationsMap(tempMap);
+            return Either.left(interfaceDefinition);
+        }
+        LOGGER.debug("Failed to delete interface operation");
+        return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND));
+    }
+
+    private Either<InterfaceDefinition,ResponseFormat> addOperationToInterface(InterfaceDefinition interfaceDefinition, Operation interfaceOperation){
+        if(interfaceOperation.getUniqueId() == null)
+            interfaceOperation.setUniqueId(UUID.randomUUID().toString());
+        if (interfaceOperation.getImplementationArtifact() == null){
+            initNewOperation(interfaceOperation);
+        }
+        Map<String, Operation> tempMap = interfaceDefinition.getOperationsMap();
+        tempMap.put(interfaceOperation.getUniqueId(), interfaceOperation);
+        interfaceDefinition.setOperationsMap(tempMap);
+        return Either.left(interfaceDefinition);
+    }
+
+    private Either<InterfaceDefinition,ResponseFormat> updateOperationInInterface(InterfaceDefinition interfaceDefinition, Operation interfaceOperation){
+        Optional<Map.Entry<String, Operation>> operationToUpdate = interfaceDefinition.getOperationsMap().entrySet().stream()
+                .filter(entry -> entry.getValue().getUniqueId().equals(interfaceOperation.getUniqueId())).findAny();
+        if (operationToUpdate.isPresent()){
+            Operation updatedOperation = updateOperation(operationToUpdate.get().getValue(),interfaceOperation);
+            Map<String, Operation> tempMap = interfaceDefinition.getOperationsMap();
+            tempMap.remove(updatedOperation.getUniqueId());
+            tempMap.put(updatedOperation.getUniqueId(), updatedOperation);
+            interfaceDefinition.setOperationsMap(tempMap);
+            return Either.left(interfaceDefinition);
+        }
+        LOGGER.debug("Failed to update interface operation");
+        return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND));
+    }
+
+    private Operation updateOperation(Operation dbOperation, Operation updatedOperation) {
+        dbOperation.setName(updatedOperation.getName());
+        dbOperation.setDescription(updatedOperation.getDescription());
+        dbOperation.setInputs(updatedOperation.getInputs());
+        return dbOperation;
+    }
+
+    public Either<Resource, ResponseFormat> updateInterfaceOperation(String resourceId, Resource resourceUpdate, User user, boolean lock) {
+        return createOrUpdateInterfaceOperation(resourceId, resourceUpdate, user, true, "updateInterfaceOperation", lock);
+    }
+
+    public Either<Resource, ResponseFormat> createInterfaceOperation(String resourceId, Resource resourceUpdate, User user, boolean lock) {
+        return createOrUpdateInterfaceOperation(resourceId, resourceUpdate, user, false, "createInterfaceOperation", lock);
+    }
+
+    private Either<Resource, ResponseFormat> createOrUpdateInterfaceOperation(String resourceId, Resource resourceUpdate, User user, boolean isUpdate, String errorContext, boolean lock) {
+        Either<Resource, ResponseFormat> eitherCreator = validateUserAndRole(resourceUpdate, user, errorContext);
+        if (eitherCreator != null)
+            return eitherCreator;
+
+        Either<Resource, ResponseFormat> resourceEither = getResourceDetails(resourceId);
+        Resource storedResource = resourceEither.left().value();
+
+        Map<String, Operation> interfaceOperations = InterfaceUtils
+                .getInterfaceOperationsFromInterfaces(resourceUpdate.getInterfaces(), storedResource);
+        if(MapUtils.isEmpty(interfaceOperations) ) {
+            LOGGER.debug("Failed to fetch interface operations from resource {}, error {}",resourceUpdate.getUniqueId(),
+                    ActionStatus.INTERFACE_OPERATION_NOT_FOUND);
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND,
+                    resourceUpdate.getUniqueId()));
+        }
+
+        Either<Boolean, ResponseFormat> interfaceOperationValidationResponseEither = interfaceOperationValidation
+                .validateInterfaceOperations( interfaceOperations.values(), resourceId, isUpdate);
+
+        if(interfaceOperationValidationResponseEither.isRight()) {
+            return     Either.right(interfaceOperationValidationResponseEither.right().value());
+        }
+
+        Either<Boolean, ResponseFormat> lockResult = null;
+        if (lock) {
+            lockResult = lockComponent(storedResource.getUniqueId(), storedResource,
+                    "Create or Update interface Operation on Resource");
+            if (lockResult.isRight()) {
+                LOGGER.debug("Failed to lock resource {}. Response is {}. ", storedResource.getName(), lockResult.right().value().getFormattedMessage());
+                titanDao.rollback();
+                return Either.right(lockResult.right().value());
+            } else {
+                LOGGER.debug("The resource with system name {} locked. ", storedResource.getSystemName());
+            }
+        }
+
+        Either<InterfaceDefinition, ResponseFormat> result;
+        Map<String, InterfaceDefinition> resultMap = new HashMap<>();
+
+        try {
+            Optional<InterfaceDefinition> optionalInterface = InterfaceUtils
+                    .getInterfaceDefinitionFromToscaName(storedResource.getInterfaces().values(), storedResource.getName());
+            Either<InterfaceDefinition, ResponseFormat> sValue = getInterfaceDefinition(storedResource, optionalInterface.orElse(null));
+            if (sValue.isRight()) {
+                return Either.right(sValue.right().value());
+            }
+            InterfaceDefinition interfaceDefinition = sValue.left().value();
+
+            for (Operation interfaceOperation : interfaceOperations.values()) {
+                if (isUpdate) {
+                    result = updateOperationInInterface(interfaceDefinition, interfaceOperation);
+                } else {
+                    result = addOperationToInterface(interfaceDefinition, interfaceOperation);
+                }
+                if (result.isRight()) {
+                    titanDao.rollback();
+                    return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+                } else {
+                    interfaceDefinition = result.left().value();
+                    resultMap.put(interfaceDefinition.getUniqueId(), interfaceDefinition);
+                }
+            }
+
+            Either<InterfaceDefinition, StorageOperationStatus> interfaceUpdate = interfaceOperation
+                    .updateInterface(storedResource.getUniqueId(), interfaceDefinition);
+            if (interfaceUpdate.isRight()) {
+                LOGGER.debug("Failed to add or update interface operation on resource {}. Response is {}. ", storedResource.getName(), interfaceUpdate.right().value());
+                titanDao.rollback();
+                return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(interfaceUpdate.right().value(), ComponentTypeEnum.RESOURCE)));
+            }
+
+            titanDao.commit();
+
+            Resource resource = createVFWithInterfaceOperationForResponse(resourceId, resultMap);
+            return Either.left(resource);
+        }
+        catch (Exception e) {
+            titanDao.rollback();
+            LOGGER.error("Exception occurred during add or update interface operation property values:{}",
+                    e.getMessage(), e);
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+        }
+        finally {
+            if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
+                graphLockOperation.unlockComponent(storedResource.getUniqueId(), NodeTypeEnum.Resource);
+            }
+        }
+    }
+
+    private void initNewOperation(Operation operation){
+        ArtifactDefinition artifactDefinition = new ArtifactDefinition();
+        String artifactUUID = UUID.randomUUID().toString();
+        artifactDefinition.setArtifactUUID(artifactUUID);
+        artifactDefinition.setUniqueId(artifactUUID);
+        artifactDefinition.setArtifactType(ArtifactTypeEnum.PLAN.getType());
+        artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.LIFE_CYCLE);
+        operation.setImplementation(artifactDefinition);
+    }
+
+    private Resource initResourceToDeleteWFOp(String resourceId, Collection<String> interfaceOperationsToDelete) {
+        InterfaceDefinition id = new InterfaceDefinition();
+        id.setUniqueId(UUID.randomUUID().toString());
+        interfaceOperationsToDelete.forEach(interfaceOpToDelete -> id.getOperationsMap().put(interfaceOpToDelete, new Operation()));
+        Map<String, InterfaceDefinition> interfaceDefinitionMap = new HashMap<>();
+        interfaceDefinitionMap.put(id.getUniqueId(), id);
+
+        Resource resourceToDelete = new Resource();
+        resourceToDelete.setUniqueId(resourceId);
+        resourceToDelete.setInterfaces(interfaceDefinitionMap);
+
+        return resourceToDelete;
+    }
+
+    private Either<Resource, ResponseFormat> validateUserAndRole(Resource resourceUpdate, User user, String errorContext) {
+        Either<User, ResponseFormat> userEither = validateUser(user, errorContext, resourceUpdate, null, false);
+        if (userEither.isRight()) {
+            return Either.right(userEither.right().value());
+        }
+        user = userEither.left().value();
+
+        Either<Boolean, ResponseFormat> userRoleEither = validateUserRole(user, resourceUpdate, new ArrayList<>(), null, null);
+        if (userRoleEither.isRight()) {
+            return Either.right(userRoleEither.right().value());
+        }
+        return null;
+    }
+
+
+
+    private Resource createVFWithInterfaceOperationForResponse(String resourceId, Map<String, InterfaceDefinition> interfaceDefinitionMap) {
+        Resource resource = new Resource();
+        resource.setUniqueId(resourceId);
+        resource.setInterfaces(interfaceDefinitionMap);
+        return resource;
+    }
+
+    public Either<Resource, ResponseFormat> getResourceDetails(String resourceId){
+        Either<Resource, StorageOperationStatus> resourceStorageOperationStatusEither =
+                toscaOperationFacade.getToscaElement(resourceId);
+        if (resourceStorageOperationStatusEither.isRight()) {
+            StorageOperationStatus errorStatus = resourceStorageOperationStatusEither.right().value();
+            LOGGER.error("Failed to fetch resource information by resource id {}, error {}", resourceId, errorStatus);
+            return Either.right(componentsUtils
+                    .getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
+        }
+        return Either.left(resourceStorageOperationStatusEither.left().value());
+    }
+
+
+    @Override
+    public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
+        return deleteMarkedComponents(ComponentTypeEnum.RESOURCE);
+    }
+
+    @Override
+    public ComponentInstanceBusinessLogic getComponentInstanceBL() {
+        return componentInstanceBusinessLogic;
+    }
+
+    @Override
+    public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId,
+                                                      ComponentTypeEnum componentTypeEnum, String userId, String searchText) {
+        return null;
+    }
+
+    @Override
+    public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String resourceId,
+                                                                    List<String> dataParamsToReturn) {
+        ComponentParametersView paramsToRetuen = new ComponentParametersView(dataParamsToReturn);
+        Either<Resource, StorageOperationStatus> resourceResultEither = toscaOperationFacade.getToscaElement(resourceId,
+                paramsToRetuen);
+
+        if (resourceResultEither.isRight()) {
+            if (resourceResultEither.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
+                LOGGER.error("Failed to found resource with id {} ", resourceId);
+                Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceId));
+            }
+
+            LOGGER.error("failed to get resource by id {} with filters {}", resourceId, dataParamsToReturn);
+            return Either.right(componentsUtils.getResponseFormatByResource(
+                    componentsUtils.convertFromStorageResponse(resourceResultEither.right().value()), ""));
+        }
+
+        Resource resource = resourceResultEither.left().value();
+        UiComponentDataTransfer dataTransfer = UiComponentDataConverter.getUiDataTransferFromResourceByParams(resource,
+                dataParamsToReturn);
+        return Either.left(dataTransfer);
+    }
+}
index 0dce2a3..bbdb14f 100644 (file)
@@ -21,6 +21,7 @@
 package org.openecomp.sdc.be.components.impl;
 
 
+import com.google.common.collect.Sets;
 import com.google.gson.Gson;
 import fj.data.Either;
 import org.apache.commons.codec.binary.Base64;
@@ -39,6 +40,7 @@ import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum;
 import org.openecomp.sdc.be.components.merge.resource.MergeResourceBLFactory;
 import org.openecomp.sdc.be.components.merge.resource.MergeResourceBusinessLogic;
+import org.openecomp.sdc.be.components.validation.InterfaceOperationValidation;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
 import org.openecomp.sdc.be.config.ConfigurationManager;
@@ -92,6 +94,8 @@ import org.openecomp.sdc.be.model.User;
 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
 import org.openecomp.sdc.be.model.category.CategoryDefinition;
 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
+import org.openecomp.sdc.be.model.jsontitan.operations.InterfaceOperation;
+import org.openecomp.sdc.be.model.jsontitan.utils.InterfaceUtils;
 import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
 import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation;
 import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation;
@@ -131,8 +135,17 @@ import org.yaml.snakeyaml.Yaml;
 import org.yaml.snakeyaml.parser.ParserException;
 
 import javax.servlet.ServletContext;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.Set;
 import java.util.function.Function;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -203,8 +216,15 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
     @Autowired
     private CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic;
 
+    @Autowired
+    private InterfaceOperation interfaceOperation;
+
     private Gson gson = new Gson();
 
+    public void setInterfaceOperation(InterfaceOperation interfaceOperation) {
+        this.interfaceOperation = interfaceOperation;
+    }
+
     public CsarOperation getCsarOperation() {
         return csarOperation;
     }
@@ -265,6 +285,10 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         this.applicationDataTypeCache = applicationDataTypeCache;
     }
 
+    public void setInterfaceTypeOperation(IInterfaceLifecycleOperation interfaceTypeOperation) {
+        this.interfaceTypeOperation = interfaceTypeOperation;
+    }
+
     /**
      * the method returns a list of all the resources that are certified, the
      * returned resources are only abstract or only none abstract according to
@@ -5181,6 +5205,13 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                 newResource.setDerivedFrom(null);
             }
 
+            Either<Boolean, ResponseFormat> validateAndUpdateInterfacesEither = validateAndUpdateInterfaces(resourceIdToUpdate, newResource);
+            if (validateAndUpdateInterfacesEither.isRight()) {
+                log.error("failed to validate and update Interfaces !!!");
+                rollbackNeeded = true;
+                return Either.right(validateAndUpdateInterfacesEither.right().value());
+            }
+
             Either<Resource, ResponseFormat> dataModelResponse = updateResourceMetadata(resourceIdToUpdate, newResource,
                     user, currentResource, false, true);
             if (dataModelResponse.isRight()) {
@@ -5652,7 +5683,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                  ResponseFormat errorResponse = componentsUtils
                          .getResponseFormat(ActionStatus.RESOURCE_VENDOR_NAME_CANNOT_BE_CHANGED);
                  return Either.right(errorResponse);
-               
+
             }
             else {
                 Either<Boolean, ResponseFormat> validateVendorName = validateVendorName(null, updateInfoResource, null);
@@ -5660,7 +5691,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                     ResponseFormat errorResponse = validateVendorName.right().value();
                     return Either.right(errorResponse);
                 }
-            } 
+            }
         }
         return Either.left(true);
     }
@@ -6759,5 +6790,65 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         }
     }
 
+    private Either<Boolean, ResponseFormat> validateAndUpdateInterfaces(String resourceId, Resource resourceUpdate) {
+        Either<Resource, StorageOperationStatus> resourceStorageOperationStatusEither =
+                toscaOperationFacade.getToscaElement(resourceId);
+        if (resourceStorageOperationStatusEither.isRight()) {
+            StorageOperationStatus errorStatus = resourceStorageOperationStatusEither.right().value();
+            log.error("Failed to fetch resource information by resource id {}, error {}", resourceId, errorStatus);
+            return Either.right(componentsUtils
+                    .getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
+        }
+
+        Resource storedResource = resourceStorageOperationStatusEither.left().value();
+        Map<String, InterfaceDefinition> storedResourceInterfaces = storedResource.getInterfaces();
+
+        if(!storedResource.getName().equals(resourceUpdate.getName()) ) {
+            Collection<InterfaceDefinition> interfaceDefinitionListFromToscaName = InterfaceUtils
+                    .getInterfaceDefinitionListFromToscaName(storedResource.getInterfaces().values(),
+                            storedResource.getName());
+
+            for (InterfaceDefinition interfaceDefinition : storedResourceInterfaces.values()) {
+                Either<InterfaceDefinition, ResponseFormat> updateInterfaceDefinitionEither = updateInterfaceDefinition(resourceUpdate,
+                        interfaceDefinition,
+                        interfaceDefinitionListFromToscaName);
+                if(updateInterfaceDefinitionEither.isRight()) {
+                    return Either.right(updateInterfaceDefinitionEither.right().value());
+                }
+            }
+        }
+
+        return  Either.left(Boolean.TRUE);
+    }
+
+    private Either<InterfaceDefinition, ResponseFormat > updateInterfaceDefinition(Resource resourceUpdate,
+                                                                                   InterfaceDefinition interfaceDefinition,
+                                                                                   Collection<InterfaceDefinition> interfaceDefinitionListFromToscaName) {
+        interfaceDefinitionListFromToscaName.forEach(interfaceDefinitionFromList -> {
+            if(interfaceDefinitionFromList.getToscaResourceName().equals(interfaceDefinition
+                    .getToscaResourceName())) {
+                log.info("Going to Update interface definition toscaResourceName {} to {}",
+                        interfaceDefinitionFromList.getToscaResourceName(),
+                        InterfaceUtils.createInterfaceToscaResourceName(resourceUpdate.getName()));
+                interfaceDefinition.setToscaResourceName(InterfaceUtils
+                        .createInterfaceToscaResourceName(resourceUpdate.getName()));
+            }
+        } );
+        try {
+            Either<InterfaceDefinition, StorageOperationStatus> interfaceUpdate = interfaceOperation
+                    .updateInterface(resourceUpdate.getUniqueId(), interfaceDefinition);
+            if (interfaceUpdate.isRight()) {
+                log.error("Failed to Update interface {}. Response is {}. ", resourceUpdate.getName(), interfaceUpdate.right().value());
+                titanDao.rollback();
+                return Either.right(componentsUtils
+                        .getResponseFormat(componentsUtils.convertFromStorageResponse(interfaceUpdate.right().value(), ComponentTypeEnum.RESOURCE)));
+            }
+        } catch (Exception e) {
+            log.error("Exception occurred during update interface toscaResourceName  : {}", e.getMessage(), e);
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+        }
+
+        return Either.left( interfaceDefinition);
 
+    }
 }
\ No newline at end of file
index bf3385a..3d3cca4 100644 (file)
@@ -20,6 +20,7 @@ import fj.data.Either;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
+import org.elasticsearch.common.Strings;
 import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.model.ComponentParametersView;
@@ -53,12 +54,12 @@ public class InterfaceOperationValidation {
     private static final Logger LOGGER = LoggerFactory.getLogger(InterfaceOperationValidation.class);
 
     public Either<Boolean, ResponseFormat> validateInterfaceOperations(
-        Collection<Operation> interfaceOperations,
-        String resourceId, boolean isUpdate) {
+            Collection<Operation> interfaceOperations,
+            String resourceId, boolean isUpdate) {
 
         for(Operation interfaceOperation : interfaceOperations) {
             Either<Boolean, ResponseFormat> interfaceOperationValidatorResponse = validateInterfaceOperation(
-                interfaceOperation, resourceId, isUpdate);
+                    interfaceOperation, resourceId, isUpdate);
             if (interfaceOperationValidatorResponse.isRight()) {
                 return interfaceOperationValidatorResponse;
             }
@@ -70,105 +71,106 @@ public class InterfaceOperationValidation {
                                                                        String resourceId, boolean isUpdate) {
         ResponseFormatManager responseFormatManager = getResponseFormatManager();
 
-        Either<Boolean, ResponseFormat> interfaceOperationTypeResponse = validateInterfaceOperationType(interfaceOperation,
-            responseFormatManager, resourceId, isUpdate);
-        if (interfaceOperationTypeResponse != null) {
-            return interfaceOperationTypeResponse;
+        Either<Boolean, ResponseFormat> interfaceOperationTypeResponse = isInterfaceOperationTypeValid(interfaceOperation,
+                responseFormatManager, resourceId, isUpdate);
+        if (interfaceOperationTypeResponse.isRight()) {
+            return Either.right(interfaceOperationTypeResponse.right().value());
         }
 
-        Either<Boolean, ResponseFormat> descriptionResponseEither = validateDescription(responseFormatManager,
-            interfaceOperation.getDescription());
-        if (descriptionResponseEither != null) {
-            return descriptionResponseEither;
+        Either<Boolean, ResponseFormat> descriptionResponseEither = isValidDescription(responseFormatManager,
+                interfaceOperation.getDescription());
+        if (descriptionResponseEither.isRight()) {
+            return Either.right(descriptionResponseEither.right().value());
         }
 
         Either<Boolean, ResponseFormat> inputParametersResponse = validateInputParameters(interfaceOperation,
                 responseFormatManager);
-        if(inputParametersResponse != null) {
-            return inputParametersResponse;
+        if(inputParametersResponse.isRight()) {
+            return Either.right(inputParametersResponse.right().value());
         }
-        return Either.left(true);
+        return Either.left(Boolean.TRUE);
     }
 
-    private Either<Boolean, ResponseFormat> validateInterfaceOperationType(Operation interfaceOperation,
-                                                                           ResponseFormatManager responseFormatManager,
-                                                                           String resourceId, boolean isUpdate) {
+    private Either<Boolean, ResponseFormat> isInterfaceOperationTypeValid(Operation interfaceOperation,
+                                                                          ResponseFormatManager responseFormatManager,
+                                                                          String resourceId, boolean isUpdate) {
 
         Either<Boolean, ResponseFormat> operationTypeEmptyEither = isOperationTypeEmpty(responseFormatManager,
-            interfaceOperation.getName());  // treating name as type for now
-        if (operationTypeEmptyEither != null) {
-            return operationTypeEmptyEither;
+                interfaceOperation.getName());  // treating name as type for now
+        if (operationTypeEmptyEither.isRight()) {
+            return Either.right(operationTypeEmptyEither.right().value());
         }
 
         Either<Boolean, ResponseFormat> operationTypeRegexValidationResponse =
-            validateOperationTypeRegex(responseFormatManager, interfaceOperation.getName());
-        if (operationTypeRegexValidationResponse != null) {
-            return operationTypeRegexValidationResponse;
+                isOperationTypeRegexValid(responseFormatManager, interfaceOperation.getName());
+        if (operationTypeRegexValidationResponse.isRight()) {
+            return Either.right(operationTypeRegexValidationResponse.right().value());
         }
 
         Either<Boolean, ResponseFormat> operationTypeUniqueResponse = validateOperationTypeUnique(interfaceOperation,
-            resourceId, isUpdate, responseFormatManager );
+                resourceId, isUpdate, responseFormatManager );
         if(operationTypeUniqueResponse.isRight()) {
             return Either.right(operationTypeUniqueResponse.right().value());
         }
         if (!operationTypeUniqueResponse.left().value()) {
-            LOGGER.debug("Interface Operation type  {} already in use ", interfaceOperation.getName());
+            LOGGER.error("Interface Operation type  {} already in use ", interfaceOperation.getName());
             ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
-                .INTERFACE_OPERATION_TYPE_ALREADY_IN_USE, interfaceOperation.getName());
+                    .INTERFACE_OPERATION_TYPE_ALREADY_IN_USE, interfaceOperation.getName());
             return Either.right(errorResponse);
         }
-        return null;
+        return Either.left(Boolean.TRUE);
     }
 
-    private Either<Boolean, ResponseFormat> validateOperationTypeRegex(ResponseFormatManager responseFormatManager,
-                                                                       String operationType) {
+    private Either<Boolean, ResponseFormat> isOperationTypeRegexValid(ResponseFormatManager responseFormatManager,
+                                                                      String operationType) {
         if (!isValidOperationType(operationType)) {
-            LOGGER.debug("Interface Operation type {} is invalid, Operation type should not contain" +
-                "Special character, space and  should not be greater than 200 characters", operationType);
+            LOGGER.error("Interface Operation type {} is invalid, Operation type should not contain" +
+                    "Special character, space, numbers and  should not be greater than 200 characters", operationType);
             ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
-                .INTERFACE_OPERATION_TYPE_INVALID, operationType);
+                    .INTERFACE_OPERATION_TYPE_INVALID, operationType);
             return Either.right(errorResponse);
         }
-        return null;
+        return Either.left(Boolean.TRUE);
     }
 
     private Either<Boolean, ResponseFormat> isOperationTypeEmpty(ResponseFormatManager responseFormatManager,
                                                                  String operationType) {
         if (StringUtils.isEmpty(operationType)) {
-            LOGGER.debug("Interface Operation type is mandatory,  it can't be empty");
+            LOGGER.error("Interface Operation type is mandatory");
             ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
-                .INTERFACE_OPERATION_TYPE_MANDATORY);
+                    .INTERFACE_OPERATION_TYPE_MANDATORY);
             return Either.right(errorResponse);
         }
-        return null;
+        return Either.left(Boolean.TRUE);
     }
 
-    private Either<Boolean, ResponseFormat> validateDescription(ResponseFormatManager responseFormatManager,
-                                                                String description) {
-        if (description.length() > DESCRIPTION_MAX_LENGTH) {
-            LOGGER.debug("Interface Operation description {} is invalid, maximum 200 characters allowed", description);
+    private Either<Boolean, ResponseFormat> isValidDescription(ResponseFormatManager responseFormatManager,
+                                                               String description) {
+        if (!Strings.isNullOrEmpty(description) && description.length() > DESCRIPTION_MAX_LENGTH) {
+            LOGGER.error("Interface Operation description {} is invalid, maximum 200 characters allowed", description);
             ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
-                .INTERFACE_OPERATION_DESCRIPTION_MAX_LENGTH);
+                    .INTERFACE_OPERATION_DESCRIPTION_MAX_LENGTH);
             return Either.right(errorResponse);
         }
-        return null;
+        return Either.left(Boolean.TRUE);
     }
 
     private boolean isValidOperationType(String operationType) {
         return Pattern.matches(TYPE_VALIDATION_REGEX, operationType);
     }
 
-    private Either<Boolean, ResponseFormat> validateOperationTypeUnique(Operation interfaceOperation,
-                                                                        String resourceId,
-                                                                        boolean isUpdate,
-                                                                        ResponseFormatManager responseFormatManager) {
+    private Either<Boolean, ResponseFormat> validateOperationTypeUnique(
+            Operation interfaceOperation,
+            String resourceId,
+            boolean isUpdate,
+            ResponseFormatManager responseFormatManager) {
         boolean isOperationTypeUnique = false;
         ComponentParametersView filter = new ComponentParametersView(true);
         filter.setIgnoreInterfaces(false);
         Either<Resource, StorageOperationStatus> interfaceOperationOrigin = toscaOperationFacade
-            .getToscaElement(resourceId, filter);
+                .getToscaElement(resourceId, filter);
         if (interfaceOperationOrigin.isRight()){
-            LOGGER.debug("Failed to fetch interface operation information by resource id {} ", resourceId);
+            LOGGER.error("Failed to fetch interface operation information by resource id {} ", resourceId);
             return Either.right(responseFormatManager.getResponseFormat(ActionStatus.GENERAL_ERROR));
         }
 
@@ -189,7 +191,7 @@ public class InterfaceOperationValidation {
 
         Map<String, String> operationTypes = new HashMap<>();
         allOperations.forEach(operationType -> operationTypes.put(operationType.getUniqueId(),
-            operationType.getName()) );
+                operationType.getName()) );
 
         if (isUpdate){
             isOperationTypeUnique = validateOperationTypeUniqueForUpdate(interfaceOperation, operationTypes);
@@ -202,25 +204,25 @@ public class InterfaceOperationValidation {
     }
     private Either<Boolean, ResponseFormat> validateInputParameters(Operation interfaceOperation,
                                                                     ResponseFormatManager responseFormatManager) {
-        Either<Boolean, Set<String>> validateInputParametersUniqueResponse = validateInputParametersUnique(interfaceOperation);
+        Either<Boolean, Set<String>> validateInputParametersUniqueResponse = isInputParametersUnique(interfaceOperation);
         if(validateInputParametersUniqueResponse.isRight()) {
-            LOGGER.debug("Interface operation input  parameter names {} are invalid, Input parameter names should be unique",
+            LOGGER.error("Interface operation input  parameter names {} are invalid, Input parameter names should be unique",
                     validateInputParametersUniqueResponse.right().value().toString());
             ResponseFormat inputResponse = responseFormatManager.getResponseFormat(ActionStatus
                     .INTERFACE_OPERATION_INPUT_NAME_INVALID, validateInputParametersUniqueResponse.right().value().toString());
             return Either.right(inputResponse);
         }
-        return  null;
+        return Either.left(Boolean.TRUE);
     }
 
-    private Either<Boolean, Set<String>> validateInputParametersUnique(Operation operationDataDefinition) {
+    private Either<Boolean, Set<String>> isInputParametersUnique(Operation operationDataDefinition) {
 
         Set<String> inputParamNamesSet = new HashSet<>();
         Set<String> duplicateParamNamesToReturn = new HashSet<>();
         operationDataDefinition.getInputs().getListToscaDataDefinition()
                 .forEach(inputParam -> {
-                    if(!inputParamNamesSet.add(inputParam.getLabel())) {
-                        duplicateParamNamesToReturn.add(inputParam.getLabel());
+                    if(!inputParamNamesSet.add(inputParam.getName())) {
+                        duplicateParamNamesToReturn.add(inputParam.getName());
                     }
                 });
         if(!duplicateParamNamesToReturn.isEmpty()) {
@@ -235,12 +237,12 @@ public class InterfaceOperationValidation {
         boolean isOperationTypeUnique = false;
         for(Map.Entry<String, String> entry : operationTypes.entrySet()){
             if (entry.getKey().equals(interfaceOperation.getUniqueId()) && entry.getValue().
-                equals(interfaceOperation.getName())) {
+                    equals(interfaceOperation.getName())) {
                 isOperationTypeUnique = true;
             }
 
             if(entry.getKey().equals(interfaceOperation.getUniqueId()) && !operationTypes.values()
-                .contains(interfaceOperation.getName())){
+                    .contains(interfaceOperation.getName())){
                 isOperationTypeUnique = true;
             }
         }
index 0e0d20f..937ec87 100644 (file)
@@ -30,6 +30,7 @@ import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic;
 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
 import org.openecomp.sdc.be.components.impl.ElementBusinessLogic;
 import org.openecomp.sdc.be.components.impl.GroupBusinessLogic;
+import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic;
 import org.openecomp.sdc.be.components.impl.MonitoringBusinessLogic;
 import org.openecomp.sdc.be.components.impl.PolicyBusinessLogic;
 import org.openecomp.sdc.be.components.impl.PolicyTypeBusinessLogic;
@@ -145,6 +146,9 @@ public class BeGenericServlet extends BasicServlet {
     protected ResourceBusinessLogic getResourceBL(ServletContext context) {
         return getClassFromWebAppContext(context, () -> ResourceBusinessLogic.class);
     }
+    protected InterfaceOperationBusinessLogic getInterfaceOperationBL(ServletContext context) {
+        return getClassFromWebAppContext(context, () -> InterfaceOperationBusinessLogic.class);
+    }
 
     protected ComponentsCleanBusinessLogic getComponentCleanerBL(ServletContext context) {
         return getClassFromWebAppContext(context, () -> ComponentsCleanBusinessLogic.class);
index 127fb98..ea6b34a 100644 (file)
@@ -39,6 +39,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
+import org.openecomp.sdc.be.datatypes.elements.InterfaceOperationDataDefinition;
 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
 import org.openecomp.sdc.be.model.ArtifactDefinition;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
@@ -196,6 +197,7 @@ public class RepresentationUtils {
             .put(InterfaceDefinition.class,IsEmptyFilterMixIn.class)
             .put(Operation.class,IsEmptyFilterMixIn.class)
             .put(Resource.class,IsEmptyFilterMixIn.class)
-            .put(ToscaDataDefinition.class,IsEmptyFilterMixIn.class).build();
+            .put(ToscaDataDefinition.class,IsEmptyFilterMixIn.class)
+            .put(InterfaceOperationDataDefinition.class,IsEmptyFilterMixIn.class).build();
 
 }
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceInterfaceOperationServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceInterfaceOperationServlet.java
new file mode 100644 (file)
index 0000000..49bce3b
--- /dev/null
@@ -0,0 +1,317 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.servlets;
+
+import com.google.common.collect.Sets;
+import com.jcabi.aspects.Loggable;
+import fj.data.Either;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic;
+import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
+import org.openecomp.sdc.be.config.BeEcompErrorManager;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.datamodel.utils.InterfaceUIDataConverter;
+import org.openecomp.sdc.be.datatypes.elements.InterfaceOperationDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+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.User;
+import org.openecomp.sdc.be.model.jsontitan.utils.InterfaceUtils;
+import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
+import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
+import org.openecomp.sdc.be.ui.model.UiResourceDataTransfer;
+import org.openecomp.sdc.common.api.Constants;
+import org.openecomp.sdc.exception.ResponseFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Singleton;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+
+@Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
+@Path("/v1/catalog/resources/{resourceId}/interfaceOperations")
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Api(value = "Interface Operation", description = "Interface Operation Servlet")
+@Singleton
+public class ResourceInterfaceOperationServlet extends AbstractValidationsServlet {
+
+  private static final Logger log = LoggerFactory.getLogger(ResourceInterfaceOperationServlet.class);
+
+  @POST
+  @Consumes(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON)
+  @Path("/")
+  @ApiOperation(value = "Create Interface Operation", httpMethod = "POST", notes = "Create Interface Operation", response = InterfaceOperationDataDefinition.class)
+  @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Interface Operation"),
+      @ApiResponse(code = 403, message = "Restricted operation"),
+      @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+      @ApiResponse(code = 409, message = "Interface Operation already exist")})
+  public Response createInterfaceOperation(
+      @ApiParam(value = "Interface Operation to create", required = true) String data,
+      @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
+      @Context final HttpServletRequest request,
+      @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+    return createOrUpdate(data, resourceId, request, userId, false);
+  }
+
+
+  @PUT
+  @Consumes(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON)
+  @Path("/")
+  @ApiOperation(value = "Update Interface Operation", httpMethod = "PUT", notes = "Update Interface Operation", response = InterfaceOperationDataDefinition.class)
+  @ApiResponses(value = {@ApiResponse(code = 201, message = "Update Interface Operation"),
+      @ApiResponse(code = 403, message = "Restricted operation"),
+      @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+  public Response updateInterfaceOperation(
+      @ApiParam(value = "Interface Operation to update", required = true) String data,
+      @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
+      @Context final HttpServletRequest request,
+      @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+    return createOrUpdate(data, resourceId, request, userId, true);
+  }
+
+
+  @DELETE
+  @Consumes(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON)
+  @Path("/{interfaceOperationId}")
+  @ApiOperation(value = "Delete Interface Operation", httpMethod = "DELETE", notes = "Delete Interface Operation", response = InterfaceOperationDataDefinition.class)
+  @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete Interface Operation"),
+      @ApiResponse(code = 403, message = "Restricted operation"),
+      @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+  public Response deleteInterfaceOperation(
+      @ApiParam(value = "Interface Operation Id") @PathParam("interfaceOperationId") String interfaceOperationId,
+      @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
+      @Context final HttpServletRequest request,
+      @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+    return delete(interfaceOperationId, resourceId, request, userId);
+  }
+
+  @GET
+  @Consumes(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON)
+  @Path("/{interfaceOperationId}")
+  @ApiOperation(value = "Get Interface Operation", httpMethod = "GET", notes = "GET Interface Operation", response = InterfaceOperationDataDefinition.class)
+  @ApiResponses(value = {@ApiResponse(code = 201, message = "Get Interface Operation"),
+      @ApiResponse(code = 403, message = "Restricted operation"),
+      @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+  public Response getInterfaceOperation(
+      @ApiParam(value = "Interface Operation Id") @PathParam("interfaceOperationId") String interfaceOperationId,
+      @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
+      @Context final HttpServletRequest request,
+      @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+    return get(interfaceOperationId, resourceId, request, userId);
+  }
+
+  private Response get (String interfaceOperationId, String resourceId, HttpServletRequest request, String userId){
+    ServletContext context = request.getSession().getServletContext();
+    String url = request.getMethod() + " " + request.getRequestURI();
+
+    User modifier = new User();
+    modifier.setUserId(userId);
+    log.debug("Start get request of {} with modifier id {}", url, userId);
+
+    try {
+      InterfaceOperationBusinessLogic businessLogic = getInterfaceOperationBL(context);
+      Either<UiComponentDataTransfer, ResponseFormat> resourceResponse = businessLogic.getComponentDataFilteredByParams(resourceId, modifier, Collections
+          .singletonList(ComponentFieldsEnum.INTERFACES.getValue()));
+      if (resourceResponse.isRight()) {
+        return buildErrorResponse(resourceResponse.right().value());
+      }
+
+      UiResourceDataTransfer uiResourceDataTransfer = (UiResourceDataTransfer) resourceResponse.left().value();
+      InterfaceOperationDataDefinition interfaceOperationDataDefinition = getInterfaceOperationForResponse(interfaceOperationId, uiResourceDataTransfer.getInterfaces());
+
+      return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toFilteredRepresentation(interfaceOperationDataDefinition));
+
+    } catch (Exception e) {
+      BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource interface operations");
+      log.debug("get resource interface operations failed with exception", e);
+      return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+    }
+  }
+
+  private Response delete (String interfaceOperationId, String resourceId, HttpServletRequest
+      request, String userId){
+
+    ServletContext context = request.getSession().getServletContext();
+    String url = request.getMethod() + " " + request.getRequestURI();
+
+    User modifier = new User();
+    modifier.setUserId(userId);
+    log.debug("Start delete request of {} with modifier id {}", url, userId);
+
+    Response response;
+
+    try {
+      String resourceIdLower = resourceId.toLowerCase();
+      InterfaceOperationBusinessLogic businessLogic = getInterfaceOperationBL(context);
+
+      Either<Resource, ResponseFormat> actionResponse = businessLogic.deleteInterfaceOperation(resourceIdLower, Sets.newHashSet(interfaceOperationId), modifier, true);
+
+      if (actionResponse.isRight()) {
+        log.debug("failed to delete interface operation");
+        response = buildErrorResponse(actionResponse.right().value());
+        return response;
+      }
+
+      Resource resource = actionResponse.left().value();
+      InterfaceOperationDataDefinition interfaceOperationDataDefinition = getInterfaceOperationForResponse(interfaceOperationId, resource.getInterfaces());
+      Object result = RepresentationUtils.toFilteredRepresentation(interfaceOperationDataDefinition);
+      return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
+
+    } catch (Exception e) {
+      BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Interface Operation");
+      log.debug("Delete interface operation with an error", e);
+      response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+      return response;
+
+    }
+  }
+
+  private Response createOrUpdate (String data, String resourceId, HttpServletRequest request, String userId, boolean isUpdate) {
+    ServletContext context = request.getSession().getServletContext();
+    String url = request.getMethod() + " " + request.getRequestURI();
+
+    User modifier = new User();
+    modifier.setUserId(userId);
+    log.debug("Start create or update request of {} with modifier id {}", url, userId);
+
+    Response response;
+    try {
+      String resourceIdLower = resourceId.toLowerCase();
+      InterfaceOperationBusinessLogic businessLogic = getInterfaceOperationBL(context);
+
+      Either<Resource, ResponseFormat> resourceEither = businessLogic.getResourceDetails(resourceId);
+      Resource origResource = resourceEither.left().value();
+
+      Either<Resource, ResponseFormat> convertResponse = parseToResource(data, origResource, isUpdate, modifier);
+      if (convertResponse.isRight()) {
+        log.debug("failed to parse resource");
+        response = buildErrorResponse(convertResponse.right().value());
+        return response;
+      }
+
+      Resource updatedResource = convertResponse.left().value();
+      Either<Resource, ResponseFormat> actionResponse ;
+      if (isUpdate) {
+        actionResponse = businessLogic.updateInterfaceOperation(resourceIdLower, updatedResource, modifier, true);
+      } else {
+        actionResponse = businessLogic.createInterfaceOperation(resourceIdLower, updatedResource, modifier, true);
+      }
+
+      if (actionResponse.isRight()) {
+        log.debug("failed to update or create interface operation");
+        response = buildErrorResponse(actionResponse.right().value());
+        return response;
+      }
+
+      Resource resource = actionResponse.left().value();
+      List<Operation> operationData = InterfaceUtils.getOperationsFromInterface(updatedResource.getInterfaces());
+      InterfaceOperationDataDefinition interfaceOperationDataDefinition = getInterfaceOperationForResponse(operationData.get(0).getUniqueId(), resource.getInterfaces());
+
+      Object result = RepresentationUtils.toFilteredRepresentation(interfaceOperationDataDefinition);
+      return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
+
+    } catch (Exception e) {
+      BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Interface Operation Creation or update");
+      log.debug("create or update interface Operation with an error", e);
+      response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+      return response;
+
+    }
+  }
+
+  private Either<Resource, ResponseFormat> parseToResource(String resourceJson, Resource origResource, boolean isUpdate, User user) {
+
+    Resource resource = convertToResourceObject(resourceJson, user).left().value();
+
+    Either<UiResourceDataTransfer, ResponseFormat> uiResourceEither = getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, UiResourceDataTransfer.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE);
+    Optional<InterfaceOperationDataDefinition> opDef = uiResourceEither.left().value().getInterfaceOperations().values().stream().findFirst();
+    InterfaceOperationDataDefinition interfaceOperationDataDefinition;
+    if(opDef.isPresent()) {
+      interfaceOperationDataDefinition = opDef.get();
+
+      if(!isUpdate)
+        interfaceOperationDataDefinition.setUniqueId(UUID.randomUUID().toString());
+
+      Map<String, Operation> interfaceOperations = new HashMap<>();
+      interfaceOperations.put(interfaceOperationDataDefinition.getUniqueId(), InterfaceUIDataConverter.convertInterfaceDataToOperationData(interfaceOperationDataDefinition));
+      InterfaceDefinition interfaceDefinition = new InterfaceDefinition();
+      interfaceDefinition.setUniqueId(UUID.randomUUID().toString());
+      interfaceDefinition.setToscaResourceName(InterfaceUtils.createInterfaceToscaResourceName(origResource.getName()));
+      interfaceDefinition.setOperationsMap(interfaceOperations);
+
+      Map<String, InterfaceDefinition> interfaceMap = new HashMap<>();
+      interfaceMap.put(interfaceDefinition.getUniqueId(), interfaceDefinition);
+
+      resource.setInterfaces(interfaceMap);
+    }
+
+    return Either.left(resource);
+  }
+
+  private Either<Resource, ResponseFormat> convertToResourceObject(String resourceJson, User user) {
+    return getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE);
+  }
+
+  private InterfaceOperationDataDefinition getInterfaceOperationForResponse(String interfaceOperationId, Map<String, InterfaceDefinition> interfaces){
+    InterfaceOperationDataDefinition interfaceOperationDataDefinition = new InterfaceOperationDataDefinition();
+    if(!MapUtils.isEmpty(interfaces)){
+      List<Operation> operationData = InterfaceUtils.getOperationsFromInterface(interfaces);
+      if(CollectionUtils.isNotEmpty(operationData)){
+        Optional<Operation> matchedOp = operationData.stream().filter(a -> a.getUniqueId().equals(interfaceOperationId)).findAny();
+        if(matchedOp.isPresent()) {
+          interfaceOperationDataDefinition = InterfaceUIDataConverter.convertOperationDataToInterfaceData(matchedOp.get());
+        }
+      }
+    }
+    return interfaceOperationDataDefinition;
+  }
+
+}
+
index 56eaaea..b0f2e21 100644 (file)
@@ -2043,7 +2043,7 @@ errors:
     INTERFACE_OPERATION_TYPE_INVALID: {
       code: 400,
       message: "Error: Interface Operation type %1 is Invalid, Operation type should not contain
-                       Special character, space and  should not be greater than 200 characters ",
+                       special character, space, numbers  and  should not be greater than 200 characters ",
       messageId: "SVC4696"
     }
 #---------SVC4697-----------------------------
index 65dbe87..52b71c5 100644 (file)
@@ -22,6 +22,7 @@ import org.openecomp.sdc.be.model.ArtifactDefinition;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.Operation;
 
+import java.util.HashMap;
 import java.util.Map;
 
 public interface InterfaceOperationTestUtils {
@@ -36,6 +37,12 @@ public interface InterfaceOperationTestUtils {
         id.setOperationsMap(op);
         return id;
     }
+    default InterfaceDefinition mockInterfaceDefinitionToReturn(String resourceNamme) {
+        Map<String, Operation> operationMap = createMockOperationMap();
+        return createInterface("int1", "Interface 1",
+                "lifecycle", "org.openecomp.interfaces.node.lifecycle." + resourceNamme, operationMap);
+    }
+
 
 
     default Operation createInterfaceOperation(String uniqueID, String description, ArtifactDefinition artifactDefinition,
@@ -51,5 +58,37 @@ public interface InterfaceOperationTestUtils {
         return operation;
     }
 
+    
+
+    default Map<String, Operation> createMockOperationMap() {
+        Operation operation = new Operation();
+        ListDataDefinition<OperationInputDefinition> operationInputDefinitionList = new ListDataDefinition<>();
+        operationInputDefinitionList.add(createMockOperationInputDefinition("label1"));
+        operation.setInputs(operationInputDefinitionList);
+
+        operation.setDefinition(false);
+        operation.setName("CREATE");
+        operation.setUniqueId("uniqueId1");
+        Map<String, Operation> operationMap = new HashMap<>();
+        operationMap.put("op1", operation);
+        return operationMap;
+    }
 
+
+    default OperationInputDefinition createMockOperationInputDefinition(String name) {
+        OperationInputDefinition operationInputDefinition = new OperationInputDefinition();
+        operationInputDefinition.setName(name);
+        operationInputDefinition.setUniqueId("uniqueId1");
+        return operationInputDefinition;
+    }
+
+    default   Map<String, InterfaceDefinition> createMockInterfaceDefinition(String resourceName) {
+        Map<String, Operation> operationMap = createMockOperationMap();
+        Map<String, InterfaceDefinition> interfaceDefinitionMap = new HashMap<>();
+        interfaceDefinitionMap.put("int1", createInterface("int1", "Interface 1",
+                "lifecycle", "org.openecomp.interfaces.node.lifecycle." + resourceName, operationMap));
+
+        return interfaceDefinitionMap;
+    }
+    
 }
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java
new file mode 100644 (file)
index 0000000..f51d06d
--- /dev/null
@@ -0,0 +1,394 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.components.impl;
+
+import fj.data.Either;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.openecomp.sdc.ElementOperationMock;
+import org.openecomp.sdc.be.auditing.impl.AuditingManager;
+import org.openecomp.sdc.be.components.InterfaceOperationTestUtils;
+import org.openecomp.sdc.be.components.impl.generic.GenericTypeBusinessLogic;
+import org.openecomp.sdc.be.components.validation.InterfaceOperationValidation;
+import org.openecomp.sdc.be.components.validation.UserValidations;
+import org.openecomp.sdc.be.config.ConfigurationManager;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
+import org.openecomp.sdc.be.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.InputDefinition;
+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;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
+import org.openecomp.sdc.be.model.jsontitan.operations.InterfaceOperation;
+import org.openecomp.sdc.be.model.jsontitan.operations.NodeTemplateOperation;
+import org.openecomp.sdc.be.model.jsontitan.operations.NodeTypeOperation;
+import org.openecomp.sdc.be.model.jsontitan.operations.TopologyTemplateOperation;
+import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
+import org.openecomp.sdc.be.model.operations.api.IElementOperation;
+import org.openecomp.sdc.be.model.operations.api.IPropertyOperation;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.operations.impl.GraphLockOperation;
+import org.openecomp.sdc.be.user.Role;
+import org.openecomp.sdc.be.user.UserBusinessLogic;
+import org.openecomp.sdc.common.api.ConfigurationSource;
+import org.openecomp.sdc.common.api.Constants;
+import org.openecomp.sdc.common.impl.ExternalConfiguration;
+import org.openecomp.sdc.common.impl.FSConfigurationSource;
+import org.openecomp.sdc.exception.ResponseFormat;
+import org.springframework.web.context.WebApplicationContext;
+
+import javax.servlet.ServletContext;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.mockito.ArgumentMatchers.anyCollection;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyObject;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.when;
+
+public class InterfaceOperationBusinessLogicTest implements InterfaceOperationTestUtils{
+
+    public static final String RESOURCE_CATEGORY1 = "Network Layer 2-3";
+    public static final String RESOURCE_SUBCATEGORY = "Router";
+
+
+    private String resourceId = "resourceId1";
+    private String operationId = "uniqueId1";
+    Resource resourceUpdate;
+
+    public static final String RESOURCE_NAME = "My-Resource_Name with   space";
+
+    final ServletContext servletContext = Mockito.mock(ServletContext.class);
+    IElementOperation mockElementDao;
+    TitanDao mockTitanDao = Mockito.mock(TitanDao.class);
+    UserBusinessLogic mockUserAdmin = Mockito.mock(UserBusinessLogic.class);
+    ToscaOperationFacade toscaOperationFacade = Mockito.mock(ToscaOperationFacade.class);
+    NodeTypeOperation nodeTypeOperation = Mockito.mock(NodeTypeOperation.class);
+    NodeTemplateOperation nodeTemplateOperation = Mockito.mock(NodeTemplateOperation.class);
+    TopologyTemplateOperation topologyTemplateOperation = Mockito.mock(TopologyTemplateOperation.class);
+    final IPropertyOperation propertyOperation = Mockito.mock(IPropertyOperation.class);
+    final ApplicationDataTypeCache applicationDataTypeCache = Mockito.mock(ApplicationDataTypeCache.class);
+    WebAppContextWrapper webAppContextWrapper = Mockito.mock(WebAppContextWrapper.class);
+    UserValidations userValidations = Mockito.mock(UserValidations.class);
+    WebApplicationContext webAppContext = Mockito.mock(WebApplicationContext.class);
+
+    InterfaceOperation interfaceOperation = Mockito.mock(InterfaceOperation.class);
+    InterfaceOperationValidation operationValidator = Mockito.mock(InterfaceOperationValidation.class);
+
+    ResponseFormatManager responseManager = null;
+    GraphLockOperation graphLockOperation = Mockito.mock(GraphLockOperation.class);
+    User user = null;
+    Resource resourceResponse = null;
+    ComponentsUtils componentsUtils;
+    ArtifactsBusinessLogic artifactManager = new ArtifactsBusinessLogic();
+    private GenericTypeBusinessLogic genericTypeBusinessLogic = Mockito.mock(GenericTypeBusinessLogic.class);
+
+
+    @InjectMocks
+    InterfaceOperationBusinessLogic bl = new InterfaceOperationBusinessLogic();
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        Mockito.reset(propertyOperation);
+
+        ExternalConfiguration.setAppName("catalog-be");
+
+        // init Configuration
+        String appConfigDir = "src/test/resources/config/catalog-be";
+        ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), appConfigDir);
+        ConfigurationManager configurationManager = new ConfigurationManager(configurationSource);
+        componentsUtils = new ComponentsUtils(Mockito.mock(AuditingManager.class));
+
+        // Elements
+        mockElementDao = new ElementOperationMock();
+
+        // User data and management
+        user = new User();
+        user.setUserId("jh0003");
+        user.setFirstName("Jimmi");
+        user.setLastName("Hendrix");
+        user.setRole(Role.ADMIN.name());
+
+        Either<User, ActionStatus> eitherGetUser = Either.left(user);
+        when(mockUserAdmin.getUser("jh0003", false)).thenReturn(eitherGetUser);
+        when(userValidations.validateUserExists(eq(user.getUserId()), anyString(), eq(false))).thenReturn(Either.left(user));
+        when(userValidations.validateUserNotEmpty(eq(user), anyString())).thenReturn(Either.left(user));
+        // Servlet Context attributes
+        when(servletContext.getAttribute(Constants.CONFIGURATION_MANAGER_ATTR)).thenReturn(configurationManager);
+        when(servletContext.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR)).thenReturn(webAppContextWrapper);
+        when(webAppContextWrapper.getWebAppContext(servletContext)).thenReturn(webAppContext);
+        when(webAppContext.getBean(IElementOperation.class)).thenReturn(mockElementDao);
+
+        Either<Boolean, StorageOperationStatus> eitherFalse = Either.left(true);
+        when(toscaOperationFacade.validateComponentNameExists("Root", ResourceTypeEnum.VFC, ComponentTypeEnum.RESOURCE)).thenReturn(eitherFalse);
+
+        Either<Boolean, StorageOperationStatus> eitherCountExist = Either.left(true);
+        when(toscaOperationFacade.validateComponentNameExists("alreadyExists", ResourceTypeEnum.VFC, ComponentTypeEnum.RESOURCE)).thenReturn(eitherCountExist);
+
+        Either<Boolean, StorageOperationStatus> eitherCount = Either.left(false);
+        when(toscaOperationFacade.validateComponentNameExists(eq(RESOURCE_NAME), any(ResourceTypeEnum.class), eq(ComponentTypeEnum.RESOURCE))).thenReturn(eitherCount);
+
+        Either<Boolean, StorageOperationStatus> validateDerivedExists = Either.left(true);
+        when(toscaOperationFacade.validateToscaResourceNameExists("Root")).thenReturn(validateDerivedExists);
+
+        Either<Boolean, StorageOperationStatus> validateDerivedNotExists = Either.left(false);
+        when(toscaOperationFacade.validateToscaResourceNameExists("kuku")).thenReturn(validateDerivedNotExists);
+        when(graphLockOperation.lockComponent(Mockito.anyString(), eq(NodeTypeEnum.Resource))).thenReturn(StorageOperationStatus.OK);
+        when(graphLockOperation.lockComponentByName(Mockito.anyString(), eq(NodeTypeEnum.Resource))).thenReturn(StorageOperationStatus.OK);
+
+        // createResource
+        resourceResponse = createResourceObject(true);
+        Either<Resource, StorageOperationStatus> eitherCreate = Either.left(resourceResponse);
+        Either<Integer, StorageOperationStatus> eitherValidate = Either.left(null);
+        when(toscaOperationFacade.createToscaComponent(any(Resource.class))).thenReturn(eitherCreate);
+        when(toscaOperationFacade.validateCsarUuidUniqueness(Mockito.anyString())).thenReturn(eitherValidate);
+        Map<String, DataTypeDefinition> emptyDataTypes = new HashMap<String, DataTypeDefinition>();
+        when(applicationDataTypeCache.getAll()).thenReturn(Either.left(emptyDataTypes));
+
+        //InterfaceOperation
+
+        when(operationValidator.validateInterfaceOperations(anyCollection(), anyString(), anyBoolean())).thenReturn(Either.left(true));
+        when(interfaceOperation.addInterface(anyString(), anyObject())).thenReturn(Either.left(mockInterfaceDefinitionToReturn(RESOURCE_NAME)));
+        when(interfaceOperation.updateInterface(anyString(), anyObject())).thenReturn(Either.left(mockInterfaceDefinitionToReturn(RESOURCE_NAME)));
+        when(interfaceOperation.deleteInterface(anyObject(), anyObject())).thenReturn(Either.left(new HashSet<>()));
+        when(interfaceOperation.deleteInterface(any(),any())).thenReturn(Either.left(new HashSet<>()));
+        when(interfaceOperation.updateInterface(any(),any())).thenReturn(Either.left(mockInterfaceDefinitionToReturn(RESOURCE_NAME)));
+        when(mockTitanDao.commit()).thenReturn(TitanOperationStatus.OK);
+
+        // BL object
+        artifactManager.setNodeTemplateOperation(nodeTemplateOperation);
+        bl = new InterfaceOperationBusinessLogic();
+
+        bl.setUserAdmin(mockUserAdmin);
+        bl.setComponentsUtils(componentsUtils);
+        bl.setGraphLockOperation(graphLockOperation);
+        bl.setTitanGenericDao(mockTitanDao);
+        bl.setGenericTypeBusinessLogic(genericTypeBusinessLogic);
+        toscaOperationFacade.setNodeTypeOperation(nodeTypeOperation);
+        toscaOperationFacade.setTopologyTemplateOperation(topologyTemplateOperation);
+        bl.setToscaOperationFacade(toscaOperationFacade);
+        bl.setUserValidations(userValidations);
+        bl.setInterfaceOperation(interfaceOperation);
+        bl.setInterfaceOperationValidation(operationValidator);
+        Resource resourceCsar = createResourceObjectCsar(true);
+        setCanWorkOnResource(resourceCsar);
+        Either<Component, StorageOperationStatus> oldResourceRes = Either.left(resourceCsar);
+        when(toscaOperationFacade.getToscaFullElement(resourceCsar.getUniqueId())).thenReturn(oldResourceRes);
+        responseManager = ResponseFormatManager.getInstance();
+
+    }
+
+    @Test
+    public void createInterfaceOperationTest() {
+        validateUserRoles(Role.ADMIN, Role.DESIGNER);
+        when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(createMockResourceForAddInterface()));
+        resourceUpdate = setUpResourceMock();
+        Either<Resource, ResponseFormat> interfaceOperation = bl.createInterfaceOperation(resourceId, resourceUpdate, user, true);
+        Assert.assertTrue(interfaceOperation.isLeft());
+    }
+
+
+    @Test
+    public void updateInterfaceOperationTest() {
+        validateUserRoles(Role.ADMIN, Role.DESIGNER);
+        resourceUpdate = setUpResourceMock();
+        when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(createResourceForInterfaceOperation()));
+        Either<Resource, ResponseFormat> interfaceOperation = bl.updateInterfaceOperation(resourceId, resourceUpdate, user, true);
+        Assert.assertTrue(interfaceOperation.isLeft());
+    }
+
+
+    @Test
+    public void deleteInterfaceOperationTest() {
+        validateUserRoles(Role.ADMIN, Role.DESIGNER);
+        when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(createResourceForInterfaceOperation()));
+        Set<String> idsToDelete = new HashSet<>();
+        idsToDelete.add(operationId);
+
+        Either<Resource, ResponseFormat> deleteResourceResponseFormatEither = bl.deleteInterfaceOperation(resourceId, idsToDelete, user, true);
+        Assert.assertTrue(deleteResourceResponseFormatEither.isLeft());
+    }
+
+    @Test
+    public void deleteInterfaceOperationTestShouldFailWrongId() {
+        validateUserRoles(Role.ADMIN, Role.DESIGNER);
+        Set<String> idsToDelete = new HashSet<>();
+        when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(createResourceForInterfaceOperation()));
+        idsToDelete.add(resourceId);
+        Either<Resource, ResponseFormat> deleteResourceResponseFormatEither = bl.deleteInterfaceOperation(resourceId, idsToDelete, user, true);
+        Assert.assertFalse(deleteResourceResponseFormatEither.isLeft());
+    }
+
+    @Test
+    public void interfaceOperationFailedScenarioTest() {
+        validateUserRoles(Role.ADMIN, Role.DESIGNER);
+        Resource resourceWithoutInterface = new Resource();
+        resourceWithoutInterface.setUniqueId(resourceId);
+        when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resourceWithoutInterface));
+        Either<Resource, ResponseFormat> interfaceOperation = bl.updateInterfaceOperation(resourceId, resourceWithoutInterface, user, true);
+        Assert.assertTrue(interfaceOperation.isRight());
+    }
+
+    private void validateUserRoles(Role... roles) {
+        List<Role> listOfRoles = Stream.of(roles).collect(Collectors.toList());
+        when(userValidations.validateUserRole(user, listOfRoles)).thenReturn(Either.left(true));
+    }
+    private Resource createMockResourceForAddInterface () {
+        Resource resource = new Resource();
+        resource.setUniqueId(resourceId);
+        resource.setName(RESOURCE_NAME);
+        resource.addCategory(RESOURCE_CATEGORY1, RESOURCE_SUBCATEGORY);
+        resource.setDescription("My short description");
+
+        Map<String, Operation> operationMap = new HashMap<>();
+        Map<String, InterfaceDefinition> interfaceDefinitionMap = new HashMap<>();
+        interfaceDefinitionMap.put("int1", createInterface("int1", "Interface 1",
+                "lifecycle", "org.openecomp.interfaces.node.lifecycle." + RESOURCE_NAME, operationMap));
+        resource.setInterfaces(interfaceDefinitionMap);
+        List<InputDefinition> inputDefinitionList = new ArrayList<>();
+        inputDefinitionList.add(createInputDefinition("uniqueId1"));
+        resource.setInputs(inputDefinitionList);
+
+        return  resource;
+    }
+
+    private Resource setCanWorkOnResource(Resource resource) {
+        resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+        resource.setLastUpdaterUserId(user.getUserId());
+        return resource;
+    }
+
+    private Resource setUpResourceMock(){
+        Resource resource = new Resource();
+        resource.setUniqueId(resourceId);
+        resource.setName(RESOURCE_NAME);
+        resource.addCategory(RESOURCE_CATEGORY1, RESOURCE_SUBCATEGORY);
+        resource.setDescription("My short description");
+        resource.setInterfaces(createMockInterfaceDefinition(RESOURCE_NAME));
+
+        List<InputDefinition> inputDefinitionList = new ArrayList<>();
+        inputDefinitionList.add(createInputDefinition("uniqueId1"));
+        resource.setInputs(inputDefinitionList);
+
+        return  resource;
+    }
+
+    private InputDefinition createInputDefinition(String inputId) {
+        InputDefinition inputDefinition = new InputDefinition();
+        inputDefinition.setInputId(inputId);
+        inputDefinition.setDescription("Input Description");
+
+        return  inputDefinition;
+
+    }
+    private Resource createResourceForInterfaceOperation() {
+        Resource resource = new Resource();
+        resource.setUniqueId(resourceId);
+        resource.setName(RESOURCE_NAME);
+        resource.addCategory(RESOURCE_CATEGORY1, RESOURCE_SUBCATEGORY);
+        resource.setDescription("Resource name for response");
+        resource.setInterfaces(createMockInterfaceDefinition(RESOURCE_NAME));
+        return resource;
+    }
+
+    private Resource createResourceObjectCsar(boolean afterCreate) {
+        Resource resource = new Resource();
+        resource.setName(RESOURCE_NAME);
+        resource.addCategory(RESOURCE_CATEGORY1, RESOURCE_SUBCATEGORY);
+        resource.setDescription("My short description");
+        List<String> tgs = new ArrayList<String>();
+        tgs.add("test");
+        tgs.add(resource.getName());
+        resource.setTags(tgs);
+        List<String> template = new ArrayList<String>();
+        template.add("Root");
+        resource.setDerivedFrom(template);
+        resource.setVendorName("Motorola");
+        resource.setVendorRelease("1.0.0");
+        resource.setResourceVendorModelNumber("");
+        resource.setContactId("ya5467");
+        resource.setIcon("MyIcon");
+        resource.setCsarUUID("valid_vf.csar");
+        resource.setCsarVersion("1");
+
+        if (afterCreate) {
+            resource.setName(resource.getName());
+            resource.setVersion("0.1");
+
+            resource.setUniqueId(resource.getName().toLowerCase() + ":" + resource.getVersion());
+            resource.setCreatorUserId(user.getUserId());
+            resource.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
+            resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+        }
+        return resource;
+    }
+
+    private Resource createResourceObject(boolean afterCreate) {
+        Resource resource = new Resource();
+        resource.setName(RESOURCE_NAME);
+        resource.addCategory(RESOURCE_CATEGORY1, RESOURCE_SUBCATEGORY);
+        resource.setDescription("My short description");
+        List<String> tgs = new ArrayList<String>();
+        tgs.add("test");
+        tgs.add(resource.getName());
+        resource.setTags(tgs);
+        List<String> template = new ArrayList<String>();
+        template.add("Root");
+        resource.setDerivedFrom(template);
+        resource.setVendorName("Motorola");
+        resource.setVendorRelease("1.0.0");
+        resource.setContactId("ya5467");
+        resource.setIcon("MyIcon");
+
+        if (afterCreate) {
+            resource.setName(resource.getName());
+            resource.setVersion("0.1");
+            resource.setUniqueId(resource.getName().toLowerCase() + ":" + resource.getVersion());
+            resource.setCreatorUserId(user.getUserId());
+            resource.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
+            resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+        }
+        return resource;
+    }
+
+
+
+}
\ No newline at end of file
index 8054baf..75aa10a 100644 (file)
@@ -29,8 +29,8 @@ import org.mockito.InjectMocks;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.openecomp.sdc.ElementOperationMock;
-import org.openecomp.sdc.be.auditing.impl.AuditingLogFormatUtil;
 import org.openecomp.sdc.be.auditing.impl.AuditingManager;
+import org.openecomp.sdc.be.components.InterfaceOperationTestUtils;
 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum;
 import org.openecomp.sdc.be.components.impl.generic.GenericTypeBusinessLogic;
 import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
@@ -39,6 +39,9 @@ import org.openecomp.sdc.be.components.validation.UserValidations;
 import org.openecomp.sdc.be.config.ConfigurationManager;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
@@ -48,18 +51,22 @@ import org.openecomp.sdc.be.model.ArtifactDefinition;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.be.model.InputDefinition;
+import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
 import org.openecomp.sdc.be.model.LifecycleStateEnum;
+import org.openecomp.sdc.be.model.Operation;
 import org.openecomp.sdc.be.model.PropertyDefinition;
 import org.openecomp.sdc.be.model.Resource;
 import org.openecomp.sdc.be.model.User;
 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
+import org.openecomp.sdc.be.model.jsontitan.operations.InterfaceOperation;
 import org.openecomp.sdc.be.model.jsontitan.operations.NodeTemplateOperation;
 import org.openecomp.sdc.be.model.jsontitan.operations.NodeTypeOperation;
 import org.openecomp.sdc.be.model.jsontitan.operations.TopologyTemplateOperation;
 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
 import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation;
 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
+import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
 import org.openecomp.sdc.be.model.operations.api.IPropertyOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.CacheMangerOperation;
@@ -98,11 +105,14 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyCollection;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyObject;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.when;
 
-public class ResourceBusinessLogicTest {
+public class ResourceBusinessLogicTest implements InterfaceOperationTestUtils{
 
     private static final Logger log = LoggerFactory.getLogger(ResourceBusinessLogicTest.class);
     public static final String RESOURCE_CATEGORY = "Network Layer 2-3/Router";
@@ -112,6 +122,10 @@ public class ResourceBusinessLogicTest {
     public static final String UPDATED_CATEGORY = "Network Layer 2-3/Gateway";
     public static final String UPDATED_SUBCATEGORY = "Gateway";
 
+    private String resourceId = "resourceId1";
+    private String operationId = "uniqueId1";
+    Resource resourceUpdate;
+
     public static final String RESOURCE_NAME = "My-Resource_Name with   space";
     private static final String GENERIC_VF_NAME = "org.openecomp.resource.abstract.nodes.VF";
     private static final String GENERIC_CR_NAME = "org.openecomp.resource.abstract.nodes.CR";
@@ -133,7 +147,9 @@ public class ResourceBusinessLogicTest {
     WebAppContextWrapper webAppContextWrapper = Mockito.mock(WebAppContextWrapper.class);
     UserValidations userValidations = Mockito.mock(UserValidations.class);
     WebApplicationContext webAppContext = Mockito.mock(WebApplicationContext.class);
-    AuditingLogFormatUtil auditingLogFormatter = Mockito.mock(AuditingLogFormatUtil.class);
+    IInterfaceLifecycleOperation interfaceTypeOperation = Mockito.mock(IInterfaceLifecycleOperation.class);
+    InterfaceOperation interfaceOperation = Mockito.mock(InterfaceOperation.class);
+
     @InjectMocks
     ResourceBusinessLogic bl = new ResourceBusinessLogic();
     ResponseFormatManager responseManager = null;
@@ -201,7 +217,7 @@ public class ResourceBusinessLogicTest {
         /*when(toscaOperationFacade.validateComponentNameExists(RESOURCE_NAME, ResourceTypeEnum.VF, ComponentTypeEnum.RESOURCE)).thenReturn(eitherCount);
         when(toscaOperationFacade.validateComponentNameExists(RESOURCE_NAME, ResourceTypeEnum.PNF, ComponentTypeEnum.RESOURCE)).thenReturn(eitherCount);
         when(toscaOperationFacade.validateComponentNameExists(RESOURCE_NAME, ResourceTypeEnum.CR, ComponentTypeEnum.RESOURCE)).thenReturn(eitherCount);*/
-
+        when(interfaceOperation.updateInterface(anyString(), anyObject())).thenReturn(Either.left(mockInterfaceDefinitionToReturn(RESOURCE_NAME)));
         Either<Boolean, StorageOperationStatus> validateDerivedExists = Either.left(true);
         when(toscaOperationFacade.validateToscaResourceNameExists("Root")).thenReturn(validateDerivedExists);
 
@@ -218,6 +234,7 @@ public class ResourceBusinessLogicTest {
         when(toscaOperationFacade.validateCsarUuidUniqueness(Mockito.anyString())).thenReturn(eitherValidate);
         Map<String, DataTypeDefinition> emptyDataTypes = new HashMap<String, DataTypeDefinition>();
         when(applicationDataTypeCache.getAll()).thenReturn(Either.left(emptyDataTypes));
+        when(mockTitanDao.commit()).thenReturn(TitanOperationStatus.OK);
 
         // BL object
         artifactManager.setNodeTemplateOperation(nodeTemplateOperation);
@@ -239,6 +256,9 @@ public class ResourceBusinessLogicTest {
         toscaOperationFacade.setTopologyTemplateOperation(topologyTemplateOperation);
         bl.setToscaOperationFacade(toscaOperationFacade);
         bl.setUserValidations(userValidations);
+        bl.setInterfaceTypeOperation(interfaceTypeOperation);
+        bl.setInterfaceOperation(interfaceOperation);
+
         Resource resourceCsar = createResourceObjectCsar(true);
         setCanWorkOnResource(resourceCsar);
         Either<Component, StorageOperationStatus> oldResourceRes = Either.left(resourceCsar);
@@ -334,7 +354,8 @@ public class ResourceBusinessLogicTest {
         when(toscaOperationFacade.getLatestComponentByCsarOrName(ComponentTypeEnum.RESOURCE, resource.getCsarUUID(), resource.getSystemName())).thenReturn(resourceLinkedToCsarRes);
         Either<Boolean, StorageOperationStatus> validateDerivedExists = Either.left(true);
         when(toscaOperationFacade.validateToscaResourceNameExists("Root")).thenReturn(validateDerivedExists);
-
+        Either<Component, StorageOperationStatus> eitherUpdate = Either.left(setCanWorkOnResource(resource));
+        when(toscaOperationFacade.getToscaElement(resource.getUniqueId())).thenReturn(eitherUpdate);
         Either<Resource, StorageOperationStatus> dataModelResponse = Either.left(resource);
         when(toscaOperationFacade.updateToscaElement(resource)).thenReturn(dataModelResponse);
         Either<Resource, ResponseFormat> updateResponse = bl.validateAndUpdateResourceFromCsar(resource, user, null, null, resource.getUniqueId());
@@ -868,6 +889,7 @@ public class ResourceBusinessLogicTest {
     @Test
     public void testResourceNameWrongFormat_UPDATE() {
         Resource resource = createResourceObject(true);
+        resource.setInterfaces(createMockInterfaceDefinition(RESOURCE_NAME));
         Resource updatedResource = createResourceObject(true);
 
         // this is in order to prevent failing with 403 earlier
@@ -889,6 +911,7 @@ public class ResourceBusinessLogicTest {
     @Test
     public void testResourceNameAfterCertify_UPDATE() {
         Resource resource = createResourceObject(true);
+        resource.setInterfaces(createMockInterfaceDefinition(RESOURCE_NAME));
         Resource updatedResource = createResourceObject(true);
 
         // this is in order to prevent failing with 403 earlier
@@ -932,6 +955,8 @@ public class ResourceBusinessLogicTest {
     @Test
     public void testResourceNameAlreadyExist_UPDATE() {
         Resource resource = createResourceObject(true);
+        resource.setInterfaces(createMockInterfaceDefinition(RESOURCE_NAME));
+
         Resource updatedResource = createResourceObject(true);
 
         // this is in order to prevent failing with 403 earlier
@@ -1815,6 +1840,4 @@ public class ResourceBusinessLogicTest {
         List<Role> listOfRoles = Stream.of(roles).collect(Collectors.toList());
         when(userValidations.validateUserRole(user, listOfRoles)).thenReturn(Either.left(true));
     }
-
-
 }
index c05dbda..792521c 100644 (file)
@@ -192,22 +192,6 @@ public class InterfaceOperationValidationTest implements InterfaceOperationTestU
         return interfaceDefinitionMap;
     }
 
-    private Map<String, Operation> createMockOperationMap() {
-        Operation operation = new Operation();
-        operation.setDefinition(false);
-        operation.setName("CREATE");
-        Map<String, Operation> operationMap = new HashMap<>();
-        operationMap.put("op1", operation);
-        return operationMap;
-    }
-
-
-    private OperationInputDefinition createMockOperationInputDefinition(String label) {
-        OperationInputDefinition operationInputDefinition = new OperationInputDefinition();
-        operationInputDefinition.setLabel(label);
-        return operationInputDefinition;
-    }
-
     private class InterfaceOperationValidationUtilTest extends InterfaceOperationValidation {
 
         protected ResponseFormatManager getResponseFormatManager() {
index 6b5f115..bb36595 100644 (file)
@@ -55,6 +55,7 @@ public class TopologyTemplate extends ToscaElement{
        
        private Map<String, MapArtifactDataDefinition> instDeploymentArtifacts;
        private Map<String, MapArtifactDataDefinition> instanceArtifacts;
+       private Map<String, InterfaceDataDefinition> interfaces;
 
        //Component Instances External References (instanceId -> ExternalRefsMap)
        //-----------------------------------------------------------------------
@@ -67,6 +68,13 @@ public class TopologyTemplate extends ToscaElement{
        }
        //-----------------------------------------------------------------------
 
+       public Map<String, InterfaceDataDefinition> getInterfaces() {
+               return interfaces;
+       }
+
+       public void setInterfaces(Map<String, InterfaceDataDefinition> interfaces) {
+               this.interfaces = interfaces;
+       }
 
        public Map<String, PropertyDataDefinition> getInputs() {
                return inputs;
index 9ad3053..355a6e2 100644 (file)
@@ -30,7 +30,21 @@ import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
-import org.openecomp.sdc.be.datatypes.elements.*;
+import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.MapCapabiltyProperty;
+import org.openecomp.sdc.be.datatypes.elements.MapGroupsDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.MapListCapabiltyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.MapListRequirementDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PolicyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
@@ -175,6 +189,13 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
                        result = Either.right(associateCapProperties);
                        return result;
                }
+
+               StorageOperationStatus associateInterfaces = associateInterfacesToResource(topologyTemplateVertex, topologyTemplate);
+               if (associateInterfaces != StorageOperationStatus.OK) {
+                       result = Either.right(associateInterfaces);
+                       return result;
+               }
+
                StorageOperationStatus associatePathProperties = associateForwardingPathToResource(topologyTemplateVertex, topologyTemplate);
                if (associateCapProperties != StorageOperationStatus.OK) {
                        result = Either.right(associatePathProperties);
@@ -665,9 +686,51 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
 
                        }
                }
+               if (!componentParametersView.isIgnoreInterfaces()) {
+                       TitanOperationStatus storageStatus = setInterfcesFromGraph(componentV, toscaElement);
+                       if (storageStatus != TitanOperationStatus.OK) {
+                               return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(storageStatus));
+                       }
+               }
+
                return Either.left(toscaElement);
        }
 
+       private TitanOperationStatus setInterfcesFromGraph(GraphVertex componentV,
+                                                                                                          TopologyTemplate topologyTemplate) {
+               Either<Map<String, InterfaceDataDefinition>, TitanOperationStatus> result = getDataFromGraph
+                               (componentV,
+                                               EdgeLabelEnum.INTERFACE_ARTIFACTS);
+               if (result.isLeft()) {
+                       topologyTemplate.setInterfaces(result.left().value());
+               } else {
+                       if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                               return result.right().value();
+                       }
+               }
+               return TitanOperationStatus.OK;
+       }
+
+       private StorageOperationStatus associateInterfacesToResource(GraphVertex topologyTemplateVertex,
+                                                                                                                                TopologyTemplate topologyTemplate) {
+               Map<String, InterfaceDataDefinition> interfaces = topologyTemplate.getInterfaces();
+               return associateInterfacesToComponent(topologyTemplateVertex,interfaces);
+       }
+
+       public StorageOperationStatus associateInterfacesToComponent(GraphVertex nodeTypeVertex,
+                                                                                                                                Map<String, InterfaceDataDefinition>
+                                                                                                                                                interfaceMap) {
+               if (interfaceMap != null && !interfaceMap.isEmpty()) {
+                       Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData
+                                       (nodeTypeVertex, VertexTypeEnum.INTERFACE_ARTIFACTS, EdgeLabelEnum.INTERFACE_ARTIFACTS, interfaceMap);
+                       if (assosiateElementToData.isRight()) {
+                               return assosiateElementToData.right().value();
+                       }
+               }
+               return StorageOperationStatus.OK;
+       }
+
+
        private TitanOperationStatus setPoliciesFromGraph(GraphVertex componentV, TopologyTemplate toscaElement) {
                Either<Map<String, PolicyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.POLICIES);
                if (result.isLeft()) {
index 71f0b77..023d3fe 100644 (file)
@@ -222,6 +222,7 @@ public class ModelConverter {
                                resource.setCsarUUID((String) topologyTemplate.getMetadataValue(JsonPresentationFields.CSAR_UUID));
                                resource.setCsarVersion((String) topologyTemplate.getMetadataValue(JsonPresentationFields.CSAR_VERSION));
                                resource.setImportedToscaChecksum((String) topologyTemplate.getMetadataValue(JsonPresentationFields.IMPORTED_TOSCA_CHECKSUM));
+                               convertInterfaces(topologyTemplate, resource);
 
                        }
                        convertComponentInstances(topologyTemplate, resource);
@@ -236,6 +237,17 @@ public class ModelConverter {
                return resource;
        }
 
+       private static void convertInterfaces(TopologyTemplate toscaElement, Resource resource) {
+               Map<String, InterfaceDataDefinition> interfaces = toscaElement.getInterfaces();
+               Map<String, InterfaceDefinition> copy;
+               if (interfaces != null) {
+                       copy = interfaces.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new InterfaceDefinition(e.getValue())));
+               } else {
+                       copy = new HashMap<>();
+               }
+               resource.setInterfaces(copy);
+       }
+
        private static void convertAttributes(NodeType nodeType, Resource resource) {
                Map<String, PropertyDataDefinition> attributes = nodeType.getAttributes();
                if (attributes != null) {
@@ -897,6 +909,7 @@ public class ModelConverter {
                        topologyTemplate.setMetadataValue(JsonPresentationFields.CSAR_UUID, resource.getCsarUUID());
                        topologyTemplate.setMetadataValue(JsonPresentationFields.CSAR_VERSION, resource.getCsarVersion());
                        topologyTemplate.setMetadataValue(JsonPresentationFields.IMPORTED_TOSCA_CHECKSUM, resource.getImportedToscaChecksum());
+                       convertInterfaces(resource, topologyTemplate);
                }
                if (componentType == ComponentTypeEnum.SERVICE) {
                        convertServiceSpecificEntities((Service) component, topologyTemplate);
@@ -917,6 +930,15 @@ public class ModelConverter {
                return topologyTemplate;
        }
 
+       private static void convertInterfaces(Resource resource, TopologyTemplate topologyTemplate) {
+               Map<String, InterfaceDefinition> interfaces = resource.getInterfaces();
+               if (interfaces != null && !interfaces.isEmpty()) {
+                       Map<String, InterfaceDataDefinition> copy = interfaces.entrySet().stream()
+                                       .collect(Collectors.toMap(Map.Entry::getKey, e -> new InterfaceDataDefinition(e.getValue())));
+                       topologyTemplate.setInterfaces(copy);
+               }
+       }
+
        private static void convertServiceSpecificEntities(Service service, TopologyTemplate topologyTemplate) {
                convertServiceMetaData(service, topologyTemplate);
                convertServiceApiArtifacts(service, topologyTemplate);
index 5eef21b..9c0d25b 100644 (file)
@@ -23,6 +23,7 @@ package org.openecomp.sdc.be.ui.model;
 import java.util.List;
 import java.util.Map;
 
+import org.openecomp.sdc.be.datatypes.elements.InterfaceOperationDataDefinition;
 import org.openecomp.sdc.be.model.AdditionalInformationDefinition;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.PropertyDefinition;
@@ -44,6 +45,7 @@ public class UiResourceDataTransfer extends UiComponentDataTransfer{
        private List<String> defaultCapabilities;
        
        private List<AdditionalInformationDefinition> additionalInformation;
+       private Map<String, InterfaceOperationDataDefinition> interfaceOperations;
        
        public UiResourceDataTransfer(){}
        
@@ -110,5 +112,11 @@ public class UiResourceDataTransfer extends UiComponentDataTransfer{
        public void setDefaultCapabilities(List<String> defaultCapabilities) {
                this.defaultCapabilities = defaultCapabilities;
        }
+       public Map<String, InterfaceOperationDataDefinition> getInterfaceOperations() {
+               return interfaceOperations;
+       }
 
+       public void setInterfaceOperations(Map<String, InterfaceOperationDataDefinition> interfaceOperations) {
+               this.interfaceOperations = interfaceOperations;
+       }
 }