aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java416
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java97
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java116
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java4
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RepresentationUtils.java4
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceInterfaceOperationServlet.java317
-rw-r--r--catalog-be/src/main/resources/config/error-configuration.yaml2
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/components/InterfaceOperationTestUtils.java39
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java394
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java37
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java16
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/TopologyTemplate.java8
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java65
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java22
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceDataTransfer.java8
15 files changed, 1459 insertions, 86 deletions
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
index 0000000000..05e7fe0941
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java
@@ -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);
+ }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java
index 0dce2a3cd9..bbdb14f1c8 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java
@@ -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
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java
index bf3385a076..3d3cca4ed2 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java
@@ -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;
}
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java
index 0e0d20ffcb..937ec871e9 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java
@@ -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);
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RepresentationUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RepresentationUtils.java
index 127fb98c3c..ea6b34a1ea 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RepresentationUtils.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RepresentationUtils.java
@@ -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
index 0000000000..49bce3bfe6
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceInterfaceOperationServlet.java
@@ -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;
+ }
+
+}
+
diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml
index 56eaaea830..b0f2e2107f 100644
--- a/catalog-be/src/main/resources/config/error-configuration.yaml
+++ b/catalog-be/src/main/resources/config/error-configuration.yaml
@@ -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-----------------------------
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/InterfaceOperationTestUtils.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/InterfaceOperationTestUtils.java
index 65dbe87a48..52b71c5743 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/InterfaceOperationTestUtils.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/InterfaceOperationTestUtils.java
@@ -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
index 0000000000..f51d06d53a
--- /dev/null
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java
@@ -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
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java
index 8054baf15f..75aa10aa64 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java
@@ -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));
}
-
-
}
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java
index c05dbda974..792521c484 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java
@@ -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() {
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/TopologyTemplate.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/TopologyTemplate.java
index 6b5f1157fc..bb36595578 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/TopologyTemplate.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/TopologyTemplate.java
@@ -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;
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java
index 9ad3053d66..355a6e28a5 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java
@@ -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()) {
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java
index 71f0b77902..023d3fe2bd 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java
@@ -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);
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceDataTransfer.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceDataTransfer.java
index 5eef21b3a5..9c0d25b228 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceDataTransfer.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiResourceDataTransfer.java
@@ -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;
+ }
}