Allign properties import during service import
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / InputsBusinessLogic.java
index d3cc6dc..a24bce9 100644 (file)
@@ -30,13 +30,15 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections4.ListUtils;
 import org.apache.commons.collections4.MapUtils;
-import org.apache.commons.lang.BooleanUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
+import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
@@ -91,7 +93,6 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
     private static final String UPDATE_INPUT = "UpdateInput";
     private static final Logger log = Logger.getLogger(InputsBusinessLogic.class);
     private static final String FAILED_TO_FOUND_COMPONENT_ERROR = "Failed to found component {}, error: {}";
-    private static final String GET_PROPERTIES_BY_INPUT = "get Properties by input";
     private static final String FAILED_TO_FOUND_INPUT_UNDER_COMPONENT_ERROR = "Failed to found input {} under component {}, error: {}";
     private static final String GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP = "Going to execute rollback on create group.";
     private static final String GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP = "Going to execute commit on create group.";
@@ -128,14 +129,14 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
         ComponentParametersView filters = new ComponentParametersView();
         filters.disableAll();
         filters.setIgnoreInputs(false);
-        Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade
+        Either<Component, StorageOperationStatus> getComponentEither = toscaOperationFacade
             .getToscaElement(componentId, filters);
         if (getComponentEither.isRight()) {
             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
             log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
             return Either.right(componentsUtils.getResponseFormat(actionStatus));
         }
-        org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
+        Component component = getComponentEither.left().value();
         List<InputDefinition> inputs = component.getInputs();
         return Either.left(inputs);
     }
@@ -148,14 +149,14 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
         filters.setIgnoreInputs(false);
         filters.setIgnoreComponentInstances(false);
         filters.setIgnoreComponentInstancesInputs(false);
-        Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade
+        Either<Component, StorageOperationStatus> getComponentEither = toscaOperationFacade
             .getToscaElement(componentId, filters);
         if (getComponentEither.isRight()) {
             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
             log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
             return Either.right(componentsUtils.getResponseFormat(actionStatus));
         }
