X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=catalog-be%2Fsrc%2Fmain%2Fjava%2Forg%2Fopenecomp%2Fsdc%2Fbe%2Fcomponents%2Fimpl%2FComponentInterfaceOperationBusinessLogic.java;h=a10bae9c1eff5f8a9e481258fc74fdebb5f3df32;hb=ceaf83e0f29c10e4521321abcd6dd17080d2db60;hp=eb8b35ec605b148df350f6933400ce419d1aa21d;hpb=fbab79aeaccf74385c9a55b697a1055a86bdf171;p=sdc.git diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInterfaceOperationBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInterfaceOperationBusinessLogic.java index eb8b35ec60..a10bae9c1e 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInterfaceOperationBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInterfaceOperationBusinessLogic.java @@ -18,28 +18,45 @@ * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ + package org.openecomp.sdc.be.components.impl; +import static org.openecomp.sdc.be.components.impl.ImportUtils.Constants.QUOTE; + +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import fj.data.Either; +import java.lang.reflect.Type; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; +import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.ListUtils; import org.apache.commons.collections.MapUtils; import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; import org.openecomp.sdc.be.components.validation.ComponentValidations; import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil; import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.ArtifactTypeDefinition; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.ComponentInstanceInterface; import org.openecomp.sdc.be.model.ComponentParametersView; import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation; @@ -49,6 +66,9 @@ import org.openecomp.sdc.be.model.operations.api.IGroupOperation; import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.tosca.utils.OperationArtifactUtil; import org.openecomp.sdc.be.user.Role; import org.openecomp.sdc.common.datastructure.Wrapper; import org.openecomp.sdc.exception.ResponseFormat; @@ -60,7 +80,13 @@ import org.springframework.beans.factory.annotation.Autowired; public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic { private static final Logger LOGGER = LoggerFactory.getLogger(ComponentInterfaceOperationBusinessLogic.class); + private static final String UPDATE_INTERFACE_OPERATION_ON_COMPONENT_INSTANCE = + "Update Interface Operation on Component instance"; + private static final String EXCEPTION_OCCURRED_WHEN_UPDATING_COMPONENT_INSTANCE_INTERFACES = + "Exception occurred when updating Component Instance Interfaces {}"; private final ComponentValidations componentValidations; + private final PropertyBusinessLogic propertyBusinessLogic; + private final ArtifactTypeBusinessLogic artifactTypeBusinessLogic; @Autowired public ComponentInterfaceOperationBusinessLogic(final IElementOperation elementDao, final IGroupOperation groupOperation, @@ -68,10 +94,14 @@ public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic final IGroupTypeOperation groupTypeOperation, final InterfaceOperation interfaceOperation, final InterfaceLifecycleOperation interfaceLifecycleTypeOperation, final ArtifactsOperations artifactToscaOperation, - final ComponentValidations componentValidations) { + final ComponentValidations componentValidations, + final PropertyBusinessLogic propertyBusinessLogic, + final ArtifactTypeBusinessLogic artifactTypeBusinessLogic) { super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation); this.componentValidations = componentValidations; + this.propertyBusinessLogic = propertyBusinessLogic; + this.artifactTypeBusinessLogic = artifactTypeBusinessLogic; } public Optional updateComponentInstanceInterfaceOperation(final String componentId, final String componentInstanceId, @@ -119,19 +149,33 @@ public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic errorWrapper.setInnerElement(responseFormat); return Optional.empty(); } + + final String model = propertyBusinessLogic.getComponentModelByComponentId(componentId); + PropertyValueConstraintValidationUtil constraintValidatorUtil = new PropertyValueConstraintValidationUtil(); + Either constraintValidatorResponse = + validateOperationInputConstraints(updatedOperationDataDefinition, constraintValidatorUtil, model); + if (!isConstraintsValidationSucceed(constraintValidatorResponse, errorWrapper, updatedOperationDataDefinition)) { + return Optional.empty(); + } + constraintValidatorResponse = validateOperationArtifactPropertyConstraints( + updatedOperationDataDefinition, constraintValidatorUtil, model); + if (!isConstraintsValidationSucceed(constraintValidatorResponse, errorWrapper, updatedOperationDataDefinition)) { + return Optional.empty(); + } + updateOperationDefinitionImplementation(updatedOperationDataDefinition); optionalComponentInstanceInterface.get().getOperations().replace(updatedOperationDataDefinition.getName(), updatedOperationDataDefinition); boolean wasLocked = false; try { if (shouldLock) { - lockComponent(componentId, component, "Update Interface Operation on Component instance"); + lockComponent(componentId, component, UPDATE_INTERFACE_OPERATION_ON_COMPONENT_INSTANCE); wasLocked = true; } final StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(component, componentInstanceId); if (status != StorageOperationStatus.OK) { janusGraphDao.rollback(); responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); - LOGGER.error("Exception occurred when updating Component Instance Interfaces {}", responseFormat); + LOGGER.error(EXCEPTION_OCCURRED_WHEN_UPDATING_COMPONENT_INSTANCE_INTERFACES, responseFormat); errorWrapper.setInnerElement(responseFormat); return Optional.empty(); } @@ -165,6 +209,34 @@ public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic return componentInstanceOptional; } + private Either validateOperationInputConstraints( + OperationDataDefinition operationDataDefinition, PropertyValueConstraintValidationUtil constraintValidatorUtil, String model) { + return constraintValidatorUtil + .validatePropertyConstraints(convertOperationInputsToPropertyDefinitions(operationDataDefinition), applicationDataTypeCache, + model); + } + + private Either validateOperationArtifactPropertyConstraints( + OperationDataDefinition operationDataDefinition, PropertyValueConstraintValidationUtil constraintValidatorUtil, String model) { + return constraintValidatorUtil + .validatePropertyConstraints(convertOperationArtifactPropsToPropertyDefinitions(operationDataDefinition, model), applicationDataTypeCache, + model); + } + + private boolean isConstraintsValidationSucceed(Either constraintValidatorResponse, + Wrapper errorWrapper, + OperationDataDefinition updatedOperationDataDefinition) { + if (constraintValidatorResponse.isRight()) { + ResponseFormat responseFormat = constraintValidatorResponse.right().value(); + LOGGER.error("Failed constraints validation on inputs for interface operation: {} - {}", + updatedOperationDataDefinition.getName(), + constraintValidatorResponse.right().value()); + errorWrapper.setInnerElement(responseFormat); + return false; + } + return true; + } + public Optional updateResourceInterfaceOperation(final String componentId, final String user, final InterfaceDefinition interfaceDefinition, @@ -209,14 +281,14 @@ public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic boolean wasLocked = false; try { if (shouldLock) { - lockComponent(componentId, component, "Update Interface Operation on Component instance"); + lockComponent(componentId, component, UPDATE_INTERFACE_OPERATION_ON_COMPONENT_INSTANCE); wasLocked = true; } final StorageOperationStatus status = toscaOperationFacade.updateComponentInterfaces(component, interfaceDefinitionType); if (status != StorageOperationStatus.OK) { janusGraphDao.rollback(); responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); - LOGGER.error("Exception occurred when updating Component Instance Interfaces {}", responseFormat); + LOGGER.error(EXCEPTION_OCCURRED_WHEN_UPDATING_COMPONENT_INSTANCE_INTERFACES, responseFormat); errorWrapper.setInnerElement(responseFormat); return Optional.empty(); } @@ -235,6 +307,84 @@ public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic return Optional.of(component); } + public Optional createComponentInstanceInterfaceOperation(String componentId, String componentInstanceId, + InterfaceDefinition interfaceDefinition, + ComponentTypeEnum componentTypeEnum, + Wrapper errorWrapper, final boolean shouldLock) + throws BusinessLogicException { + ResponseFormat responseFormat; + final Component component = getComponent(componentId); + final Optional componentInstanceOptional = componentValidations.getComponentInstance(component, componentInstanceId); + if (componentInstanceOptional.isEmpty()) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND); + LOGGER.debug("Failed to find component instance with id {}, error: {}", componentInstanceId, responseFormat); + errorWrapper.setInnerElement(responseFormat); + return Optional.empty(); + } + Map> componentInstancesInterfaceMap = component.getComponentInstancesInterfaces(); + if (MapUtils.isEmpty(componentInstancesInterfaceMap)) { + componentInstancesInterfaceMap = new HashMap<>(); + component.setComponentInstancesInterfaces(componentInstancesInterfaceMap); + } + final String interfaceKey = interfaceDefinition.getType(); + interfaceDefinition.setUniqueId(interfaceKey); + interfaceDefinition.setToscaResourceName(interfaceKey); + interfaceDefinition.setUserCreated(true); + + final Optional optionalOperationDataDefinition = interfaceDefinition.getOperations().values().stream().findFirst(); + if (optionalOperationDataDefinition.isEmpty()) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, interfaceKey); + LOGGER.debug("Failed to find interface operation on interface being added {}, error: {}", interfaceKey, responseFormat); + errorWrapper.setInnerElement(responseFormat); + return Optional.empty(); + } + + final OperationDataDefinition updatedOperationDataDefinition = optionalOperationDataDefinition.get(); + updatedOperationDataDefinition.setUniqueId(UUID.randomUUID().toString()); + updatedOperationDataDefinition.getImplementation() + .setArtifactName(generateArtifactName(updatedOperationDataDefinition.getImplementation().getArtifactName())); + + List componentInstanceInterfaceList = componentInstancesInterfaceMap.get(componentInstanceId); + componentInstanceInterfaceList = CollectionUtils.isEmpty(componentInstanceInterfaceList) ? new ArrayList<>() : componentInstanceInterfaceList; + Optional componentInstanceInterface = + componentInstanceInterfaceList.stream().filter(instInterface -> instInterface.getInterfaceId().equals(interfaceKey)).findFirst(); + + if (componentInstanceInterface.isEmpty()) { + componentInstanceInterfaceList.add(new ComponentInstanceInterface(interfaceKey, interfaceDefinition)); + componentInstanceOptional.get().addInterface(interfaceKey, interfaceDefinition); + } else { + componentInstanceInterface.get().getOperations().put(updatedOperationDataDefinition.getName(), updatedOperationDataDefinition); + } + + boolean wasLocked = false; + try { + if (shouldLock) { + lockComponent(componentId, component, UPDATE_INTERFACE_OPERATION_ON_COMPONENT_INSTANCE); + wasLocked = true; + } + StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(component, componentInstanceId); + if (status != StorageOperationStatus.OK) { + janusGraphDao.rollback(); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + LOGGER.error(EXCEPTION_OCCURRED_WHEN_UPDATING_COMPONENT_INSTANCE_INTERFACES, responseFormat); + errorWrapper.setInnerElement(responseFormat); + return Optional.empty(); + } + janusGraphDao.commit(); + } catch (final Exception e) { + janusGraphDao.rollback(); + LOGGER.error("Exception occurred when updating Interface Operation on Component Instance: {}", e.getMessage(), e); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + errorWrapper.setInnerElement(responseFormat); + throw new BusinessLogicException(responseFormat); + } finally { + if (wasLocked) { + unlockComponent(component.getUniqueId(), componentTypeEnum); + } + } + return componentInstanceOptional; + } + public Optional createInterfaceOperationInResource(final String componentId, final InterfaceDefinition interfaceDefinition, final ComponentTypeEnum componentTypeEnum, final Wrapper errorWrapper, final boolean shouldLock) @@ -263,6 +413,8 @@ public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic final OperationDataDefinition updatedOperationDataDefinition = optionalOperationDataDefinition.get(); updatedOperationDataDefinition.setUniqueId(UUID.randomUUID().toString()); + updatedOperationDataDefinition.getImplementation() + .setArtifactName(generateArtifactName(updatedOperationDataDefinition.getImplementation().getArtifactName())); final InterfaceDefinition interfaceDefinitionFound = componentInterfaceMap.get(componentInterfaceUpdatedKey); if (interfaceDefinitionFound != null) { @@ -287,7 +439,7 @@ public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic boolean wasLocked = false; try { if (shouldLock) { - lockComponent(componentId, component, "Update Interface Operation on Component instance"); + lockComponent(componentId, component, UPDATE_INTERFACE_OPERATION_ON_COMPONENT_INSTANCE); wasLocked = true; } final Either operationStatusEither = @@ -295,7 +447,7 @@ public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic if (operationStatusEither.isRight()) { janusGraphDao.rollback(); responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); - LOGGER.error("Exception occurred when updating Component Instance Interfaces {}", responseFormat); + LOGGER.error(EXCEPTION_OCCURRED_WHEN_UPDATING_COMPONENT_INSTANCE_INTERFACES, responseFormat); errorWrapper.setInnerElement(responseFormat); return Optional.empty(); } @@ -314,6 +466,14 @@ public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic return Optional.of(component); } + private String generateArtifactName(final String name) { + if (OperationArtifactUtil.artifactNameIsALiteralValue(name)) { + return name; + } else { + return QUOTE + name + QUOTE; + } + } + public User validateUser(final String userId) { final User user = userValidations.validateUserExists(userId); userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN)); @@ -329,4 +489,62 @@ public class ComponentInterfaceOperationBusinessLogic extends BaseBusinessLogic artifactInfo.setArtifactName(String.format("'%s'", updatedOperationDataDefinition.getImplementation().getArtifactName())); updatedOperationDataDefinition.setImplementation(artifactInfo); } + + private List convertOperationInputsToPropertyDefinitions(final OperationDataDefinition operationDataDefinition) { + List propertyDefinitions = new ArrayList<>(); + ListDataDefinition inputsDefinitionListData = operationDataDefinition.getInputs(); + if (null != inputsDefinitionListData && !inputsDefinitionListData.isEmpty()) { + List inputDefinitionList = + inputsDefinitionListData.getListToscaDataDefinition(); + for (OperationInputDefinition operationInputDefinition : inputDefinitionList) { + PropertyDefinition propertyDefinition = new PropertyDefinition(); + propertyDefinition.setValue(operationInputDefinition.getValue()); + propertyDefinition.setUniqueId(operationInputDefinition.getUniqueId()); + propertyDefinition.setType(operationInputDefinition.getType()); + propertyDefinition.setName(operationInputDefinition.getName()); + propertyDefinition.setDefaultValue(operationInputDefinition.getDefaultValue()); + propertyDefinition.setInputPath(operationInputDefinition.getInputPath()); + propertyDefinitions.add(propertyDefinition); + } + } + return propertyDefinitions; + } + + private List convertOperationArtifactPropsToPropertyDefinitions(final OperationDataDefinition operationDataDefinition, + final String model) { + List artifactPropertiesToValidateCollection = new ArrayList<>(); + final ArtifactDataDefinition artifactDataDefinition = operationDataDefinition.getImplementation(); + if (null != artifactDataDefinition) { + final String artifactType = artifactDataDefinition.getArtifactType(); + final String uniqueId = UniqueIdBuilder.buildArtifactTypeUid(model, artifactType); + ArtifactTypeDefinition retrievedArtifact = artifactTypeBusinessLogic.getArtifactTypeByUid(uniqueId); + if (retrievedArtifact != null) { + List artifactPropertiesList = artifactDataDefinition.getProperties(); + if (null != artifactPropertiesList && !artifactPropertiesList.isEmpty()) { + for (PropertyDataDefinition propertyDataDefinition : artifactPropertiesList) { + PropertyDefinition propertyDefinition = new PropertyDefinition(); + propertyDefinition.setConstraints(deserializePropertyConstraints(propertyDataDefinition.getPropertyConstraints())); + propertyDefinition.setValue(propertyDataDefinition.getValue()); + propertyDefinition.setType(propertyDataDefinition.getType()); + propertyDefinition.setName(propertyDataDefinition.getName()); + propertyDefinition.setDefaultValue(propertyDataDefinition.getDefaultValue()); + propertyDefinition.setInputPath(propertyDataDefinition.getInputPath()); + artifactPropertiesToValidateCollection.add(propertyDefinition); + } + } + } + } + return artifactPropertiesToValidateCollection; + } + + private List deserializePropertyConstraints(List constraints) { + if (CollectionUtils.isNotEmpty(constraints)) { + Type constraintType = new TypeToken() { + }.getType(); + Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyOperation.PropertyConstraintDeserialiser()).create(); + return constraints.stream().map(c -> (PropertyConstraint) gson.fromJson(c, constraintType)).collect( + Collectors.toList()); + } + return null; + } }