-        org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
+        Component component = getComponentEither.left().value();
         if (!ComponentValidations.validateComponentInstanceExist(component, componentInstanceId)) {
             ActionStatus actionStatus = ActionStatus.COMPONENT_INSTANCE_NOT_FOUND;
             log.debug("Failed to found component instance inputs {}, error: {}", componentInstanceId, actionStatus);
@@ -183,12 +184,12 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
                                                                                                            String instanceId, String inputId) {
         validateUserExists(userId);
         String parentId = componentId;
-        org.openecomp.sdc.be.model.Component component;
+        Component component;
         ComponentParametersView filters = new ComponentParametersView();
         filters.disableAll();
         filters.setIgnoreComponentInstances(false);
         if (!instanceId.equals(inputId)) {
-            Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade
+            Either<Component, StorageOperationStatus> getComponentEither = toscaOperationFacade
                 .getToscaElement(parentId, filters);
             if (getComponentEither.isRight()) {
                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
@@ -205,7 +206,7 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
         filters.setIgnoreComponentInstancesProperties(false);
         filters.setIgnoreComponentInstancesInputs(false);
         filters.setIgnoreProperties(false);
-        Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade
+        Either<Component, StorageOperationStatus> getComponentEither = toscaOperationFacade
             .getToscaElement(parentId, filters);
         if (getComponentEither.isRight()) {
             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
@@ -264,11 +265,10 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
     }
 
     public Either<List<InputDefinition>, ResponseFormat> updateInputsValue(ComponentTypeEnum componentType, String componentId,
-                                                                           List<InputDefinition> inputs, String userId, boolean shouldLockComp,
-                                                                           boolean inTransaction) {
+                                                                           List<InputDefinition> inputs, String userId, boolean shouldLockComp) {
         List<InputDefinition> returnInputs = new ArrayList<>();
         Either<List<InputDefinition>, ResponseFormat> result = null;
-        org.openecomp.sdc.be.model.Component component = null;
+        Component component = null;
         try {
             validateUserExists(userId);
             ComponentParametersView componentParametersView = new ComponentParametersView();
@@ -289,35 +289,39 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
                 }
             }
             //Validate value and Constraint of input
-            Either<Boolean, ResponseFormat> constraintValidatorResponse = validateInputValueConstraint(inputs);
+            Either<Boolean, ResponseFormat> constraintValidatorResponse = validateInputValueConstraint(inputs, component.getModel());
             if (constraintValidatorResponse.isRight()) {
                 log.error("Failed validation value and constraint of property: {}", constraintValidatorResponse.right().value());
+                unlockComponent(true, component);
                 return Either.right(constraintValidatorResponse.right().value());
             }
             validateCanWorkOnComponent(component, userId);
             Map<String, DataTypeDefinition> dataTypes;
-            dataTypes = getAllDataTypes(applicationDataTypeCache);
+            dataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, component.getModel());
             List<InputDefinition> componentsOldInputs = Optional.ofNullable(component.getInputs()).orElse(Collections.emptyList());
             for (InputDefinition newInput : inputs) {
                 InputDefinition currInput = getInputFromInputsListById(componentsOldInputs, newInput);
                 if (currInput == null) {
                     ActionStatus actionStatus = ActionStatus.COMPONENT_NOT_FOUND;
                     log.debug("Failed to found newInput {} under component {}, error: {}", newInput.getUniqueId(), componentId, actionStatus);
-                    result = Either.right(componentsUtils.getResponseFormat(actionStatus));
-                    return result;
+                    unlockComponent(true, component);
+                    return Either.right(componentsUtils.getResponseFormat(actionStatus));
                 }
                 String updateInputObjectValue = updateInputObjectValue(currInput, newInput, dataTypes);
                 currInput.setDefaultValue(updateInputObjectValue);
                 currInput.setOwnerId(userId);
                 currInput.setMetadata(newInput.getMetadata());
+                if (newInput.getConstraints() != null) {
+                    currInput.setConstraints(newInput.getConstraints());
+                }
                 if (newInput.isRequired() != null) {
                     currInput.setRequired(newInput.isRequired());
                 }
                 Either<InputDefinition, StorageOperationStatus> status = toscaOperationFacade.updateInputOfComponent(component, currInput);
                 if (status.isRight()) {
                     ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status.right().value());
-                    result = Either.right(componentsUtils.getResponseFormat(actionStatus, ""));
-                    return result;
+                    unlockComponent(true, component);
+                    return Either.right(componentsUtils.getResponseFormat(actionStatus, ""));
                 } else {
                     returnInputs.add(status.left().value());
                 }
@@ -335,34 +339,36 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
         return result;
     }
 
-    private Either<Boolean, ResponseFormat> validateInputValueConstraint(List<InputDefinition> inputs) {
-        PropertyValueConstraintValidationUtil propertyValueConstraintValidationUtil = PropertyValueConstraintValidationUtil.getInstance();
+    private Either<Boolean, ResponseFormat> validateInputValueConstraint(List<InputDefinition> inputs, final String model) {
+        PropertyValueConstraintValidationUtil propertyValueConstraintValidationUtil = new PropertyValueConstraintValidationUtil();
         List<InputDefinition> inputDefinitions = new ArrayList<>();
         for (InputDefinition inputDefinition : inputs) {
             InputDefinition inputDef = new InputDefinition();
-            inputDefinition.setDefaultValue(inputDefinition.getDefaultValue());
-            inputDefinition.setInputPath(inputDefinition.getSubPropertyInputPath());
-            inputDefinition.setType(inputDefinition.getType());
+            inputDef.setName(inputDefinition.getName());
+            inputDef.setDefaultValue(inputDefinition.getDefaultValue());
+            inputDef.setInputPath(inputDefinition.getSubPropertyInputPath());
+            inputDef.setType(inputDefinition.getType());
+            inputDef.setConstraints(inputDefinition.getConstraints());
             if (Objects.nonNull(inputDefinition.getParentPropertyType())) {
                 ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
                 propertyDefinition.setType(inputDefinition.getParentPropertyType());
-                inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
+                inputDef.setProperties(Collections.singletonList(propertyDefinition));
             }
             inputDefinitions.add(inputDef);
         }
-        return propertyValueConstraintValidationUtil.validatePropertyConstraints(inputDefinitions, applicationDataTypeCache);
+        return propertyValueConstraintValidationUtil.validatePropertyConstraints(inputDefinitions, applicationDataTypeCache, model);
     }
 
     public Either<List<ComponentInstanceInput>, ResponseFormat> getInputsForComponentInput(String userId, String componentId, String inputId) {
         validateUserExists(userId);
-        org.openecomp.sdc.be.model.Component component = null;
+        Component component = null;
         ComponentParametersView filters = new ComponentParametersView();
         filters.disableAll();
         filters.setIgnoreComponentInstances(false);
         filters.setIgnoreInputs(false);
         filters.setIgnoreComponentInstancesInputs(false);
         filters.setIgnoreProperties(false);
-        Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade
+        Either<Component, StorageOperationStatus> getComponentEither = toscaOperationFacade
             .getToscaElement(componentId, filters);
         if (getComponentEither.isRight()) {
             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
@@ -385,14 +391,20 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
         return createMultipleInputs(userId, componentId, componentTypeEnum, componentInstInputsMap, true, false);
     }
 
-    public Either<List<InputDefinition>, ResponseFormat> createMultipleInputs(String userId, String componentId, ComponentTypeEnum componentType,
-                                                                              ComponentInstInputsMap componentInstInputsMapUi, boolean shouldLockComp,
-                                                                              boolean inTransaction) {
+    private Either<List<InputDefinition>, ResponseFormat> createMultipleInputs(String userId, String componentId, ComponentTypeEnum componentType,
+                                                                               ComponentInstInputsMap componentInstInputsMapUi,
+                                                                               boolean shouldLockComp,
+                                                                               boolean inTransaction) {
         Either<List<InputDefinition>, ResponseFormat> result = null;
-        org.openecomp.sdc.be.model.Component component = null;
+        Component component = null;
         try {
             validateUserExists(userId);
             component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp);
+            ImmutablePair<StorageOperationStatus, String> status = validateInputName(component, componentInstInputsMapUi);
+            if (status.getLeft() != StorageOperationStatus.OK) {
+                log.debug("Input name already exist");
+                throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.INPUT_NAME_ALREADY_EXIST, status.getRight()));
+            }
             result = propertyDeclarationOrchestrator.declarePropertiesToInputs(component, componentInstInputsMapUi).left()
                 .bind(inputsToCreate -> prepareInputsForCreation(userId, componentId, inputsToCreate)).right()
                 .map(componentsUtils::getResponseFormat);
@@ -418,6 +430,29 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
         }
     }
 
+    private ImmutablePair<StorageOperationStatus, String> validateInputName(final Component component,
+                                                                            final ComponentInstInputsMap componentInstInputsMap) {
+        final Map<String, List<ComponentInstancePropInput>> inputDeclaredProperties = new HashMap<>();
+        if (MapUtils.isNotEmpty(componentInstInputsMap.getComponentInstanceProperties())) {
+            inputDeclaredProperties.putAll(componentInstInputsMap.getComponentInstanceProperties());
+        } else if (MapUtils.isNotEmpty(componentInstInputsMap.getServiceProperties())) {
+            inputDeclaredProperties.putAll(componentInstInputsMap.getServiceProperties());
+        }
+        if (MapUtils.isNotEmpty(inputDeclaredProperties) && CollectionUtils.isNotEmpty(component.getInputs())) {
+            for (final List<ComponentInstancePropInput> componentInstancePropInputs : inputDeclaredProperties.values()) {
+                for (final ComponentInstancePropInput componentInstancePropInput : componentInstancePropInputs) {
+                    final Optional<InputDefinition> inputDefinition = component.getInputs().stream()
+                        .filter(input -> input.getName().equals(componentInstancePropInput.getInputName())
+                            || input.getName().equals(componentInstancePropInput.getName())).findAny();
+                    if (inputDefinition.isPresent()) {
+                        return new ImmutablePair<>(StorageOperationStatus.INVALID_VALUE, inputDefinition.get().getName());
+                    }
+                }
+            }
+        }
+        return new ImmutablePair<>(StorageOperationStatus.OK, StringUtils.EMPTY);
+    }
+
     /**
      * Creates a list input with a data type which has properties specified.
      *
@@ -432,7 +467,7 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
                                                                          ComponentInstListInput componentListInput, boolean shouldLockComp,
                                                                          boolean inTransaction) {
         Either<List<InputDefinition>, ResponseFormat> result = null;
-        org.openecomp.sdc.be.model.Component component = null;
+        Component component = null;
         log.trace("#createListInput: enter");
         try {
             /* check if user exists */
@@ -514,11 +549,11 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
         return componentParametersView;
     }
 
-    private org.openecomp.sdc.be.model.Component getAndValidateComponentForCreate(
+    private Component getAndValidateComponentForCreate(
         String userId, String componentId, ComponentTypeEnum componentType, boolean shouldLockComp
     ) {
         ComponentParametersView componentParametersView = getBaseComponentParametersView();
-        org.openecomp.sdc.be.model.Component component = validateComponentExists(componentId, componentType, componentParametersView);
+        Component component = validateComponentExists(componentId, componentType, componentParametersView);
         if (shouldLockComp) {
             // lock the component
             lockComponent(component, CREATE_INPUT);
@@ -567,11 +602,11 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
     }
 
     public Either<List<InputDefinition>, ResponseFormat> createInputsInGraph(Map<String, InputDefinition> inputs,
-                                                                             org.openecomp.sdc.be.model.Component component) {
+                                                                             Component component) {
 
         List<InputDefinition> resourceProperties = component.getInputs();
 
-        Map<String, DataTypeDefinition> dataTypes = getAllDataTypes(applicationDataTypeCache);
+        final Map<String, DataTypeDefinition> dataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, component.getModel());
 
         for (Map.Entry<String, InputDefinition> inputDefinition : inputs.entrySet()) {
             String inputName = inputDefinition.getKey();
@@ -605,12 +640,11 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
 
     private Either<List<InputDefinition>, ResponseFormat> createListInputsInGraph(Map<String, InputDefinition> inputs,
                                                                                   Map<String, DataTypeDefinition> privateDataTypes,
-                                                                                  org.openecomp.sdc.be.model.Component component) {
+                                                                                  Component component) {
 
         log.trace("#createListInputsInGraph: enter");
 
-        Map<String, DataTypeDefinition> dataTypes = getAllDataTypes(
-            applicationDataTypeCache);
+        Map<String, DataTypeDefinition> dataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, component.getModel());
         dataTypes.putAll(privateDataTypes);
 
         for (Map.Entry<String, InputDefinition> inputDefinition : inputs.entrySet()) {
@@ -654,12 +688,12 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
         componentParametersView.setIgnoreInterfaces(false);
         componentParametersView.setIgnoreDataType(false);
         componentParametersView.setIgnoreProperties(false);
-        Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> componentEither = toscaOperationFacade
+        Either<Component, StorageOperationStatus> componentEither = toscaOperationFacade
             .getToscaElement(componentId, componentParametersView);
         if (componentEither.isRight()) {
             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(componentEither.right().value()));
         }
-        org.openecomp.sdc.be.model.Component component = componentEither.left().value();
+        Component component = componentEither.left().value();
         // Validate inputId is child of the component
         Optional<InputDefinition> optionalInput = component.getInputs().stream().
             // filter by ID
@@ -702,10 +736,9 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
     }
 
     private Either<InputDefinition, ResponseFormat> deleteListInput(String componentId, String inputId,
-                                                                    org.openecomp.sdc.be.model.Component component, InputDefinition inputForDelete,
+                                                                    Component component, InputDefinition inputForDelete,
                                                                     StorageOperationStatus status) {
         // the input is created by 'Declare List'.
-
         // need to 1. undeclare properties, 2. delete input, 3. delete private data type
         StorageOperationStatus storageOperationStatus = propertyDeclarationOrchestrator.unDeclarePropertiesAsListInputs(component, inputForDelete);
         if (storageOperationStatus != StorageOperationStatus.OK) {
@@ -764,14 +797,14 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
             filters.setIgnoreComponentInstancesInputs(false);
             filters.setIgnoreComponentInstancesProperties(false);
             filters.setIgnoreProperties(false);
-            Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus> getComponentEither = toscaOperationFacade
+            Either<Component, StorageOperationStatus> getComponentEither = toscaOperationFacade
                 .getToscaElement(componentId, filters);
             if (getComponentEither.isRight()) {
                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
                 log.debug(FAILED_TO_FOUND_COMPONENT_ERROR, componentId, actionStatus);
                 return Either.right(componentsUtils.getResponseFormat(actionStatus));
             }
-            org.openecomp.sdc.be.model.Component component = getComponentEither.left().value();
+            Component component = getComponentEither.left().value();
             Optional<InputDefinition> op = component.getInputs().stream().filter(in -> in.getUniqueId().equals(inputId)).findFirst();
             if (!op.isPresent()) {
                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getComponentEither.right().value());
@@ -829,7 +862,7 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
                 result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INPUT_ALREADY_EXIST, inputName));
                 return result;
             }
-            Map<String, DataTypeDefinition> allDataTypes = getAllDataTypes(applicationDataTypeCache);
+            Map<String, DataTypeDefinition> allDataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, component.getModel());
             // validate input default values
             Either<Boolean, ResponseFormat> defaultValuesValidation = validatePropertyDefaultValue(newInputDefinition, allDataTypes);
             if (defaultValuesValidation.isRight()) {