From 51411acd1d4b06fc9bbc40338a27dd061dba425f Mon Sep 17 00:00:00 2001 From: Toshimichi Fukuda Date: Thu, 18 Apr 2019 21:38:46 +0900 Subject: Change to enable SDC list type input Change-Id: Ic3a9c6e714a5afd22b58bf2cb066932b1ec2a5c0 Issue-ID: SDC-2046 Signed-off-by: Toshimichi Fukuda Signed-off-by: Satoshi Fujii Signed-off-by: Ayumu Ueha --- .../be/components/impl/DataTypeBusinessLogic.java | 138 +++++ .../be/components/impl/InputsBusinessLogic.java | 322 +++++++++--- .../ComponentInstanceInputPropertyDeclarator.java | 10 + .../ComponentInstancePropertyDeclarator.java | 9 + .../property/ComponentPropertyDeclarator.java | 69 ++- .../property/DefaultPropertyDeclarator.java | 77 ++- .../property/GroupPropertyDeclarator.java | 7 + .../property/PolicyPropertyDeclarator.java | 7 + .../property/PropertyDeclarationOrchestrator.java | 44 ++ .../be/components/property/PropertyDeclarator.java | 17 + ...omponentInstancePropertyToPolicyDeclarator.java | 5 + .../ComponentPropertyToPolicyDeclarator.java | 7 +- .../openecomp/sdc/be/servlets/InputsServlet.java | 219 ++++++++ .../openecomp/sdc/be/tosca/PropertyConvertor.java | 42 +- .../openecomp/sdc/be/tosca/ToscaExportHandler.java | 61 ++- .../sdc/be/tosca/model/ToscaDataType.java | 126 +++++ .../sdc/be/tosca/model/ToscaTemplate.java | 17 + .../components/impl/DataTypeBusinessLogicTest.java | 156 ++++++ .../components/impl/InputsBusinessLogicTest.java | 376 ++++++++++++- ...mponentInstanceInputPropertyDeclaratorTest.java | 83 ++- .../ComponentInstancePropertyDeclaratorTest.java | 131 ++++- .../property/ComponentPropertyDeclaratorTest.java | 175 ++++++ .../property/GroupPropertyDeclaratorTest.java | 50 ++ .../property/PolicyPropertyDeclaratorTest.java | 49 ++ .../PropertyDecelerationOrchestratorTest.java | 59 ++- .../property/PropertyDeclaratorTestBase.java | 4 + .../be/datamodel/UiComponentDataConverterTest.java | 6 +- .../sdc/be/servlets/InputsServletTest.java | 585 +++++++++++++++------ .../sdc/be/tosca/ToscaExportHandlerTest.java | 28 +- .../sdc/be/tosca/model/ToscaDataTypeTest.java | 60 +++ .../sdc/be/tosca/model/ToscaTemplateTest.java | 21 +- 31 files changed, 2658 insertions(+), 302 deletions(-) create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaDataType.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/DataTypeBusinessLogicTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/property/ComponentPropertyDeclaratorTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaDataTypeTest.java (limited to 'catalog-be') diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeBusinessLogic.java new file mode 100644 index 0000000000..e020876b3b --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeBusinessLogic.java @@ -0,0 +1,138 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 Fujitsu Limited. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.components.impl; + +import fj.data.Either; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@org.springframework.stereotype.Component("dataTypeBusinessLogic") +public class DataTypeBusinessLogic extends BaseBusinessLogic { + + /** + * Get a list of data types that the Component has. + * + * @param componentId Unique ID of the Component + * @return list of data types + */ + public Either, StorageOperationStatus> getPrivateDataTypes(String componentId) { + ComponentParametersView filter = new ComponentParametersView(); + filter.disableAll(); + filter.setIgnoreDataType(false); + + // Get Component object + Either componentResult = + toscaOperationFacade.getToscaElement(componentId, filter); + if (componentResult.isRight()) { + return Either.right(componentResult.right().value()); + } + Component component = componentResult.left().value(); + + List dataTypesToReturn = component.getDataTypes(); + if (dataTypesToReturn == null) { + // this means there is no DATA_TYPES graph vertex. + // in this case, returns empty list. + dataTypesToReturn = new ArrayList<>(); + } + + return Either.left(dataTypesToReturn); + } + + /** + * Get a data type in a Component + * + * @param componentId Unique ID of the Component + * @param dataTypeName Data type name + * @return found data type + */ + public Either getPrivateDataType(String componentId, String dataTypeName) { + Either, StorageOperationStatus> dataTypesResult = this.getPrivateDataTypes(componentId); + if (dataTypesResult.isRight()) { + return Either.right(dataTypesResult.right().value()); + } + List dataTypes = dataTypesResult.left().value(); + Optional findResult = dataTypes.stream().filter(e -> e.getName().equals(dataTypeName)).findAny(); + if (!findResult.isPresent()) { + return Either.right(StorageOperationStatus.NOT_FOUND); + } + return Either.left(findResult.get()); + } + + /** + * Delete a data type from the Component. + * + * @param componentId Unique ID of the Component + * @param dataTypeName Data type name to be deleted + * @return deleted data type + */ + public Either deletePrivateDataType(String componentId, String dataTypeName) { + ComponentParametersView filter = new ComponentParametersView(); + filter.disableAll(); + filter.setIgnoreDataType(false); + + // Get Component object + Either componentResult = + toscaOperationFacade.getToscaElement(componentId, filter); + if (componentResult.isRight()) { + // not exists + return Either.right(componentResult.right().value()); + } + + return deletePrivateDataType(componentResult.left().value(), dataTypeName); + } + + /** + * Delete a data type from the Component. + * + * @param component Component object which has data types. + * needs to be fetched with componentParametersView.setIgnoreDataType(false) + * @param dataTypeName Data type name to be deleted + * @return deleted data type + */ + public Either deletePrivateDataType(Component component, String dataTypeName) { + // check the specified data type exists + List dataTypes = component.getDataTypes(); + if (CollectionUtils.isEmpty(dataTypes)) { + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Optional dataTypeResult = + dataTypes.stream().filter(e -> e.getName().equals(dataTypeName)).findFirst(); + if (!dataTypeResult.isPresent()) { + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + // delete it + StorageOperationStatus deleteResult = toscaOperationFacade.deleteDataTypeOfComponent(component, dataTypeName); + if (deleteResult != StorageOperationStatus.OK) { + return Either.right(deleteResult); + } + + // return deleted data type if ok + return Either.left(dataTypeResult.get()); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java index 214b5df4e1..a98694626f 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java @@ -22,7 +22,9 @@ package org.openecomp.sdc.be.components.impl; import fj.data.Either; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -31,6 +33,10 @@ import java.util.stream.Collectors; import javax.inject.Inject; 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.openecomp.sdc.be.components.impl.exceptions.ComponentException; import org.openecomp.sdc.be.components.property.PropertyDeclarationOrchestrator; import org.openecomp.sdc.be.components.validation.ComponentValidations; import org.openecomp.sdc.be.dao.api.ActionStatus; @@ -42,14 +48,18 @@ import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; import org.openecomp.sdc.be.model.ComponentInstInputsMap; +import org.openecomp.sdc.be.model.ComponentInstListInput; import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstancePropInput; import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.ComponentParametersView; import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; import org.openecomp.sdc.common.log.wrappers.Logger; @@ -73,6 +83,9 @@ public class InputsBusinessLogic extends BaseBusinessLogic { private PropertyDeclarationOrchestrator propertyDeclarationOrchestrator; @Inject private ComponentInstanceBusinessLogic componentInstanceBusinessLogic; + @Inject + private DataTypeBusinessLogic dataTypeBusinessLogic; + /** * associate inputs to a given component with paging * @@ -280,7 +293,7 @@ public class InputsBusinessLogic extends BaseBusinessLogic { } //Validate value and Constraint of input - Either constraintValidatorResponse = validateInputValueConstraint(component, inputs); + Either constraintValidatorResponse = validateInputValueConstraint(inputs); if (constraintValidatorResponse.isRight()) { log.error("Failed validation value and constraint of property: {}", constraintValidatorResponse.right().value()); @@ -339,8 +352,7 @@ public class InputsBusinessLogic extends BaseBusinessLogic { } } - private Either validateInputValueConstraint( - org.openecomp.sdc.be.model.Component component, List inputs) { + private Either validateInputValueConstraint(List inputs) { PropertyValueConstraintValidationUtil propertyValueConstraintValidationUtil = PropertyValueConstraintValidationUtil.getInstance(); List inputDefinitions = new ArrayList<>(); @@ -408,46 +420,107 @@ public class InputsBusinessLogic extends BaseBusinessLogic { try { validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false); - ComponentParametersView componentParametersView = new ComponentParametersView(); - componentParametersView.disableAll(); - componentParametersView.setIgnoreInputs(false); - componentParametersView.setIgnoreComponentInstancesInputs(false); - componentParametersView.setIgnoreComponentInstances(false); - componentParametersView.setIgnoreComponentInstancesProperties(false); - componentParametersView.setIgnorePolicies(false); - componentParametersView.setIgnoreGroups(false); - componentParametersView.setIgnoreUsers(false); + component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp); - Either validateComponent = validateComponentExists(componentId, componentType, componentParametersView); + result = propertyDeclarationOrchestrator.declarePropertiesToInputs(component, componentInstInputsMapUi) + .left() + .bind(inputsToCreate -> prepareInputsForCreation(userId, componentId, inputsToCreate)) + .right() + .map(componentsUtils::getResponseFormat); - if (validateComponent.isRight()) { - result = Either.right(validateComponent.right().value()); - return result; - } - component = validateComponent.left().value(); + return result; - if (shouldLockComp) { - Either lockComponent = lockComponent(component, CREATE_INPUT); - if (lockComponent.isRight()) { - result = Either.right(lockComponent.right().value()); - return result; + } catch (ComponentException e) { + log.error("#createMultipleInputs: Exception thrown: ", e); + result = Either.right(e.getResponseFormat()); + return result; + } finally { + + if (!inTransaction) { + if (result == null || result.isRight()) { + log.debug(GOING_TO_EXECUTE_ROLLBACK_ON_CREATE_GROUP); + titanDao.rollback(); + } else { + log.debug(GOING_TO_EXECUTE_COMMIT_ON_CREATE_GROUP); + titanDao.commit(); } } + // unlock resource + if (shouldLockComp && component != null) { + graphLockOperation.unlockComponent(componentId, componentType.getNodeType()); + } - Either canWork = validateCanWorkOnComponent(component, userId); - if (canWork.isRight()) { - result = Either.right(canWork.right().value()); - return result; + } + } + + /** + * Creates a list input with a data type which has properties specified. + * + * @param userId User ID + * @param componentId Component ID + * @param componentType Component type + * @param componentListInput Properties to be declared and input to be created + * @param shouldLockComp true if the component should be locked + * @param inTransaction true if already in transaction + */ + public Either, ResponseFormat> createListInput(String userId, String componentId, + ComponentTypeEnum componentType, ComponentInstListInput componentListInput, boolean shouldLockComp, + boolean inTransaction) { + + Either, ResponseFormat> result = null; + org.openecomp.sdc.be.model.Component component = null; + + log.trace("#createListInput: enter"); + + try { + /* check if user exists */ + validateUserExists(userId, GET_PROPERTIES_BY_INPUT, false); + + component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp); + + InputDefinition listInput = componentListInput.getListInput(); + DataTypeDefinition dataType = + prepareDataTypeForListInput(componentListInput.getComponentInstInputsMap(), listInput); + Map dataTypesMap = new HashMap<>(); + dataTypesMap.put(dataType.getName(), dataType); + if (log.isDebugEnabled()) { + log.debug("#createListInput: dataTypesMap={}", ReflectionToStringBuilder.toString(dataTypesMap)); } - result = propertyDeclarationOrchestrator.declarePropertiesToInputs(component, componentInstInputsMapUi) - .left() - .bind(inputsToCreate -> prepareInputsForCreation(userId, componentId, inputsToCreate)) - .right() - .map(componentsUtils::getResponseFormat); + Either, StorageOperationStatus> dataTypeResult = + toscaOperationFacade.addDataTypesToComponent(dataTypesMap, componentId); + if (dataTypeResult.isRight()) { + log.debug("#createListInput: DataType creation failed."); + throw new ComponentException(componentsUtils.getResponseFormat(dataTypeResult.right().value())); + } + + // create list input + listInput.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(componentId, listInput.getName())); + listInput.setInstanceUniqueId( + propertyDeclarationOrchestrator.getPropOwnerId(componentListInput.getComponentInstInputsMap())); + listInput.setIsDeclaredListInput(true); + Map listInputMap = new HashMap<>(); + listInputMap.put(listInput.getName(), listInput); + result = createListInputsInGraph(listInputMap, dataTypesMap, component); + if (result.isRight()) { + log.debug("#createListInput: createListInputsInGraph failed."); + throw new ComponentException(result.right().value()); + } + + // update properties + result = propertyDeclarationOrchestrator + .declarePropertiesToListInput(component, componentListInput.getComponentInstInputsMap(), listInput) + .right().map(err -> componentsUtils.getResponseFormat(err)) + .left().map(Arrays::asList); + + log.trace("#createListInput: leave"); return result; + } catch (ComponentException e) { + log.error("#createListInput: Exception thrown", e); + result = Either.right(e.getResponseFormat()); + return result; } finally { if (!inTransaction) { @@ -463,8 +536,65 @@ public class InputsBusinessLogic extends BaseBusinessLogic { if (shouldLockComp && component != null) { graphLockOperation.unlockComponent(componentId, componentType.getNodeType()); } + } + } + private ComponentParametersView getBaseComponentParametersView() { + ComponentParametersView componentParametersView = new ComponentParametersView(); + componentParametersView.disableAll(); + componentParametersView.setIgnoreInputs(false); + componentParametersView.setIgnoreComponentInstances(false); + componentParametersView.setIgnoreComponentInstancesInputs(false); + componentParametersView.setIgnoreComponentInstancesProperties(false); + componentParametersView.setIgnorePolicies(false); + componentParametersView.setIgnoreGroups(false); + componentParametersView.setIgnoreUsers(false); + return componentParametersView; + } + + private org.openecomp.sdc.be.model.Component getAndValidateComponentForCreate( + String userId, String componentId, ComponentTypeEnum componentType, boolean shouldLockComp + ) { + + ComponentParametersView componentParametersView = getBaseComponentParametersView(); + + Either componentEither = + // get Component Object + validateComponentExists(componentId, componentType, componentParametersView) + .left().bind(component -> { + if (shouldLockComp) { + // lock the component + return lockComponent(component, CREATE_INPUT).left().map(result -> component); + } + return Either.left(component); + }).left().bind(component -> validateCanWorkOnComponent(component, userId).left().map(result -> component)); + if (componentEither.isRight()) { + throw new ComponentException(componentEither.right().value()); + } + return componentEither.left().value(); + } + + private DataTypeDefinition prepareDataTypeForListInput(ComponentInstInputsMap inputsMap, InputDefinition input) { + // Confirm if type is list + if (StringUtils.isEmpty(input.getType()) || !input.getType().equals(ToscaPropertyType.LIST.getType())) { + log.debug("#prepareDataTypeForListInput: Type of input is not list."); + throw new ComponentException(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_TYPE)); } + + // Confirm schema type is not empty + String desiredTypeName = input.getSchemaType(); + if (StringUtils.isEmpty(desiredTypeName)) { + log.debug("#prepareDataTypeForListInput: Schema type of list input is empty."); + throw new ComponentException(componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE)); + } + + DataTypeDefinition dataType = new DataTypeDefinition(); + List propInputs = inputsMap.resolvePropertiesToDeclare().getRight(); + dataType.setName(desiredTypeName); + dataType.setDerivedFromName(ToscaPropertyType.Root.getType()); + // Copy properties from inputsMap + dataType.setProperties(propInputs.stream().map(PropertyDefinition::new).collect(Collectors.toList())); + return dataType; } private Either, StorageOperationStatus> prepareInputsForCreation(String userId, String cmptId, List inputsToCreate) { @@ -519,6 +649,42 @@ public class InputsBusinessLogic extends BaseBusinessLogic { return Either.left(associateInputsEither.left().value()); } + private Either, ResponseFormat> createListInputsInGraph(Map inputs, + Map privateDataTypes, org.openecomp.sdc.be.model.Component component) { + + log.trace("#createListInputsInGraph: enter"); + Either, ResponseFormat> allDataTypes = getAllDataTypes( + applicationDataTypeCache); + if (allDataTypes.isRight()) { + return Either.right(allDataTypes.right().value()); + } + + Map dataTypes = allDataTypes.left().value(); + dataTypes.putAll(privateDataTypes); + + for (Map.Entry inputDefinition : inputs.entrySet()) { + String inputName = inputDefinition.getKey(); + inputDefinition.getValue().setName(inputName); + + Either preparedInputEither = + prepareAndValidateInputBeforeCreate(inputDefinition.getValue(), dataTypes); + if (preparedInputEither.isRight()) { + return Either.right(preparedInputEither.right().value()); + } + } + + Either, StorageOperationStatus> addInputsEither = toscaOperationFacade + .addInputsToComponent(inputs, component.getUniqueId()); + if (addInputsEither.isRight()) { + log.debug("#createListInputsInGraph: Failed to create inputs under component {}. Status is {}", + component.getUniqueId(), addInputsEither.right().value()); + return Either.right(componentsUtils.getResponseFormat( + componentsUtils.convertFromStorageResponse(addInputsEither.right().value()))); + } + log.trace("#createListInputsInGraph: leave"); + return Either.left(addInputsEither.left().value()); + } + /** * Delete input from service * @@ -536,21 +702,16 @@ public class InputsBusinessLogic extends BaseBusinessLogic { validateUserExists(userId, "Delete input", true); - ComponentParametersView componentParametersView = new ComponentParametersView(); - componentParametersView.disableAll(); - componentParametersView.setIgnoreInputs(false); - componentParametersView.setIgnoreComponentInstances(false); - componentParametersView.setIgnoreComponentInstancesInputs(false); - componentParametersView.setIgnoreComponentInstancesProperties(false); - componentParametersView.setIgnorePolicies(false); - componentParametersView.setIgnoreGroups(false); - componentParametersView.setIgnoreUsers(false); + ComponentParametersView componentParametersView = getBaseComponentParametersView(); componentParametersView.setIgnoreInterfaces(false); + componentParametersView.setIgnoreDataType(false); componentParametersView.setIgnoreProperties(false); - Either componentEither = toscaOperationFacade.getToscaElement(componentId, componentParametersView); + Either componentEither = + toscaOperationFacade.getToscaElement(componentId, componentParametersView); if (componentEither.isRight()) { - deleteEither = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(componentEither.right().value()))); + deleteEither = Either.right(componentsUtils.getResponseFormat( + componentsUtils.convertFromStorageResponse(componentEither.right().value()))); return deleteEither; } org.openecomp.sdc.be.model.Component component = componentEither.left().value(); @@ -562,13 +723,15 @@ public class InputsBusinessLogic extends BaseBusinessLogic { // Get the input findAny(); if (!optionalInput.isPresent()) { - return Either.right(componentsUtils.getResponseFormat(ActionStatus.INPUT_IS_NOT_CHILD_OF_COMPONENT, inputId, componentId)); + return Either.right( + componentsUtils.getResponseFormat(ActionStatus.INPUT_IS_NOT_CHILD_OF_COMPONENT, inputId, componentId)); } InputDefinition inputForDelete = optionalInput.get(); // Lock component - Either lockResultEither = lockComponent(componentId, component, "deleteInput"); + Either lockResultEither = + lockComponent(componentId, component, "deleteInput"); if (lockResultEither.isRight()) { ResponseFormat responseFormat = lockResultEither.right().value(); deleteEither = Either.right(responseFormat); @@ -577,18 +740,29 @@ public class InputsBusinessLogic extends BaseBusinessLogic { // Delete input operations try { - StorageOperationStatus status = toscaOperationFacade.deleteInputOfResource(component, inputForDelete.getName()); + StorageOperationStatus status = + toscaOperationFacade.deleteInputOfResource(component, inputForDelete.getName()); if (status != StorageOperationStatus.OK) { log.debug("Component id: {} delete input id: {} failed", componentId, inputId); - deleteEither = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status), component.getName())); + deleteEither = Either.right(componentsUtils.getResponseFormat( + componentsUtils.convertFromStorageResponse(status), component.getName())); + return deleteEither; + } + + if (BooleanUtils.isTrue(inputForDelete.getIsDeclaredListInput())){ + deleteEither = deleteListInput(componentId, inputId, component, inputForDelete, status); return deleteEither; } - StorageOperationStatus storageOperationStatus = propertyDeclarationOrchestrator.unDeclarePropertiesAsInputs(component, inputForDelete); + + StorageOperationStatus storageOperationStatus = + propertyDeclarationOrchestrator.unDeclarePropertiesAsInputs(component, inputForDelete); if (storageOperationStatus != StorageOperationStatus.OK) { log.debug("Component id: {} update properties declared as input for input id: {} failed", componentId, inputId); - deleteEither = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status), component.getName())); + deleteEither = Either.right(componentsUtils.getResponseFormat( + componentsUtils.convertFromStorageResponse(status), component.getName())); return deleteEither; } + deleteEither = Either.left(inputForDelete); return deleteEither; } finally { @@ -603,8 +777,31 @@ public class InputsBusinessLogic extends BaseBusinessLogic { } } - private Either prepareAndValidateInputBeforeCreate(InputDefinition newInputDefinition, Map dataTypes) { + private Either deleteListInput(String componentId, String inputId, + org.openecomp.sdc.be.model.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) { + log.debug("Component id: {} update properties declared as input for input id: {} failed", componentId, inputId); + return Either.right(componentsUtils.getResponseFormat( + componentsUtils.convertFromStorageResponse(status), component.getName())); + } + Either deleteResult = + dataTypeBusinessLogic.deletePrivateDataType(component, inputForDelete.getSchemaType()); + if (deleteResult.isRight()) { + log.debug("Component id: {} delete datatype name: {} failed", componentId, inputForDelete.getSchemaType()); + return Either.right(componentsUtils.getResponseFormat( + componentsUtils.convertFromStorageResponse(deleteResult.right().value()), component.getName())); + } + log.trace("deleteInput: deletePrivateDataType (OK)"); + return Either.left(inputForDelete); + } + private Either prepareAndValidateInputBeforeCreate(InputDefinition newInputDefinition, Map dataTypes) { // validate input default values Either defaultValuesValidation = validatePropertyDefaultValue(newInputDefinition, dataTypes); @@ -613,24 +810,22 @@ public class InputsBusinessLogic extends BaseBusinessLogic { } // convert property ToscaPropertyType type = getType(newInputDefinition.getType()); - if (type != null) { + if (type != null && newInputDefinition != null) { PropertyValueConverter converter = type.getConverter(); // get inner type + SchemaDefinition schema = newInputDefinition.getSchema(); String innerType = null; - if (newInputDefinition != null) { - SchemaDefinition schema = newInputDefinition.getSchema(); - if (schema != null) { - PropertyDataDefinition prop = schema.getProperty(); - if (prop != null) { - innerType = prop.getType(); - } - } - String convertedValue; - if (newInputDefinition.getDefaultValue() != null) { - convertedValue = converter.convert(newInputDefinition.getDefaultValue(), innerType, dataTypes); - newInputDefinition.setDefaultValue(convertedValue); + if (schema != null) { + PropertyDataDefinition prop = schema.getProperty(); + if (prop != null) { + innerType = prop.getType(); } } + String convertedValue; + if (newInputDefinition.getDefaultValue() != null) { + convertedValue = converter.convert(newInputDefinition.getDefaultValue(), innerType, dataTypes); + newInputDefinition.setDefaultValue(convertedValue); + } } return Either.left(newInputDefinition); } @@ -696,5 +891,4 @@ public class InputsBusinessLogic extends BaseBusinessLogic { } - } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentInstanceInputPropertyDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentInstanceInputPropertyDeclarator.java index faeca88d60..d7b366e0a8 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentInstanceInputPropertyDeclarator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentInstanceInputPropertyDeclarator.java @@ -78,6 +78,16 @@ public class ComponentInstanceInputPropertyDeclarator extends DefaultPropertyDec return toscaOperationFacade.updateComponentInstanceInputs(component, componentInstanceInputsByInputId.get(0).getComponentInstanceId(), componentInstanceInputsByInputId); } + @Override + public StorageOperationStatus unDeclarePropertiesAsListInputs(Component component, InputDefinition input) { + List componentInstanceInputsByInputId = componentInstanceBusinessLogic.getComponentInstanceInputsByInputId(component, input.getUniqueId()); + if (isEmpty(componentInstanceInputsByInputId)) { + return StorageOperationStatus.OK; + } + componentInstanceInputsByInputId.forEach(cmptInstanceInput -> prepareValueBeforeDelete(input, cmptInstanceInput, cmptInstanceInput.getPath())); + return toscaOperationFacade.updateComponentInstanceInputs(component, componentInstanceInputsByInputId.get(0).getComponentInstanceId(), componentInstanceInputsByInputId); + } + @Override InputDefinition createInputFromProperty(String componentId, ComponentInstance propertiesOwner, String inputName, ComponentInstancePropInput propInput, PropertyDataDefinition prop) { InputDefinition inputFromProperty = super.createInputFromProperty(componentId, propertiesOwner, inputName, propInput, prop); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentInstancePropertyDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentInstancePropertyDeclarator.java index c716e24440..973e5985f9 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentInstancePropertyDeclarator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentInstancePropertyDeclarator.java @@ -70,4 +70,13 @@ public class ComponentInstancePropertyDeclarator extends DefaultPropertyDeclarat return toscaOperationFacade.updateComponentInstanceProperties(component, componentInstancePropertiesDeclaredAsInput.get(0).getComponentInstanceId(), componentInstancePropertiesDeclaredAsInput); } + @Override + public StorageOperationStatus unDeclarePropertiesAsListInputs(Component component, InputDefinition input) { + List componentInstancePropertiesDeclaredAsInput = componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(component, input.getUniqueId()); + if (CollectionUtils.isEmpty(componentInstancePropertiesDeclaredAsInput)) { + return StorageOperationStatus.OK; + } + componentInstancePropertiesDeclaredAsInput.forEach(cmptInstanceProperty -> prepareValueBeforeDelete(input, cmptInstanceProperty, cmptInstanceProperty.getPath())); + return toscaOperationFacade.updateComponentInstanceProperties(component, componentInstancePropertiesDeclaredAsInput.get(0).getComponentInstanceId(), componentInstancePropertiesDeclaredAsInput); + } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentPropertyDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentPropertyDeclarator.java index d382499172..ae76dadbf0 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentPropertyDeclarator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentPropertyDeclarator.java @@ -110,6 +110,40 @@ public class ComponentPropertyDeclarator extends DefaultPropertyDeclarator> propertyToUpdateCandidate = + getDeclaredPropertiesByInputId(component, input.getUniqueId()); + + if(propertyToUpdateCandidate.isPresent()) { + List propertiesToUpdate = propertyToUpdateCandidate.get(); + if (!propertiesToUpdate.isEmpty()) { + return unDeclareInputs(component, input, propertiesToUpdate); + } + } + + return StorageOperationStatus.OK; + } + + private StorageOperationStatus unDeclareInputs(Component component, + InputDefinition input, + List propertiesToUpdate) { + for (PropertyDefinition propertyToUpdate : propertiesToUpdate) { + StorageOperationStatus storageOperationStatus = unDeclareInput(component, input, propertyToUpdate); + if (StorageOperationStatus.OK != storageOperationStatus) { + return storageOperationStatus; + } + } + return StorageOperationStatus.OK; + } + private StorageOperationStatus unDeclareInput(Component component, InputDefinition input, PropertyDefinition propertyToUpdate) { @@ -124,9 +158,34 @@ public class ComponentPropertyDeclarator extends DefaultPropertyDeclarator getDeclaredPropertyByInputId(Component component, + private Optional getDeclaredPropertyByInputId(Component component, String inputId) { + List properties = component.getProperties(); + + if (CollectionUtils.isEmpty(properties)) { + return Optional.empty(); + } + + for (PropertyDefinition propertyDefinition : properties) { + List getInputValues = propertyDefinition.getGetInputValues(); + if (CollectionUtils.isEmpty(getInputValues)) { + continue; + } + + Optional getInputCandidate = + getInputValues.stream().filter(getInput -> getInput.getInputId().equals(inputId)).findAny(); + + if (getInputCandidate.isPresent()) { + return Optional.of(propertyDefinition); + } + } + + return Optional.empty(); + } + + private Optional> getDeclaredPropertiesByInputId(Component component, String inputId) { List properties = component.getProperties(); + List propertiesToUpdate = new ArrayList<>(); if(CollectionUtils.isEmpty(properties)) { return Optional.empty(); @@ -139,14 +198,14 @@ public class ComponentPropertyDeclarator extends DefaultPropertyDeclarator getInputCandidate = - getInputValues.stream().filter(getInput -> getInput.getInputId().equals(inputId)) - .findAny(); + getInputValues.stream().filter(getInput -> getInput.getInputId().equals(inputId)) + .findAny(); if(getInputCandidate.isPresent()) { - return Optional.of(propertyDefinition); + propertiesToUpdate.add(propertyDefinition); } } - return Optional.empty(); + return Optional.of(propertiesToUpdate); } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/DefaultPropertyDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/DefaultPropertyDeclarator.java index 02b261b132..46c1c009bc 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/DefaultPropertyDeclarator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/DefaultPropertyDeclarator.java @@ -11,12 +11,14 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Arrays; import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang.StringUtils; import org.json.simple.JSONObject; import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition; @@ -45,6 +47,7 @@ public abstract class DefaultPropertyDeclarator declarePropertiesAsPolicies(component, propertyOwner, propsToDeclare)) .orElse(Either.right(onPropertiesOwnerNotFound(component.getUniqueId(), propertiesOwnerId))); + } + @Override + public Either declarePropertiesAsListInput(Component component, String propertiesOwnerId, List propsToDeclare, InputDefinition input) { + log.debug("#declarePropertiesAsListInput - declaring properties as inputs for component {} from properties owner {}", component.getUniqueId(), propertiesOwnerId); + Optional propertyOwner = resolvePropertiesOwner(component, propertiesOwnerId); + if (propertyOwner.isPresent()) { + return declarePropertiesAsListInput(component, propertyOwner.get(), propsToDeclare, input); + } else { + return Either.right(onPropertiesOwnerNotFound(component.getUniqueId(), propertiesOwnerId)); + } } public StorageOperationStatus unDeclarePropertiesAsPolicies(Component component, PolicyDefinition policy) { @@ -130,12 +143,12 @@ public abstract class DefaultPropertyDeclarator()); @@ -155,6 +168,39 @@ public abstract class DefaultPropertyDeclarator declarePropertiesAsListInput(Component component, PROPERTYOWNER propertiesOwner, List propsToDeclare, InputDefinition input) { + List declaredProperties = new ArrayList<>(); + for (ComponentInstancePropInput propInput : propsToDeclare) { + if (StringUtils.isNotEmpty(propInput.getPropertiesName()) && propInput.getInput() != null) { + // sub-property in complex type is checked on UI. currently not supported. + log.debug("skip propInput (propertiesName={}) currently not supported.", propInput.getPropertiesName()); + continue; + } + PROPERTYTYPE declaredProperty = createDeclaredProperty(propInput); + + JSONObject jsonObject = new JSONObject(); + jsonObject.put(GET_INPUT, Arrays.asList(input.getName(), GET_INPUT_INDEX, propInput.getName())); + declaredProperty.setValue(jsonObject.toJSONString()); + + GetInputValueDataDefinition getInputValueDataDefinition = new GetInputValueDataDefinition(); + getInputValueDataDefinition.setInputId(input.getUniqueId()); + getInputValueDataDefinition.setInputName(input.getName()); + List getInputValues = declaredProperty.getGetInputValues(); + if (getInputValues == null) { + getInputValues = new ArrayList<>(); + declaredProperty.setGetInputValues(getInputValues); + } + getInputValues.add(getInputValueDataDefinition); + + if (!declaredProperties.contains(declaredProperty)) { + // Add property to the list if not contain in declareProperties. + declaredProperties.add(declaredProperty); + } + } + return updatePropertiesValues(component, propertiesOwner.getUniqueId(), declaredProperties) + .left().map(x -> input); + } + private PropertiesDeclarationData createInputsAndOverridePropertiesValues(String componentId, PROPERTYOWNER propertiesOwner, List propsToDeclare) { List declaredProperties = new ArrayList<>(); List createdInputs = propsToDeclare.stream() @@ -182,6 +228,7 @@ public abstract class DefaultPropertyDeclarator()); } @@ -453,6 +499,9 @@ public abstract class DefaultPropertyDeclarator subMap = (Map)value; resetInputName(subMap, inputName); + } else if (value instanceof List && ((List) value).contains(inputName) && key.equals(GET_INPUT)) { + value = ""; + lhm1.remove(key); } else { continue; } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/GroupPropertyDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/GroupPropertyDeclarator.java index 46ca85c585..f9ef479ab0 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/GroupPropertyDeclarator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/GroupPropertyDeclarator.java @@ -89,6 +89,13 @@ public class GroupPropertyDeclarator extends DefaultPropertyDeclarator unDeclareGroupProperties(component, inputForDelete, groupProperties)) + .orElse(StorageOperationStatus.OK); + } + private StorageOperationStatus unDeclareGroupProperties(Component container, InputDefinition input, GroupProperties groupProperties) { String groupId = groupProperties.getGroupId(); List propsDeclaredAsInput = groupProperties.getProperties(); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PolicyPropertyDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PolicyPropertyDeclarator.java index f7f4a75be1..17059104ff 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PolicyPropertyDeclarator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PolicyPropertyDeclarator.java @@ -87,6 +87,13 @@ public class PolicyPropertyDeclarator extends DefaultPropertyDeclarator unDeclarePolicyProperties(component, inputForDelete, policyProperties)) + .orElse(StorageOperationStatus.OK); + } + private StorageOperationStatus unDeclarePolicyProperties(Component container, InputDefinition input, PolicyProperties policyProperties) { String policyId = policyProperties.getPolicyId(); List propsDeclaredAsInput = policyProperties.getProperties(); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyDeclarationOrchestrator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyDeclarationOrchestrator.java index 3a32559dda..a6c752d689 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyDeclarationOrchestrator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyDeclarationOrchestrator.java @@ -58,6 +58,20 @@ public class PropertyDeclarationOrchestrator { return propertyDeclarator.declarePropertiesAsPolicies(component, propsToDeclare.getLeft(), propsToDeclare.getRight()); } + /** + * + * @param component + * @param componentInstInputsMap + * @param input + * @return + */ + public Either declarePropertiesToListInput(Component component, ComponentInstInputsMap componentInstInputsMap, InputDefinition input) { + PropertyDeclarator propertyDeclarator = getPropertyDeclarator(componentInstInputsMap); + Pair> propsToDeclare = componentInstInputsMap.resolvePropertiesToDeclare(); + log.debug("#declarePropertiesToInputs: componentId={}, propOwnerId={}", component.getUniqueId(), propsToDeclare.getLeft()); + return propertyDeclarator.declarePropertiesAsListInput(component, propsToDeclare.getLeft(), propsToDeclare.getRight(), input); + } + public StorageOperationStatus unDeclarePropertiesAsInputs(Component component, InputDefinition inputToDelete) { log.debug("#unDeclarePropertiesAsInputs - removing input declaration for input {} on component {}", inputToDelete.getName(), component.getUniqueId()); for (PropertyDeclarator propertyDeclarator : propertyDeclaratorsToInput) { @@ -70,6 +84,36 @@ public class PropertyDeclarationOrchestrator { return StorageOperationStatus.OK; } + /** + * Un declare properties declared as list type input + * + * @param component + * @param inputToDelete + * @return + */ + public StorageOperationStatus unDeclarePropertiesAsListInputs(Component component, InputDefinition inputToDelete) { + log.debug("#unDeclarePropertiesAsListInputs - removing input declaration for input {} on component {}", inputToDelete.getName(), component.getUniqueId()); + for (PropertyDeclarator propertyDeclarator : propertyDeclaratorsToInput) { + StorageOperationStatus storageOperationStatus = propertyDeclarator.unDeclarePropertiesAsListInputs(component, inputToDelete); + if (StorageOperationStatus.OK != storageOperationStatus) { + log.debug("#unDeclarePropertiesAsListInputs - failed to remove input declaration for input {} on component {}. reason {}", inputToDelete.getName(), component.getUniqueId(), storageOperationStatus); + return storageOperationStatus; + } + } + return StorageOperationStatus.OK; + + } + + /** + * Get properties owner id + * + * @param componentInstInputsMap + * @return + */ + public String getPropOwnerId(ComponentInstInputsMap componentInstInputsMap) { + Pair> propsToDeclare = componentInstInputsMap.resolvePropertiesToDeclare(); + return propsToDeclare.getLeft(); + } public StorageOperationStatus unDeclarePropertiesAsPolicies(Component component, PolicyDefinition policyToDelete) { log.debug("#unDeclarePropertiesAsInputs - removing policy declaration for input {} on component {}", policyToDelete diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyDeclarator.java index c0f76288b2..b8b6c6eb62 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyDeclarator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyDeclarator.java @@ -44,4 +44,21 @@ public interface PropertyDeclarator { */ StorageOperationStatus unDeclarePropertiesAsPolicies(Component component, PolicyDefinition policy); + /** + * Updates given list of properties to get values from the specified "list input" with get_input function. + * This function does NOT create "list input", it needs to be created separately. + * @param component the container + * @param propertiesOwnerId the id of the owner of the properties to declare (e.g ComponentInstance, Policy, Group etc) + * @param propsToDeclare the list of properties that are being declared as inputs + * @param input the input from which properties get values + * @return the input same as passed one at 4th argument + */ + Either declarePropertiesAsListInput(Component component, String propertiesOwnerId, List propsToDeclare, InputDefinition input); + + /** + * Un declare properties declared as list type input + * @param component the container of the input to be deleted + * @param input the input to be deleted + */ + StorageOperationStatus unDeclarePropertiesAsListInputs(Component component, InputDefinition input); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/propertytopolicydeclarators/ComponentInstancePropertyToPolicyDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/propertytopolicydeclarators/ComponentInstancePropertyToPolicyDeclarator.java index bbbdf6f105..2726f67342 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/propertytopolicydeclarators/ComponentInstancePropertyToPolicyDeclarator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/propertytopolicydeclarators/ComponentInstancePropertyToPolicyDeclarator.java @@ -64,6 +64,11 @@ public class ComponentInstancePropertyToPolicyDeclarator extends return StorageOperationStatus.OK; } + @Override + public StorageOperationStatus unDeclarePropertiesAsListInputs(Component component, InputDefinition input) { + return StorageOperationStatus.OK; + } + @Override public StorageOperationStatus unDeclarePropertiesAsPolicies(Component component, PolicyDefinition policy) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/propertytopolicydeclarators/ComponentPropertyToPolicyDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/propertytopolicydeclarators/ComponentPropertyToPolicyDeclarator.java index 1d73786938..6bd09c1622 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/propertytopolicydeclarators/ComponentPropertyToPolicyDeclarator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/propertytopolicydeclarators/ComponentPropertyToPolicyDeclarator.java @@ -64,10 +64,15 @@ public class ComponentPropertyToPolicyDeclarator extends DefaultPropertyDeclarat return StorageOperationStatus.OK; } + @Override + public StorageOperationStatus unDeclarePropertiesAsListInputs(Component component, InputDefinition input) { + // no need for implementation since we are in a policy scenario + return StorageOperationStatus.OK; + } + @Override public void addPropertiesListToInput(PropertyDataDefinition declaredProp, InputDefinition input) { // no need for implementation since we are in a policy scenario - return; } @Override diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java index 7da6533570..9f77c5150a 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java @@ -44,10 +44,15 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import org.apache.commons.lang3.builder.ReflectionToStringBuilder; +import org.openecomp.sdc.be.components.impl.DataTypeBusinessLogic; import org.openecomp.sdc.be.components.impl.InputsBusinessLogic; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.datatypes.enums.DeclarationTypeEnum; import org.openecomp.sdc.be.model.ComponentInstInputsMap; import org.openecomp.sdc.be.model.ComponentInstanceInput; @@ -55,10 +60,13 @@ import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.ComponentInstListInput; +import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.exception.ResponseFormat; +import org.springframework.web.context.WebApplicationContext; @Loggable(prepend = true, value = Loggable.DEBUG, trim = false) @Api(value = "Input Catalog", description = "Input Servlet") @@ -256,6 +264,14 @@ public class InputsServlet extends AbstractValidationsServlet { } } + private Either parseToComponentInstanceMap(String serviceJson, User user) { + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, ComponentInstInputsMap.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); + } + + private Either parseToComponentInstListInput(String json, User user) { + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(json, user, ComponentInstListInput.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); + } + @POST @Path("/{componentType}/{componentId}/create/inputs") @ApiOperation(value = "Create inputs on service", httpMethod = "POST", notes = "Return inputs list", response = Resource.class) @@ -268,6 +284,71 @@ public class InputsServlet extends AbstractValidationsServlet { } + /** + * Creates a "list input" and updates given list of properties to get value from the input. + * also a data type which has same properties is created. + * the data type will be the entry_schema of the list input. + * @param componentType the container type (service, resource, ...) + * @param componentId the container ID + * @param request HttpServletRequest object + * @param userId the User ID + * @param componentInstInputsMapObj the list of properties to be declared and the "list input" to be created. + * the type of the input must be "list". + * schema.type of the input will be the name of new data type. + * @return the created input + */ + @POST + @Path("/{componentType}/{componentId}/create/listInput") + @ApiOperation(value = "Create a list input on service", httpMethod = "POST", notes = "Return input", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) + public Response createListInput(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @ApiParam(value = "ComponentIns Inputs Object to be created", required = true) String componentInstInputsMapObj) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("#createListInput: Start handle request of {}", url); + Response response = null; + + try { + InputsBusinessLogic businessLogic = getInputBL(context); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Either componentInstInputsMapRes = + parseToComponentInstListInput(componentInstInputsMapObj, modifier); + if (componentInstInputsMapRes.isRight()) { + log.debug("failed to parse componentInstInputsMap"); + response = buildErrorResponse(componentInstInputsMapRes.right().value()); + return response; + } + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + ComponentInstListInput componentInstInputsMap = componentInstInputsMapRes.left().value(); + if (log.isDebugEnabled()) { + // for inspection on debug + log.debug("parsed componentInstInputsMap={}", ReflectionToStringBuilder.toString(componentInstInputsMap)); + } + + Either, ResponseFormat> inputPropertiesRes = businessLogic.createListInput( + userId, componentId, componentTypeEnum, componentInstInputsMap, true, false); + if (inputPropertiesRes.isRight()) { + log.debug("failed to create list input for service: {}", componentId); + return buildErrorResponse(inputPropertiesRes.right().value()); + } + Object properties = RepresentationUtils.toRepresentation(inputPropertiesRes.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), properties); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create list input for service with id: " + componentId); + log.debug("createListInput failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + @DELETE @Path("/{componentType}/{componentId}/delete/{inputId}/input") @@ -304,4 +385,142 @@ public class InputsServlet extends AbstractValidationsServlet { } } + /** + * Gets a specific data type associated with a component. + * @param componentType the container type (service, resource, ...) + * @param componentId the container ID + * @param dataTypeName the data type name + * @param request HttpServletRequest object + * @return the data type info + */ + @GET + @Path("/{componentType}/{componentId}/dataType/{dataTypeName}") + @ApiOperation(value = "Get data type in service", httpMethod = "GET", notes = "Get data type in service", + response = DataTypeDefinition.class) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Data type found"), + @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Data type not found")}) + public Response getDataType( + @PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, + @PathParam("dataTypeName") final String dataTypeName, + @Context final HttpServletRequest request + ) { + ServletContext context = request.getSession().getServletContext(); + ComponentsUtils componentsUtils = getComponentsUtils(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(getDataType) Start handle request of {}", url); + Response response; + + try { + DataTypeBusinessLogic businessLogic = getDataTypeBL(context); + Either getResult = businessLogic.getPrivateDataType(componentId, dataTypeName); + if (getResult.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getResult.right().value()); + return buildErrorResponse(componentsUtils.getResponseFormat(actionStatus)); + } + Object json = RepresentationUtils.toRepresentation(getResult.left().value()); + return buildOkResponse(componentsUtils.getResponseFormat(ActionStatus.OK), json); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get data type from service + " + componentId + " + with name: " + dataTypeName); + log.debug("Get data type failed with exception", e); + response = buildErrorResponse(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + /** + * Gets a list of data types which a component has. + * @param componentType the container type (service, resource, ...) + * @param componentId the container ID + * @param request HttpServletRequest object + * @return the list of data types in the component + */ + @GET + @Path("/{componentType}/{componentId}/dataTypes") + @ApiOperation(value = "Get data types that service has", httpMethod = "GET", notes = "Get data types in service", + response = Resource.class) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Data type found"), + @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Component not found")}) + public Response getDataTypes( + @PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, + @Context final HttpServletRequest request + ) { + ServletContext context = request.getSession().getServletContext(); + ComponentsUtils componentsUtils = getComponentsUtils(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(getDataType) Start handle request of {}", url); + Response response; + + try { + DataTypeBusinessLogic businessLogic = getDataTypeBL(context); + Either, StorageOperationStatus> getResult = businessLogic.getPrivateDataTypes(componentId); + if (getResult.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getResult.right().value()); + return buildErrorResponse(componentsUtils.getResponseFormat(actionStatus)); + } + Object json = RepresentationUtils.toRepresentation(getResult.left().value()); + return buildOkResponse(componentsUtils.getResponseFormat(ActionStatus.OK), json); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get data type from service + " + componentId); + log.debug("Get data type failed with exception", e); + response = buildErrorResponse(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + /** + * Deletes a data type from a component. + * @param componentType the container type (service, resource, ...) + * @param componentId the container ID + * @param dataTypeName the data type name to be deleted + * @param request HttpServletRequest object + * @return operation result + */ + @DELETE + @Path("/{componentType}/{componentId}/dataType/{dataTypeName}") + @ApiOperation(value = "Delete data type from service", httpMethod = "DELETE", notes = "Delete service input", + response = Resource.class) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Data type deleted"), + @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Data type not found")}) + public Response deleteDataType( + @PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, + @PathParam("dataTypeName") final String dataTypeName, + @Context final HttpServletRequest request + ) { + ServletContext context = request.getSession().getServletContext(); + ComponentsUtils componentsUtils = getComponentsUtils(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response; + + try { + DataTypeBusinessLogic businessLogic = getDataTypeBL(context); + Either deleteResult = businessLogic.deletePrivateDataType(componentId, dataTypeName); + if (deleteResult.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(deleteResult.right().value()); + return buildErrorResponse(componentsUtils.getResponseFormat(actionStatus)); + } + Object json = RepresentationUtils.toRepresentation(deleteResult.left().value()); + return buildOkResponse(componentsUtils.getResponseFormat(ActionStatus.OK), json); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete data type for service + " + componentId + " + with name: " + dataTypeName); + log.debug("Delete data type failed with exception", e); + response = buildErrorResponse(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + private DataTypeBusinessLogic getDataTypeBL(ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + return webApplicationContext.getBean(DataTypeBusinessLogic.class); + } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java index 405db5a465..baf5b30267 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java @@ -22,6 +22,7 @@ package org.openecomp.sdc.be.tosca; import com.google.gson.Gson; import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.stream.JsonReader; import fj.data.Either; @@ -32,6 +33,7 @@ import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.tosca.ToscaFunctions; import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; import org.openecomp.sdc.be.model.tosca.converters.DataTypePropertyConverter; import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter; @@ -185,25 +187,31 @@ public class PropertyConvertor { log.trace("It's well defined type. convert it"); ToscaValueConverter converter = type.getValueConverter(); return converter.convertToToscaValue(value, innerType, dataTypes); - } else { - log.trace("It's data type or inputs in primitive type. convert as map"); - Object convertedValue; - if (innerConverter != null && (ToscaPropertyType.MAP.equals(type) || ToscaPropertyType.LIST.equals(type))) { - convertedValue = innerConverter.convertToToscaValue(value, innerType, dataTypes); - } else { - if (isScalar) { - // complex json for scalar type - convertedValue = mapConverterInst.handleComplexJsonValue(jsonElement); - } else { - if (innerConverter != null) { - convertedValue = innerConverter.convertToToscaValue(value, innerType, dataTypes); - } else { - convertedValue = mapConverterInst.convertDataTypeToToscaObject(innerType, dataTypes, innerConverter, isScalar, jsonElement, preserveEmptyValue); - } - } + } + log.trace("It's data type or inputs in primitive type. convert as map"); + if (jsonElement.isJsonObject()) { + JsonObject jsonObj = jsonElement.getAsJsonObject(); + // check if value is a get_input function + if (jsonObj.entrySet().size() == 1 && jsonObj.has(ToscaFunctions.GET_INPUT.getFunctionName())) { + Object obj = mapConverterInst.handleComplexJsonValue(jsonElement); + log.debug("It's get_input function. obj={}", obj); + return obj; } - return convertedValue; } + Object convertedValue; + if (innerConverter != null && (ToscaPropertyType.MAP.equals(type) || ToscaPropertyType.LIST.equals(type))) { + convertedValue = innerConverter.convertToToscaValue(value, innerType, dataTypes); + } else if (isScalar) { + // complex json for scalar type + convertedValue = mapConverterInst.handleComplexJsonValue(jsonElement); + } else if (innerConverter != null) { + convertedValue = innerConverter.convertToToscaValue(value, innerType, dataTypes); + } else { + convertedValue = mapConverterInst.convertDataTypeToToscaObject( + innerType, dataTypes, innerConverter, isScalar, jsonElement, preserveEmptyValue); + } + + return convertedValue; } catch (Exception e) { log.debug("convertToToscaValue failed to parse json value :", e); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java index 54cf4cf096..65451e9dc5 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java @@ -76,7 +76,6 @@ import java.util.stream.Collectors; import static org.apache.commons.collections.CollectionUtils.isEmpty; import static org.apache.commons.collections.CollectionUtils.isNotEmpty; import static org.apache.commons.collections.MapUtils.isNotEmpty; -import static org.apache.commons.lang.StringUtils.isNotEmpty; import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.addInterfaceDefinitionElement; import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.addInterfaceTypeElement; @@ -313,6 +312,7 @@ public class ToscaExportHandler { topologyTemplate.setSubstitution_mappings(substitutionMapping); toscaNode.setTopology_template(topologyTemplate); + return Either.left(toscaNode); } @@ -560,6 +560,30 @@ public class ToscaExportHandler { resolveDefaultPropertyValue(inputDef, mergedProperties, dataTypes); toscaNodeType.setProperties(mergedProperties); } + + /* convert private data_types */ + List privateDataTypes = component.getDataTypes(); + if (CollectionUtils.isNotEmpty(privateDataTypes) ) { + Map toscaDataTypeMap = new HashMap<>(); + for (DataTypeDefinition dataType: privateDataTypes) { + log.debug("Emitting private data type: component.name={} dataType.name={}", + component.getNormalizedName(), dataType.getName()); + ToscaDataType toscaDataType = new ToscaDataType(); + toscaDataType.setDerived_from(dataType.getDerivedFromName()); + toscaDataType.setDescription(dataType.getDescription()); + toscaDataType.setVersion(dataType.getVersion()); + if (CollectionUtils.isNotEmpty(dataType.getProperties())) { + toscaDataType.setProperties(dataType.getProperties().stream() + .collect(Collectors.toMap( + s -> s.getName(), + s -> propertyConvertor.convertProperty(dataTypes, s, PropertyConvertor.PropertyType.PROPERTY) + ))); + } + toscaDataTypeMap.put(dataType.getName(), toscaDataType); + } + toscaNode.setData_types(toscaDataTypeMap); + } + // Extracted to method for code reuse return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes); } @@ -570,17 +594,30 @@ public class ToscaExportHandler { for (Map.Entry mergedPropertyEntry : mergedProperties.entrySet()) { ToscaProperty value = mergedPropertyEntry.getValue(); if (Objects.nonNull(value) && value.getDefaultp() instanceof Map) { - Map valueAsMap = (Map) value.getDefaultp(); - String inputName = valueAsMap.get(ToscaFunctions.GET_INPUT.getFunctionName()); - Optional matchedInputDefinition = inputDef.stream() - .filter(componentInput -> componentInput.getName().equals(inputName)) - .findFirst(); - if (matchedInputDefinition.isPresent()) { - InputDefinition matchedInput = matchedInputDefinition.get(); - Object resolvedDefaultValue = new PropertyConvertor().convertToToscaObject(matchedInput.getType(), - matchedInput.getDefaultValue(), matchedInput.getSchemaType(), dataTypes, false); - value.setDefaultp(resolvedDefaultValue); - mergedProperties.put(mergedPropertyEntry.getKey(), value); + Map valueAsMap = (Map) value.getDefaultp(); + Object getInputValue = valueAsMap.get(ToscaFunctions.GET_INPUT.getFunctionName()); + if (getInputValue instanceof String) { + String inputName = (String)getInputValue; + Optional matchedInputDefinition = inputDef.stream() + .filter(componentInput -> componentInput.getName().equals(inputName)) + .findFirst(); + if (matchedInputDefinition.isPresent()) { + InputDefinition matchedInput = matchedInputDefinition.get(); + Object resolvedDefaultValue = new PropertyConvertor().convertToToscaObject(matchedInput.getType(), + matchedInput.getDefaultValue(), matchedInput.getSchemaType(), dataTypes, false); + value.setDefaultp(resolvedDefaultValue); + mergedProperties.put(mergedPropertyEntry.getKey(), value); + } + } else if (getInputValue instanceof List) { + // new get_input syntax to refer to sub-element (introduced from TOSCA v1.3) + // e.g. get_input: [input_name, INDEX, inner_property] + // currently resolving default value for the syntax is not supported + log.debug("#resolveDefaultPropertyValue: ignore get_input list syntax. propname={}, val={}", + mergedPropertyEntry.getKey(), getInputValue); + } else { + // Ignore unknown get_input syntax + log.debug("#resolveDefaultPropertyValue: ignore unknown get_input syntax. propname={}, val={}", + mergedPropertyEntry.getKey(), getInputValue); } } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaDataType.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaDataType.java new file mode 100644 index 0000000000..8a4ec7c301 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaDataType.java @@ -0,0 +1,126 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 Fujitsu Limited. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.tosca.model; + +import java.util.Map; + +/** + * Represents a data type (in data_types in TOSCA model). + */ +public class ToscaDataType { + + private String derived_from; + private String version; + private Map metadata; + private String description; + //private List constraints; + private Map properties; + + /** + * Gets derived_from. + * + * @return Current derived_from value. + */ + public String getDerived_from() { + return derived_from; + } + + /** + * Sets derived_from. + * + * @param derived_from New derived_from value. + */ + public void setDerived_from(String derived_from) { + this.derived_from = derived_from; + } + + /** + * Gets version. + * + * @return Current version value. + */ + public String getVersion() { + return version; + } + + /** + * Sets version. + * + * @param version New version value. + */ + public void setVersion(String version) { + this.version = version; + } + + /** + * Gets metadata map. + * + * @return Current metadata map. + */ + public Map getMetadata() { + return metadata; + } + + /** + * Sets metadata map. + * + * @param metadata New metadata map. + */ + public void setMetadata(Map metadata) { + this.metadata = metadata; + } + + /** + * Gets description. + * + * @return Current description value. + */ + public String getDescription() { + return description; + } + + /** + * Sets description. + * + * @param description New description value. + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * Gets properties map. + * + * @return Current properties map. + */ + public Map getProperties() { + return properties; + } + + /** + * Sets properties map. + * + * @param properties New properties map. + */ + public void setProperties(Map properties) { + this.properties = properties; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplate.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplate.java index 65a6dbf282..742e8bb233 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplate.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplate.java @@ -32,6 +32,7 @@ public class ToscaTemplate { private ToscaMetadata metadata; private List>> imports; private Map interface_types; + private Map data_types; private Map node_types; private ToscaTopolgyTemplate topology_template; @@ -102,5 +103,21 @@ public class ToscaTemplate { this.interface_types = interface_types; } + + /** + * Gets data_types map. + * @return Current data_types map. + */ + public Map getData_types() { + return data_types; + } + + /** + * Sets data_types map. + * @param data_types New data_types map. + */ + public void setData_types(Map data_types) { + this.data_types = data_types; + } } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/DataTypeBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/DataTypeBusinessLogicTest.java new file mode 100644 index 0000000000..9219de1aac --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/DataTypeBusinessLogicTest.java @@ -0,0 +1,156 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 Fujitsu Limited. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.components.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import fj.data.Either; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.openecomp.sdc.be.components.validation.UserValidations; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.user.IUserBusinessLogic; + +public class DataTypeBusinessLogicTest { + + private static final String COMPONENT_INSTANCE_ID = "instanceId"; + private static final String COMPONENT_ID = "componentId"; + private static final String USER_ID = "userId"; + private static final String INSTANCE_INPUT_ID = "inputId"; + private static final String DATATYPE_NAME = "org.onap.datatypes.mytype"; + + @Mock + private ComponentsUtils componentsUtilsMock; + + @Mock + private IUserBusinessLogic userAdminMock; + + @Mock + private ToscaOperationFacade toscaOperationFacadeMock; + + @Mock + private UserValidations userValidations; + + @Mock + private ComponentInstanceBusinessLogic componentInstanceBusinessLogic; + + @InjectMocks + private DataTypeBusinessLogic testInstance; + + private Service service; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + service = new Service(); + service.setUniqueId(COMPONENT_INSTANCE_ID); + ComponentInstance componentInstance = new ComponentInstance(); + componentInstance.setUniqueId(COMPONENT_INSTANCE_ID); + service.setComponentInstances(Collections.singletonList(componentInstance)); + DataTypeDefinition dataType = new DataTypeDefinition(); + dataType.setName(DATATYPE_NAME); + dataType.setDerivedFromName(ToscaPropertyType.Root.getType()); + List dataTypes = Arrays.asList(dataType); + service.setDataTypes(dataTypes); + + Map> instanceInputMap = new HashMap<>(); + ComponentInstanceInput componentInstanceInput = new ComponentInstanceInput(); + componentInstanceInput.setInputId(INSTANCE_INPUT_ID); + instanceInputMap.put(COMPONENT_INSTANCE_ID, Collections.singletonList(componentInstanceInput)); + instanceInputMap.put("someInputId", Collections.singletonList(new ComponentInstanceInput())); + service.setComponentInstancesInputs(instanceInputMap); + when(userValidations.validateUserExists(eq(USER_ID), anyString(), eq(false))).thenReturn(new User()); + when(userAdminMock.getUser(USER_ID, false)).thenReturn(Either.left(new User())); + } + + @Test + public void test_getPrivateDataTypes() throws Exception { + setMockitoWhenGetToscaElementCalled(); + + Either, StorageOperationStatus> result = testInstance.getPrivateDataTypes(COMPONENT_ID); + assertTrue(result.isLeft()); + List dataTypes = result.left().value(); + assertEquals(service.getDataTypes(), dataTypes); + } + + @Test + public void test_getPrivateDataType() throws Exception { + setMockitoWhenGetToscaElementCalled(); + + Either result = + testInstance.getPrivateDataType(COMPONENT_ID, DATATYPE_NAME); + assertTrue(result.isLeft()); + DataTypeDefinition dataType = result.left().value(); + assertEquals(service.getDataTypes().get(0), dataType); + } + + @Test + public void test_deletePrivateDataType1() throws Exception { + setMockitoWhenGetToscaElementCalled(); + when(toscaOperationFacadeMock.deleteDataTypeOfComponent(service, DATATYPE_NAME)) + .thenReturn(StorageOperationStatus.OK); + + Either result = + testInstance.deletePrivateDataType(COMPONENT_ID, DATATYPE_NAME); + assertTrue(result.isLeft()); + DataTypeDefinition dataType = result.left().value(); + assertEquals(service.getDataTypes().get(0), dataType); + } + + @Test + public void test_deletePrivateDataType2() throws Exception { + when(toscaOperationFacadeMock.deleteDataTypeOfComponent(service, DATATYPE_NAME)) + .thenReturn(StorageOperationStatus.OK); + + Either result = + testInstance.deletePrivateDataType(service, DATATYPE_NAME); + assertTrue(result.isLeft()); + DataTypeDefinition dataType = result.left().value(); + assertEquals(service.getDataTypes().get(0), dataType); + } + + private void setMockitoWhenGetToscaElementCalled() { + when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), Mockito.any(ComponentParametersView.class))) + .thenReturn(Either.left(service)); + } +} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogicTest.java index 2ef3d463eb..b306b2ad72 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogicTest.java @@ -21,18 +21,31 @@ package org.openecomp.sdc.be.components.impl; import fj.data.Either; +import org.apache.commons.lang3.tuple.ImmutablePair; import org.junit.Before; import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; +import org.openecomp.sdc.be.components.property.PropertyDeclarationOrchestrator; +import org.openecomp.sdc.be.components.utils.PropertyDataDefinitionBuilder; import org.openecomp.sdc.be.components.validation.UserValidations; 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.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.model.*; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade; +import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; import org.openecomp.sdc.be.user.IUserBusinessLogic; import org.openecomp.sdc.exception.ResponseFormat; @@ -40,9 +53,9 @@ import java.util.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.anyObject; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class InputsBusinessLogicTest { @@ -50,7 +63,13 @@ public class InputsBusinessLogicTest { private static final String COMPONENT_INSTANCE_ID = "instanceId"; private static final String COMPONENT_ID = "componentId"; private static final String USER_ID = "userId"; - public static final String INSTANCE_INPUT_ID = "inputId"; + private static final String INSTANCE_INPUT_ID = "inputId"; + private static final String LISTINPUT_NAME = "listInput"; + private static final String LISTINPUT_SCHEMA_TYPE = "org.onap.datatypes.listinput"; + private static final String LISTINPUT_PROP1_NAME = "prop1"; + private static final String LISTINPUT_PROP1_TYPE = "string"; + private static final String LISTINPUT_PROP2_NAME = "prop2"; + private static final String LISTINPUT_PROP2_TYPE = "integer"; @Mock private ComponentsUtils componentsUtilsMock; @@ -67,26 +86,54 @@ public class InputsBusinessLogicTest { @Mock private ComponentInstanceBusinessLogic componentInstanceBusinessLogic; + @Mock + private IGraphLockOperation graphLockOperation; + + @Mock + private PropertyDeclarationOrchestrator propertyDeclarationOrchestrator; + + @Mock + private ApplicationDataTypeCache applicationDataTypeCache; + + @Mock + private PropertyOperation propertyOperation; + + @Mock + private TitanDao titanDao; + + @Mock + private DataTypeBusinessLogic dataTypeBusinessLogic; + @InjectMocks private InputsBusinessLogic testInstance; private Service service; + @Captor + ArgumentCaptor> dataTypesMapCaptor; + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); service = new Service(); - service.setUniqueId(COMPONENT_INSTANCE_ID); + service.setUniqueId(COMPONENT_ID); + service.setLastUpdaterUserId(USER_ID); + service.setIsDeleted(false); + service.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + + // add a ComponentInstance ComponentInstance componentInstance = new ComponentInstance(); componentInstance.setUniqueId(COMPONENT_INSTANCE_ID); service.setComponentInstances(Collections.singletonList(componentInstance)); + // add inputs to the ComponentInstance Map> instanceInputMap = new HashMap<>(); ComponentInstanceInput componentInstanceInput = new ComponentInstanceInput(); componentInstanceInput.setInputId(INSTANCE_INPUT_ID); instanceInputMap.put(COMPONENT_INSTANCE_ID, Collections.singletonList(componentInstanceInput)); instanceInputMap.put("someInputId", Collections.singletonList(new ComponentInstanceInput())); service.setComponentInstancesInputs(instanceInputMap); + when(userValidations.validateUserExists(eq(USER_ID), anyString(), eq(false))).thenReturn(new User()); when(userAdminMock.getUser(USER_ID, false)).thenReturn(Either.left(new User())); } @@ -96,7 +143,7 @@ public class InputsBusinessLogicTest { when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), Mockito.any(ComponentParametersView.class))).thenReturn(Either.left(service)); Either, ResponseFormat> componentInstanceInputs = testInstance.getComponentInstanceInputs(USER_ID, COMPONENT_ID, "nonExisting"); assertTrue(componentInstanceInputs.isRight()); - Mockito.verify(componentsUtilsMock).getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND); + verify(componentsUtilsMock).getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND); } @Test @@ -263,4 +310,321 @@ public class InputsBusinessLogicTest { Either, ResponseFormat> result = testInstance.getInputsForComponentInput("USR01", COMPONENT_ID,"INPO1"); assertEquals(true,result.isLeft()); } + + + private InputDefinition setUpListInput() { + InputDefinition listInput = new InputDefinition(); + listInput.setName(LISTINPUT_NAME); + listInput.setType("list"); + SchemaDefinition listInputSchema = new SchemaDefinition(); + listInputSchema.setProperty(new PropertyDataDefinitionBuilder() + .setType(LISTINPUT_SCHEMA_TYPE) + .setIsRequired(false) + .build() + ); + listInput.setSchema(listInputSchema); + return listInput; + } + + private ComponentInstListInput setUpCreateListInputParams() { + ComponentInstListInput componentInstListInput = new ComponentInstListInput(); + + // Create a "list input" + InputDefinition listInput = setUpListInput(); + componentInstListInput.setListInput(listInput); + + // Create ComponentInstancePropInputs + // for inputs in the ComponentInstance + Map> propInputsListMap = new HashMap<>(); + // Add 2 PropInputs. property owner is COMPONENT_INSTANCE_ID + List propInputsList = new ArrayList<>(); + ComponentInstancePropInput propInput = new ComponentInstancePropInput(); + propInput.setName(LISTINPUT_PROP1_NAME); + propInput.setType(LISTINPUT_PROP1_TYPE); + propInput.setUniqueId(COMPONENT_INSTANCE_ID+"."+LISTINPUT_PROP1_NAME); + propInputsList.add(propInput); + propInput = new ComponentInstancePropInput(); + propInput.setName(LISTINPUT_PROP2_NAME); + propInput.setType(LISTINPUT_PROP2_TYPE); + propInput.setUniqueId(COMPONENT_INSTANCE_ID+"."+LISTINPUT_PROP2_NAME); + propInputsList.add(propInput); + propInputsListMap.put(COMPONENT_INSTANCE_ID, propInputsList); + ComponentInstInputsMap componentInstInputsMap = new ComponentInstInputsMap(); + componentInstInputsMap.setComponentInstanceInputsMap(propInputsListMap); + componentInstListInput.setComponentInstInputsMap(componentInstInputsMap); + + return componentInstListInput; + } + + @Test + public void test_createListInput_success() throws Exception { + ComponentInstListInput createListInputParams = setUpCreateListInputParams(); + ComponentInstInputsMap componentInstInputsMap = createListInputParams.getComponentInstInputsMap(); + List propInputsList = componentInstInputsMap.getComponentInstanceInputsMap().get(COMPONENT_INSTANCE_ID); + InputDefinition listInput = createListInputParams.getListInput(); + + // set up mock returns + // for get component object: + when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), Mockito.any(ComponentParametersView.class))).thenReturn(Either.left(service)); + when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.OK); + // for data type creation (use captor): + when(toscaOperationFacadeMock.addDataTypesToComponent(dataTypesMapCaptor.capture(), eq(COMPONENT_ID))).thenReturn(Either.left(new ArrayList<>())); + when(propertyDeclarationOrchestrator.getPropOwnerId(componentInstInputsMap)).thenReturn(COMPONENT_INSTANCE_ID); + when(propertyDeclarationOrchestrator.declarePropertiesToListInput(service, componentInstInputsMap, listInput)).thenReturn(Either.left(listInput)); + // for BaseOperation.getAllDataTypes: + when(applicationDataTypeCache.getAll()).thenReturn(Either.left(new HashMap<>())); // don't use Collections.emptyMap + // for BaseOperation.validatePropertyDefaultValue: + when(propertyOperation.isPropertyTypeValid(any())).thenReturn(true); + when(propertyOperation.isPropertyInnerTypeValid(any(),any())).thenReturn(new ImmutablePair<>(listInput.getSchemaType(), true)); + when(propertyOperation.isPropertyDefaultValueValid(any(), any())).thenReturn(true); + // for createListInputsInGraph: + when(toscaOperationFacadeMock.addInputsToComponent(anyMap(), eq(COMPONENT_ID))).thenReturn(Either.left(Arrays.asList(listInput))); + // for rollback/commit: + when(titanDao.commit()).thenReturn(TitanOperationStatus.OK); + // for unlock resource + when(graphLockOperation.unlockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.OK); + + Either, ResponseFormat> result = + testInstance.createListInput(USER_ID, COMPONENT_ID, ComponentTypeEnum.SERVICE, createListInputParams, true, false); + // validate result + assertEquals(true, result.isLeft()); + List resultInputList = result.left().value(); + assertEquals(1, resultInputList.size()); + //InputDefinition resultInput = resultInputList.get(0); + Map captoredDataTypeMap = dataTypesMapCaptor.getValue(); + assertEquals(1, captoredDataTypeMap.size()); + assertEquals(true, captoredDataTypeMap.containsKey(LISTINPUT_SCHEMA_TYPE)); + DataTypeDefinition captoredDataType = captoredDataTypeMap.get(LISTINPUT_SCHEMA_TYPE); + assertEquals("tosca.datatypes.Root", captoredDataType.getDerivedFromName()); + assertEquals( propInputsList.size(), captoredDataType.getProperties().size()); + // confirm if corresponding property exists in data type + captoredDataType.getProperties().forEach(dataTypeProp -> { + Optional find = propInputsList.stream() + .filter(propInput -> propInput.getName().equals(dataTypeProp.getName())).findAny(); + assertEquals(true, find.isPresent()); + }); + } + + @Test + public void test_createListInput_fail_getComponent() throws Exception { + ComponentInstListInput createListInputParams = setUpCreateListInputParams(); + when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), Mockito.any(ComponentParametersView.class))).thenReturn(Either.right(StorageOperationStatus.NOT_FOUND)); + Either, ResponseFormat> result = + testInstance.createListInput(USER_ID, COMPONENT_ID, ComponentTypeEnum.SERVICE, createListInputParams, true, false); + assertEquals(true, result.isRight()); + } + + + @Test + public void test_createListInput_fail_lockComponent() throws Exception { + ComponentInstListInput createListInputParams = setUpCreateListInputParams(); + when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), Mockito.any(ComponentParametersView.class))).thenReturn(Either.left(service)); + when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.FAILED_TO_LOCK_ELEMENT); + Either, ResponseFormat> result = + testInstance.createListInput(USER_ID, COMPONENT_ID, ComponentTypeEnum.SERVICE, createListInputParams, true, false); + assertEquals(true, result.isRight()); + } + + @Test + public void test_createListInput_fail_getAllDataTypes() throws Exception { + ComponentInstListInput createListInputParams = setUpCreateListInputParams(); + ComponentInstInputsMap componentInstInputsMap = createListInputParams.getComponentInstInputsMap(); + + when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), Mockito.any(ComponentParametersView.class))).thenReturn(Either.left(service)); + when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacadeMock.addDataTypesToComponent(dataTypesMapCaptor.capture(), eq(COMPONENT_ID))).thenReturn(Either.left(new ArrayList<>())); + when(propertyDeclarationOrchestrator.getPropOwnerId(componentInstInputsMap)).thenReturn(COMPONENT_INSTANCE_ID); + when(applicationDataTypeCache.getAll()).thenReturn(Either.right(TitanOperationStatus.NOT_FOUND)); + when(componentsUtilsMock.getResponseFormat(ActionStatus.DATA_TYPE_CANNOT_BE_EMPTY)).thenReturn(new ResponseFormat()); + + Either, ResponseFormat> result = + testInstance.createListInput(USER_ID, COMPONENT_ID, ComponentTypeEnum.SERVICE, createListInputParams, true, false); + assertEquals(true, result.isRight()); + verify(applicationDataTypeCache, times(1)).getAll(); + verify(componentsUtilsMock, times(1)).getResponseFormat(ActionStatus.DATA_TYPE_CANNOT_BE_EMPTY); + } + + @Test + public void test_createListInput_fail_prepareAndValidateInput() throws Exception { + ComponentInstListInput createListInputParams = setUpCreateListInputParams(); + ComponentInstInputsMap componentInstInputsMap = createListInputParams.getComponentInstInputsMap(); + InputDefinition listInput = createListInputParams.getListInput(); + + when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), Mockito.any(ComponentParametersView.class))).thenReturn(Either.left(service)); + when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacadeMock.addDataTypesToComponent(dataTypesMapCaptor.capture(), eq(COMPONENT_ID))).thenReturn(Either.left(new ArrayList<>())); + when(propertyDeclarationOrchestrator.getPropOwnerId(componentInstInputsMap)).thenReturn(COMPONENT_INSTANCE_ID); + when(applicationDataTypeCache.getAll()).thenReturn(Either.left(new HashMap<>())); // don't use Collections.emptyMap + // for BaseOperation.validatePropertyDefaultValue: + when(propertyOperation.isPropertyTypeValid(any())).thenReturn(false); + + Either, ResponseFormat> result = + testInstance.createListInput(USER_ID, COMPONENT_ID, ComponentTypeEnum.SERVICE, createListInputParams, true, false); + assertEquals(true, result.isRight()); + verify(propertyOperation, times(1)).isPropertyTypeValid(any()); + } + + @Test + public void test_createListInput_fail_addInputsToComponent() throws Exception { + ComponentInstListInput createListInputParams = setUpCreateListInputParams(); + ComponentInstInputsMap componentInstInputsMap = createListInputParams.getComponentInstInputsMap(); + InputDefinition listInput = createListInputParams.getListInput(); + + when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), Mockito.any(ComponentParametersView.class))).thenReturn(Either.left(service)); + when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacadeMock.addDataTypesToComponent(dataTypesMapCaptor.capture(), eq(COMPONENT_ID))).thenReturn(Either.left(new ArrayList<>())); + when(propertyDeclarationOrchestrator.getPropOwnerId(componentInstInputsMap)).thenReturn(COMPONENT_INSTANCE_ID); + when(applicationDataTypeCache.getAll()).thenReturn(Either.left(new HashMap<>())); // don't use Collections.emptyMap + // for BaseOperation.validatePropertyDefaultValue: + when(propertyOperation.isPropertyTypeValid(any())).thenReturn(true); + when(propertyOperation.isPropertyInnerTypeValid(any(),any())).thenReturn(new ImmutablePair<>(listInput.getSchemaType(), true)); + when(propertyOperation.isPropertyDefaultValueValid(any(), any())).thenReturn(true); + when(toscaOperationFacadeMock.addInputsToComponent(anyMap(), eq(COMPONENT_ID))).thenReturn(Either.right(StorageOperationStatus.NOT_FOUND)); + + Either, ResponseFormat> result = + testInstance.createListInput(USER_ID, COMPONENT_ID, ComponentTypeEnum.SERVICE, createListInputParams, true, false); + assertEquals(true, result.isRight()); + verify(toscaOperationFacadeMock, times(1)).addInputsToComponent(anyMap(), eq(COMPONENT_ID)); + } + + @Test + public void test_deleteInput_listInput_fail_getComponent() throws Exception { + //ComponentInstListInput createListInputParams = setUpCreateListInputParams(); + when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) + .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND)); + when(componentsUtilsMock.getResponseFormat(any())).thenReturn(new ResponseFormat()); + + Either result = testInstance.deleteInput(COMPONENT_ID, USER_ID, LISTINPUT_NAME); + assertEquals(true, result.isRight()); + verify(toscaOperationFacadeMock, times(1)).getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)); + } + + + @Test + public void test_deleteInput_listInput_fail_validateInput() throws Exception { + InputDefinition listInput = setUpListInput(); + String inputId = COMPONENT_ID + "." + listInput.getName(); + listInput.setUniqueId(inputId); + service.setInputs(Collections.singletonList(listInput)); + //ComponentInstListInput createListInputParams = setUpCreateListInputParams(); + final String NONEXIST_INPUT_NAME = "myInput"; + + when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) + .thenReturn(Either.left(service)); + when(componentsUtilsMock.getResponseFormat(any())).thenReturn(new ResponseFormat()); + + Either result = testInstance.deleteInput(COMPONENT_ID, USER_ID, NONEXIST_INPUT_NAME); + assertEquals(true, result.isRight()); + verify(toscaOperationFacadeMock, times(1)).getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)); + } + + + @Test + public void test_deleteInput_listInput_fail_lockComponent() throws Exception { + InputDefinition listInput = setUpListInput(); + String inputId = COMPONENT_ID + "." + listInput.getName(); + listInput.setUniqueId(inputId); + service.setInputs(Collections.singletonList(listInput)); + + when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) + .thenReturn(Either.left(service)); + //when(componentsUtilsMock.getResponseFormat(any())).thenReturn(new ResponseFormat()); + when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.NOT_FOUND); + + Either result = testInstance.deleteInput(COMPONENT_ID, USER_ID, inputId); + assertEquals(true, result.isRight()); + verify(toscaOperationFacadeMock, times(1)).getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)); + verify(graphLockOperation, times(1)).lockComponent(COMPONENT_ID, NodeTypeEnum.Service); + } + + + @Test + public void test_deleteInput_listInput_fail_deleteInput() throws Exception { + InputDefinition listInput = setUpListInput(); + String inputId = COMPONENT_ID + "." + listInput.getName(); + listInput.setUniqueId(inputId); + service.setInputs(Collections.singletonList(listInput)); + + when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) + .thenReturn(Either.left(service)); + when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacadeMock.deleteInputOfResource(service, listInput.getName())).thenReturn(StorageOperationStatus.BAD_REQUEST); + when(componentsUtilsMock.getResponseFormat(any())).thenReturn(new ResponseFormat()); + + Either result = testInstance.deleteInput(COMPONENT_ID, USER_ID, inputId); + assertEquals(true, result.isRight()); + verify(toscaOperationFacadeMock, times(1)).getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)); + verify(graphLockOperation, times(1)).lockComponent(COMPONENT_ID, NodeTypeEnum.Service); + verify(toscaOperationFacadeMock, times(1)).deleteInputOfResource(service, listInput.getName()); + } + + + @Test + public void test_deleteInput_listInput_success() throws Exception { + InputDefinition listInput = setUpListInput(); + String inputId = COMPONENT_ID + "." + listInput.getName(); + listInput.setUniqueId(inputId); + listInput.setIsDeclaredListInput(true); + service.setInputs(Collections.singletonList(listInput)); + ArgumentCaptor schemaTypeCaptor = ArgumentCaptor.forClass(String.class); + + when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) + .thenReturn(Either.left(service)); + when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacadeMock.deleteInputOfResource(service, listInput.getName())).thenReturn(StorageOperationStatus.OK); + //when(componentsUtilsMock.getResponseFormat(any())).thenReturn(new ResponseFormat()); + when(propertyDeclarationOrchestrator.unDeclarePropertiesAsListInputs(service, listInput)).thenReturn(StorageOperationStatus.OK); + when(dataTypeBusinessLogic.deletePrivateDataType(eq(service), schemaTypeCaptor.capture())) + .thenReturn(Either.left(new DataTypeDefinition())); // TODO: replace to return proper datatype + //when(propertyDeclarationOrchestrator.unDeclarePropertiesAsInputs(service, listInput)).thenReturn(StorageOperationStatus.OK); + + Either result = testInstance.deleteInput(COMPONENT_ID, USER_ID, inputId); + assertEquals(true, result.isLeft()); + verify(propertyDeclarationOrchestrator, times(1)).unDeclarePropertiesAsListInputs(service, listInput); + verify(dataTypeBusinessLogic, times(1)).deletePrivateDataType(service, listInput.getSchemaType()); + assertEquals(listInput.getSchemaType(), schemaTypeCaptor.getValue()); + } + + + @Test + public void test_deleteInput_input_fail_unDeclare() throws Exception { + InputDefinition listInput = setUpListInput(); + String inputId = COMPONENT_ID + "." + listInput.getName(); + listInput.setUniqueId(inputId); + listInput.setIsDeclaredListInput(false); + service.setInputs(Collections.singletonList(listInput)); + + when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) + .thenReturn(Either.left(service)); + when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacadeMock.deleteInputOfResource(service, listInput.getName())).thenReturn(StorageOperationStatus.OK); + //when(componentsUtilsMock.getResponseFormat(any())).thenReturn(new ResponseFormat()); + when(propertyDeclarationOrchestrator.unDeclarePropertiesAsInputs(service, listInput)).thenReturn(StorageOperationStatus.BAD_REQUEST); + + Either result = testInstance.deleteInput(COMPONENT_ID, USER_ID, inputId); + assertEquals(true, result.isRight()); + verify(propertyDeclarationOrchestrator, times(1)).unDeclarePropertiesAsInputs(service, listInput); + } + + + @Test + public void test_deleteInput_input_success() throws Exception { + InputDefinition listInput = setUpListInput(); + String inputId = COMPONENT_ID + "." + listInput.getName(); + listInput.setUniqueId(inputId); + listInput.setIsDeclaredListInput(false); + service.setInputs(Collections.singletonList(listInput)); + + when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) + .thenReturn(Either.left(service)); + when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacadeMock.deleteInputOfResource(service, listInput.getName())).thenReturn(StorageOperationStatus.OK); + //when(componentsUtilsMock.getResponseFormat(any())).thenReturn(new ResponseFormat()); + when(propertyDeclarationOrchestrator.unDeclarePropertiesAsInputs(service, listInput)).thenReturn(StorageOperationStatus.OK); + + Either result = testInstance.deleteInput(COMPONENT_ID, USER_ID, inputId); + assertEquals(true, result.isLeft()); + verify(propertyDeclarationOrchestrator, times(1)).unDeclarePropertiesAsInputs(service, listInput); + } + } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/ComponentInstanceInputPropertyDeclaratorTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/ComponentInstanceInputPropertyDeclaratorTest.java index acfa721e74..f5d4aabd92 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/ComponentInstanceInputPropertyDeclaratorTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/ComponentInstanceInputPropertyDeclaratorTest.java @@ -1,6 +1,7 @@ package org.openecomp.sdc.be.components.property; import fj.data.Either; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -8,19 +9,25 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.utils.AnnotationBuilder; import org.openecomp.sdc.be.components.utils.InputsBuilder; +import org.openecomp.sdc.be.components.utils.PropertyDataDefinitionBuilder; import org.openecomp.sdc.be.components.utils.ResourceBuilder; import org.openecomp.sdc.be.datatypes.elements.Annotation; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstanceInput; import org.openecomp.sdc.be.model.ComponentInstancePropInput; import org.openecomp.sdc.be.model.ComponentParametersView; import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade; import org.openecomp.sdc.be.model.operations.StorageException; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -41,6 +48,12 @@ public class ComponentInstanceInputPropertyDeclaratorTest extends PropertyDeclar @Mock private ToscaOperationFacade toscaOperationFacade; + @Mock + private ComponentInstanceBusinessLogic componentInstanceBusinessLogic; + + @Mock + private PropertyOperation propertyOperation; + @Captor private ArgumentCaptor inputsFilterCaptor; @@ -50,8 +63,8 @@ public class ComponentInstanceInputPropertyDeclaratorTest extends PropertyDeclar @Before public void setUp() throws Exception { super.setUp(); - testInstance = new ComponentInstanceInputPropertyDeclarator(mockComponentUtils(), null, - toscaOperationFacade, null, mockExceptionUtils()); + testInstance = new ComponentInstanceInputPropertyDeclarator(mockComponentUtils(), propertyOperation, + toscaOperationFacade, componentInstanceBusinessLogic, mockExceptionUtils()); annotation1 = AnnotationBuilder.create() .setType("annotationType1") .setName("annotation1") @@ -88,6 +101,55 @@ public class ComponentInstanceInputPropertyDeclaratorTest extends PropertyDeclar assertThatExceptionOfType(StorageException.class).isThrownBy(() -> testInstance.declarePropertiesAsInputs(resource, "inst1", propsToDeclare)); } + @Test + public void unDeclarePropertiesAsListInputsTest() { + InputDefinition inputToDelete = new InputDefinition(); + inputToDelete.setUniqueId(INPUT_ID); + inputToDelete.setName(INPUT_ID); + inputToDelete.setIsDeclaredListInput(true); + + Component component = createComponentWithListInput(INPUT_ID, "innerPropName"); + PropertyDefinition prop = new PropertyDataDefinitionBuilder() + .setName("propName") + .setValue(generateGetInputValueAsListInput(INPUT_ID, "innerPropName")) + .setType("list") + .setUniqueId("propName") + .addGetInputValue(INPUT_ID) + .build(); + component.setProperties(Collections.singletonList(prop)); + + List ciPropList = new ArrayList<>(); + ComponentInstanceInput ciProp = new ComponentInstanceInput(); + List pathOfComponentInstances = new ArrayList<>(); + pathOfComponentInstances.add("pathOfComponentInstances"); + ciProp.setPath(pathOfComponentInstances); + ciProp.setUniqueId("componentInstanceId"); + ciProp.setDefaultValue("default value"); + ciProp.setComponentInstanceId("componentInstanceId"); + ciProp.setComponentInstanceName("componentInstanceName"); + ciProp.setValue(generateGetInputValueAsListInput(INPUT_ID, "innerPropName")); + ciPropList.add(ciProp); + + when(componentInstanceBusinessLogic.getComponentInstanceInputsByInputId(eq(component), eq(INPUT_ID))).thenReturn(ciPropList); + when(propertyOperation.findDefaultValueFromSecondPosition(eq(pathOfComponentInstances), eq(ciProp.getUniqueId()), eq(ciProp.getDefaultValue()))).thenReturn(Either.left(ciProp.getDefaultValue())); + when(toscaOperationFacade.updateComponentInstanceInputs(eq(component), eq(ciProp.getComponentInstanceId()), eq(ciPropList))).thenReturn(StorageOperationStatus.OK); + StorageOperationStatus storageOperationStatus = testInstance.unDeclarePropertiesAsListInputs(component, inputToDelete); + + assertThat(storageOperationStatus).isEqualTo(StorageOperationStatus.OK); + } + + @Test + public void unDeclarePropertiesAsListInputsTest_whenNoListInput_returnOk() { + InputDefinition input = new InputDefinition(); + input.setUniqueId(INPUT_ID); + input.setName(INPUT_ID); + input.setValue("value"); + List resList = new ArrayList<>(); + when(componentInstanceBusinessLogic.getComponentInstanceInputsByInputId(eq(resource), eq(INPUT_ID))).thenReturn(resList); + StorageOperationStatus status = testInstance.unDeclarePropertiesAsListInputs(resource, input); + Assert.assertEquals(status, StorageOperationStatus.OK); + } + private void verifyInputAnnotations(InputDefinition inputDefinition) { List annotations = inputDefinition.getAnnotations(); assertThat(annotations) @@ -105,4 +167,19 @@ public class ComponentInstanceInputPropertyDeclaratorTest extends PropertyDeclar .build(); } -} \ No newline at end of file + private Component createComponentWithListInput(String inputName, String propName) { + InputDefinition input = InputsBuilder.create() + .setName(inputName) + .build(); + + input.setUniqueId(INPUT_ID); + input.setName(INPUT_ID); + input.setDefaultValue("defaultValue"); + input.setValue(generateGetInputValueAsListInput(inputName, propName)); + + return new ResourceBuilder() + .setUniqueId(RESOURCE_ID) + .addInput(input) + .build(); + } +} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/ComponentInstancePropertyDeclaratorTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/ComponentInstancePropertyDeclaratorTest.java index 5752ae272e..f59adada9a 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/ComponentInstancePropertyDeclaratorTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/ComponentInstancePropertyDeclaratorTest.java @@ -1,26 +1,25 @@ package org.openecomp.sdc.be.components.property; import fj.data.Either; +import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.InjectMocks; -import org.mockito.Mock; +import org.mockito.*; import org.mockito.junit.MockitoJUnitRunner; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.utils.InputsBuilder; import org.openecomp.sdc.be.components.utils.PropertyDataDefinitionBuilder; +import org.openecomp.sdc.be.components.utils.ResourceBuilder; import org.openecomp.sdc.be.dao.utils.MapUtil; import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.model.*; import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -37,6 +36,11 @@ public class ComponentInstancePropertyDeclaratorTest extends PropertyDeclaratorT private ComponentInstancePropertyDeclarator testInstance; @Mock private ToscaOperationFacade toscaOperationFacade; + @Mock + private ComponentInstanceBusinessLogic componentInstanceBusinessLogic; + @Mock + private PropertyOperation propertyOperation; + @Captor private ArgumentCaptor>> instancePropertiesCaptor; @@ -98,6 +102,100 @@ public class ComponentInstancePropertyDeclaratorTest extends PropertyDeclaratorT verifyUpdatedComplexProperty(capturedInstanceProperties, inputs); } + @Test + public void declarePropertiesAsListInput() { + // construct arguments + List properties = Arrays.asList(prop1, prop2); + List propsToDeclare = createInstancePropInputList(properties); + InputDefinition input = new InputDefinition(new PropertyDataDefinitionBuilder() + .setName("listinput") + .setType("list") + .setDescription("description") + .setSchemaType("org.onap.datatype.listinput") + .build()); + // mock returns + when(toscaOperationFacade.addComponentInstancePropertiesToComponent(eq(resource), instancePropertiesCaptor.capture())).thenReturn(Either.left(Collections.emptyMap())); + Either result = testInstance.declarePropertiesAsListInput(resource, "inst1", propsToDeclare, input); + // validate result + assertThat(result.isLeft()).isTrue(); + List capturedInstanceProperties = instancePropertiesCaptor.getValue().get(INSTANCE_ID); + assertThat(capturedInstanceProperties.size()).isEqualTo(2); + Map propertiesMap = + properties.stream().collect(Collectors.toMap(PropertyDataDefinition::getName, e->e)); + for(ComponentInstanceProperty instanceProperty: capturedInstanceProperties) { + assertThat(propertiesMap.containsKey(instanceProperty.getName())).isTrue(); + PropertyDataDefinition property = propertiesMap.get(instanceProperty.getName()); + assertThat(instanceProperty.getType()).isEqualTo(property.getType()); + assertThat(instanceProperty.isGetInputProperty()).isTrue(); + } + } + + @Test + public void declarePropertiesAsListInput_propertyOwnerNotFound() { + // construct arguments + List properties = Arrays.asList(prop1, prop2); + List propsToDeclare = createInstancePropInputList(properties); + InputDefinition input = new InputDefinition(new PropertyDataDefinitionBuilder() + .setName("listinput") + .setType("list") + .setDescription("description") + .setSchemaType("org.onap.datatype.listinput") + .build()); + Either result = testInstance.declarePropertiesAsListInput(resource, "inst2", propsToDeclare, input); + // validate result + assertThat(result.isRight()).isTrue(); + assertThat(result.right().value()).isEqualTo(StorageOperationStatus.NOT_FOUND); + } + + @Test + public void unDeclarePropertiesAsListInputsTest() { + InputDefinition inputToDelete = new InputDefinition(); + inputToDelete.setUniqueId(INPUT_ID); + inputToDelete.setName(INPUT_ID); + inputToDelete.setIsDeclaredListInput(true); + + Component component = createComponentWithListInput(INPUT_ID, "innerPropName"); + PropertyDefinition prop = new PropertyDataDefinitionBuilder() + .setName("propName") + .setValue(generateGetInputValueAsListInput(INPUT_ID, "innerPropName")) + .setType("list") + .setUniqueId("propName") + .addGetInputValue(INPUT_ID) + .build(); + component.setProperties(Collections.singletonList(prop)); + + List ciPropList = new ArrayList<>(); + ComponentInstanceProperty ciProp = new ComponentInstanceProperty(); + List pathOfComponentInstances = new ArrayList<>(); + pathOfComponentInstances.add("pathOfComponentInstances"); + ciProp.setPath(pathOfComponentInstances); + ciProp.setUniqueId("componentInstanceId"); + ciProp.setDefaultValue("default value"); + ciProp.setComponentInstanceId("componentInstanceId"); + ciProp.setComponentInstanceName("componentInstanceName"); + ciProp.setValue(generateGetInputValueAsListInput(INPUT_ID, "innerPropName")); + ciPropList.add(ciProp); + + when(componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(eq(component), eq(INPUT_ID))).thenReturn(ciPropList); + when(propertyOperation.findDefaultValueFromSecondPosition(eq(pathOfComponentInstances), eq(ciProp.getUniqueId()), eq(ciProp.getDefaultValue()))).thenReturn(Either.left(ciProp.getDefaultValue())); + when(toscaOperationFacade.updateComponentInstanceProperties(eq(component), eq(ciProp.getComponentInstanceId()), eq(ciPropList))).thenReturn(StorageOperationStatus.OK); + StorageOperationStatus storageOperationStatus = testInstance.unDeclarePropertiesAsListInputs(component, inputToDelete); + + assertThat(storageOperationStatus).isEqualTo(StorageOperationStatus.OK); + } + + @Test + public void unDeclarePropertiesAsListInputsTest_whenNoListInput_returnOk() { + InputDefinition input = new InputDefinition(); + input.setUniqueId(INPUT_ID); + input.setName(INPUT_ID); + input.setValue("value"); + List resList = new ArrayList<>(); + when(componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(eq(resource), eq(INPUT_ID))).thenReturn(resList); + StorageOperationStatus status = testInstance.unDeclarePropertiesAsListInputs(resource, input); + Assert.assertEquals(status, StorageOperationStatus.OK); + } + private void verifyUpdatedProperties(List properties, List capturedInstanceProperties, List inputs) { assertThat(capturedInstanceProperties).hasSize(properties.size()); Map updatedPropertiesByName = MapUtil.toMap(capturedInstanceProperties, ComponentInstanceProperty::getName); @@ -204,4 +302,19 @@ public class ComponentInstancePropertyDeclaratorTest extends PropertyDeclaratorT assertThat(input.getInstanceUniqueId()).isEqualTo(INSTANCE_ID); } -} \ No newline at end of file + private Component createComponentWithListInput(String inputName, String propName) { + InputDefinition input = InputsBuilder.create() + .setName(inputName) + .build(); + + input.setUniqueId(INPUT_ID); + input.setName(INPUT_ID); + input.setDefaultValue("defaultValue"); + input.setValue(generateGetInputValueAsListInput(inputName, propName)); + + return new ResourceBuilder() + .setUniqueId(RESOURCE_ID) + .addInput(input) + .build(); + } +} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/ComponentPropertyDeclaratorTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/ComponentPropertyDeclaratorTest.java new file mode 100644 index 0000000000..7069fe84d7 --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/ComponentPropertyDeclaratorTest.java @@ -0,0 +1,175 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 Fujitsu Limited. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.components.property; + +import fj.data.Either; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic; +import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + + +@RunWith(MockitoJUnitRunner.class) +public class ComponentPropertyDeclaratorTest extends PropertyDeclaratorTestBase { + + @InjectMocks + private ComponentPropertyDeclarator testInstance; + @Mock + private PropertyBusinessLogic propertyBusinessLogic; + @Mock + private PropertyOperation propertyOperation; + @Mock + private ToscaOperationFacade toscaOperationFacade; + + @Test + public void unDeclarePropertiesAsListInputsTest_whenPropertyUsedByOperation() { + InputDefinition input = new InputDefinition(); + input.setUniqueId(INPUT_ID); + input.setName(INPUT_ID); + input.setValue("value"); + + PropertyDefinition propertyDefinition = new PropertyDefinition(input); + + when(propertyBusinessLogic.isPropertyUsedByOperation(eq(resource), eq(propertyDefinition))).thenReturn(true); + StorageOperationStatus status = testInstance.unDeclarePropertiesAsListInputs(resource, input); + Assert.assertEquals(status, StorageOperationStatus.DECLARED_INPUT_USED_BY_OPERATION); + } + + @Test + public void unDeclarePropertiesAsListInputsTest_whenNotPresentPropertyToUpdateCandidate() { + InputDefinition input = new InputDefinition(); + input.setUniqueId(INPUT_ID); + input.setName(INPUT_ID); + input.setValue("value"); + + PropertyDefinition propertyDefinition = new PropertyDefinition(); + resource.setProperties(Collections.singletonList(propertyDefinition)); + + when(propertyBusinessLogic.isPropertyUsedByOperation(eq(resource), any(PropertyDefinition.class))).thenReturn(false); + StorageOperationStatus status = testInstance.unDeclarePropertiesAsListInputs(resource, input); + Assert.assertEquals(status, StorageOperationStatus.OK); + } + + @Test + public void unDeclarePropertiesAsListInputsTest_whenPropertiesEmpty() { + InputDefinition input = new InputDefinition(); + input.setUniqueId(INPUT_ID); + input.setName(INPUT_ID); + input.setValue("value"); + + resource.setProperties(new ArrayList<>()); + + when(propertyBusinessLogic.isPropertyUsedByOperation(eq(resource), any(PropertyDefinition.class))).thenReturn(false); + StorageOperationStatus status = testInstance.unDeclarePropertiesAsListInputs(resource, input); + Assert.assertEquals(status, StorageOperationStatus.OK); + } + + @Test + public void unDeclarePropertiesAsListInputsTest_whenPropertiesToUpdateIsEmpty() { + InputDefinition input = new InputDefinition(); + input.setUniqueId(INPUT_ID); + input.setName(INPUT_ID); + input.setValue("value"); + + PropertyDefinition propertyDefinition = new PropertyDefinition(input); + resource.setProperties(Collections.singletonList(propertyDefinition)); + + when(propertyBusinessLogic.isPropertyUsedByOperation(eq(resource), eq(propertyDefinition))).thenReturn(false); + StorageOperationStatus status = testInstance.unDeclarePropertiesAsListInputs(resource, input); + Assert.assertEquals(status, StorageOperationStatus.OK); + } + + @Test + public void unDeclarePropertiesAsListInputsTest_singleProperty() { + InputDefinition input = new InputDefinition(); + input.setUniqueId(INPUT_ID); + input.setName(INPUT_ID); + input.setValue("value"); + input.setDefaultValue("default value"); + + PropertyDefinition propertyDefinition = new PropertyDefinition(input); + List getInputValueList = new ArrayList<>(); + getInputValueList.add(buildGetInputValue(INPUT_ID)); + getInputValueList.add(buildGetInputValue("otherInputId")); + propertyDefinition.setGetInputValues(getInputValueList); + propertyDefinition.setUniqueId("propertyId"); + propertyDefinition.setDefaultValue("default value"); + propertyDefinition.setValue(generateGetInputValueAsListInput(INPUT_ID, "innerPropName")); + resource.setProperties(Collections.singletonList(propertyDefinition)); + + when(propertyBusinessLogic.isPropertyUsedByOperation(eq(resource), any())).thenReturn(false); + when(propertyOperation.findDefaultValueFromSecondPosition(eq(Collections.emptyList()), eq(propertyDefinition.getUniqueId()), eq(propertyDefinition.getDefaultValue()))).thenReturn(Either.left(propertyDefinition.getDefaultValue())); + when(toscaOperationFacade.updatePropertyOfComponent(eq(resource), any())).thenReturn(Either.left(propertyDefinition)); + StorageOperationStatus status = testInstance.unDeclarePropertiesAsListInputs(resource, input); + Assert.assertEquals(status, StorageOperationStatus.OK); + } + + @Test + public void unDeclarePropertiesAsListInputsTest_UnDeclareInputFail() { + InputDefinition input = new InputDefinition(); + input.setUniqueId(INPUT_ID); + input.setName(INPUT_ID); + input.setValue("value"); + input.setDefaultValue("default value"); + + PropertyDefinition propertyDefinition = new PropertyDefinition(input); + List getInputValueList = new ArrayList<>(); + getInputValueList.add(buildGetInputValue(INPUT_ID)); + getInputValueList.add(buildGetInputValue("otherInputId")); + propertyDefinition.setGetInputValues(getInputValueList); + propertyDefinition.setUniqueId("propertyId"); + propertyDefinition.setDefaultValue("default value"); + propertyDefinition.setValue(generateGetInputValueAsListInput(INPUT_ID, "innerPropName")); + resource.setProperties(Collections.singletonList(propertyDefinition)); + + when(propertyBusinessLogic.isPropertyUsedByOperation(eq(resource), any())).thenReturn(false); + when(propertyOperation.findDefaultValueFromSecondPosition(eq(Collections.emptyList()), eq(propertyDefinition.getUniqueId()), eq(propertyDefinition.getDefaultValue()))).thenReturn(Either.left(propertyDefinition.getDefaultValue())); + when(toscaOperationFacade.updatePropertyOfComponent(eq(resource), any())).thenReturn(Either.right(StorageOperationStatus.NOT_FOUND)); + StorageOperationStatus status = testInstance.unDeclarePropertiesAsListInputs(resource, input); + Assert.assertEquals(status, StorageOperationStatus.NOT_FOUND); + } + + private GetInputValueDataDefinition buildGetInputValue(String InputId) { + GetInputValueDataDefinition getInputValue = new GetInputValueDataDefinition(); + getInputValue.setInputId(InputId); + getInputValue.setInputName(InputId); + + return getInputValue; + } + +} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/GroupPropertyDeclaratorTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/GroupPropertyDeclaratorTest.java index 63e39b5e61..72706db606 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/GroupPropertyDeclaratorTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/GroupPropertyDeclaratorTest.java @@ -136,6 +136,56 @@ public class GroupPropertyDeclaratorTest extends PropertyDeclaratorTestBase { assertThat(updatedProperty.getUniqueId()).isEqualTo(getInputPropForInput.getUniqueId()); } + @Test + public void testUnDeclarePropertiesAsListInputs_whenComponentHasNoGroups_returnOk() { + Resource resource = new Resource(); + StorageOperationStatus storageOperationStatus = groupPropertyDeclarator.unDeclarePropertiesAsListInputs(resource, input); + assertThat(storageOperationStatus).isEqualTo(StorageOperationStatus.OK); + verifyZeroInteractions(groupOperation); + } + + @Test + public void testUnDeclarePropertiesAsListInputs_whenNoPropertiesFromGroupMatchInputId_returnOk() { + StorageOperationStatus storageOperationStatus = groupPropertyDeclarator.unDeclarePropertiesAsListInputs(createResourceWithGroup(), input); + assertThat(storageOperationStatus).isEqualTo(StorageOperationStatus.OK); + verifyZeroInteractions(groupOperation); + } + + @Test + public void whenFailingToUpdateDeclaredPropertiesAsListInputs_returnErrorStatus() { + Resource resource = createResourceWithGroups(GROUP_ID); + Optional groupDefinition = resource.getGroupById(GROUP_ID); + assertThat(groupDefinition.isPresent()).isTrue(); + PropertyDataDefinition getInputPropForInput = buildGetInputProperty(INPUT_ID); + groupDefinition.get().setProperties(Collections.singletonList(getInputPropForInput)); + when(propertyOperation.findDefaultValueFromSecondPosition(Collections.emptyList(), getInputPropForInput.getUniqueId(), getInputPropForInput.getDefaultValue())).thenReturn(Either.left(getInputPropForInput.getDefaultValue())); + when(groupOperation.updateGroupProperties(eq(resource), eq(GROUP_ID), updatedPropsCapture.capture())).thenReturn(StorageOperationStatus.GENERAL_ERROR); + StorageOperationStatus storageOperationStatus = groupPropertyDeclarator.unDeclarePropertiesAsListInputs(resource, input); + assertThat(storageOperationStatus).isEqualTo(StorageOperationStatus.GENERAL_ERROR); + } + + @Test + public void testUnDeclarePropertiesAsListInputs_propertiesUpdatedCorrectly() { + Resource resource = createResourceWithGroups(GROUP_ID, "groupId3"); + Optional groupDefinition = resource.getGroupById(GROUP_ID); + PropertyDataDefinition getInputPropForInput = buildGetInputProperty(INPUT_ID); + PropertyDataDefinition someOtherProperty = new PropertyDataDefinitionBuilder().build(); + groupDefinition.get().setProperties(Arrays.asList(getInputPropForInput, someOtherProperty)); + + when(propertyOperation.findDefaultValueFromSecondPosition(Collections.emptyList(), getInputPropForInput.getUniqueId(), getInputPropForInput.getDefaultValue())).thenReturn(Either.left(getInputPropForInput.getDefaultValue())); + when(groupOperation.updateGroupProperties(eq(resource), eq(GROUP_ID), updatedPropsCapture.capture())).thenReturn(StorageOperationStatus.OK); + StorageOperationStatus storageOperationStatus = groupPropertyDeclarator.unDeclarePropertiesAsListInputs(resource, input); + + assertThat(storageOperationStatus).isEqualTo(StorageOperationStatus.OK); + List updatedProperties = updatedPropsCapture.getValue(); + assertThat(updatedProperties).hasSize(1); + PropertyDataDefinition updatedProperty = updatedProperties.get(0); + assertThat(updatedProperty.isGetInputProperty()).isFalse(); + assertThat(updatedProperty.getValue()).isEmpty(); + assertThat(updatedProperty.getDefaultValue()).isEqualTo(getInputPropForInput.getDefaultValue()); + assertThat(updatedProperty.getUniqueId()).isEqualTo(getInputPropForInput.getUniqueId()); + } + private Resource createResourceWithGroup() { return createResourceWithGroups(GROUP_ID); } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PolicyPropertyDeclaratorTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PolicyPropertyDeclaratorTest.java index 72c26541f1..f85388a06b 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PolicyPropertyDeclaratorTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PolicyPropertyDeclaratorTest.java @@ -134,6 +134,55 @@ public class PolicyPropertyDeclaratorTest extends PropertyDeclaratorTestBase { assertThat(updatedProperty.getUniqueId()).isEqualTo(getInputPropForInput.getUniqueId()); } + @Test + public void testUnDeclarePropertiesAsListInputs_whenComponentHasNoPolicies_returnOk() { + Resource resource = new Resource(); + StorageOperationStatus storageOperationStatus = policyPropertyDeclarator.unDeclarePropertiesAsListInputs(resource, input); + assertThat(storageOperationStatus).isEqualTo(StorageOperationStatus.OK); + verifyZeroInteractions(policyOperation); + } + + @Test + public void testUnDeclarePropertiesAsListInputs_whenNoPropertiesFromPolicyMatchInputId_returnOk() { + StorageOperationStatus storageOperationStatus = policyPropertyDeclarator.unDeclarePropertiesAsListInputs(createResourceWithPolicy(), input); + assertThat(storageOperationStatus).isEqualTo(StorageOperationStatus.OK); + verifyZeroInteractions(policyOperation); + } + + @Test + public void whenFailingToUpdateDeclaredPropertiesAsListInputs_returnErrorStatus() { + Resource resource = createResourceWithPolicies(POLICY_ID); + PolicyDefinition policyDefinition = resource.getPolicies().get(POLICY_ID); + PropertyDataDefinition getInputPropForInput = buildGetInputProperty(INPUT_ID); + policyDefinition.setProperties(Collections.singletonList(getInputPropForInput)); + when(propertyOperation.findDefaultValueFromSecondPosition(Collections.emptyList(), getInputPropForInput.getUniqueId(), getInputPropForInput.getDefaultValue())).thenReturn(Either.left(getInputPropForInput.getDefaultValue())); + when(policyOperation.updatePolicyProperties(eq(resource), eq(POLICY_ID), updatedPropsCapture.capture())).thenReturn(StorageOperationStatus.GENERAL_ERROR); + StorageOperationStatus storageOperationStatus = policyPropertyDeclarator.unDeclarePropertiesAsListInputs(resource, input); + assertThat(storageOperationStatus).isEqualTo(StorageOperationStatus.GENERAL_ERROR); + } + + @Test + public void testUnDeclarePropertiesAsListInputs_propertiesUpdatedCorrectly() { + Resource resource = createResourceWithPolicies(POLICY_ID, "policyId3"); + PolicyDefinition policyDefinition = resource.getPolicies().get(POLICY_ID); + PropertyDataDefinition getInputPropForInput = buildGetInputProperty(INPUT_ID); + PropertyDataDefinition someOtherProperty = new PropertyDataDefinitionBuilder().build(); + policyDefinition.setProperties(Arrays.asList(getInputPropForInput, someOtherProperty)); + + when(propertyOperation.findDefaultValueFromSecondPosition(Collections.emptyList(), getInputPropForInput.getUniqueId(), getInputPropForInput.getDefaultValue())).thenReturn(Either.left(getInputPropForInput.getDefaultValue())); + when(policyOperation.updatePolicyProperties(eq(resource), eq(POLICY_ID), updatedPropsCapture.capture())).thenReturn(StorageOperationStatus.OK); + StorageOperationStatus storageOperationStatus = policyPropertyDeclarator.unDeclarePropertiesAsListInputs(resource, input); + + assertThat(storageOperationStatus).isEqualTo(StorageOperationStatus.OK); + List updatedProperties = updatedPropsCapture.getValue(); + assertThat(updatedProperties).hasSize(1); + PropertyDataDefinition updatedProperty = updatedProperties.get(0); + assertThat(updatedProperty.isGetInputProperty()).isFalse(); + assertThat(updatedProperty.getValue()).isEmpty(); + assertThat(updatedProperty.getDefaultValue()).isEqualTo(getInputPropForInput.getDefaultValue()); + assertThat(updatedProperty.getUniqueId()).isEqualTo(getInputPropForInput.getUniqueId()); + } + private Resource createResourceWithPolicy() { return createResourceWithPolicies(POLICY_ID); } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PropertyDecelerationOrchestratorTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PropertyDecelerationOrchestratorTest.java index 1a2a76e433..ef1d45dbaa 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PropertyDecelerationOrchestratorTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PropertyDecelerationOrchestratorTest.java @@ -4,23 +4,32 @@ import fj.data.Either; import mockit.Deencapsulation; import org.junit.Before; import org.junit.Test; +import org.mockito.Answers; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -import org.openecomp.sdc.be.model.*; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstInputsMap; +import org.openecomp.sdc.be.model.ComponentInstancePropInput; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; -import java.util.*; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; public class PropertyDecelerationOrchestratorTest { @InjectMocks PropertyDeclarationOrchestrator testSubject; - @Mock + @Mock(answer = Answers.CALLS_REAL_METHODS) List propertyDeceleratorsMock; - + @Mock private ComponentInstanceInputPropertyDeclarator componentInstanceInputPropertyDecelerator; @Mock @@ -44,6 +53,21 @@ public class PropertyDecelerationOrchestratorTest { result = testSubject.declarePropertiesToInputs(component, componentInstInputsMap); } + @Test + public void testDeclarePropertiesToListInputs() throws Exception { + Component component = new Resource(); + ComponentInstInputsMap componentInstInputsMap = new ComponentInstInputsMap(); + Map> componentInstanceInputsMap = new HashMap<>(); + List value = new LinkedList<>(); + componentInstanceInputsMap.put("mock", value); + componentInstInputsMap.setComponentInstanceInputsMap(componentInstanceInputsMap); + InputDefinition input = new InputDefinition(); + Either result; + + // default test + result = testSubject.declarePropertiesToListInput(component, componentInstInputsMap, input); + } + @Test public void testUnDeclarePropertiesAsInputs() throws Exception { Component component = new Resource(); @@ -58,6 +82,33 @@ public class PropertyDecelerationOrchestratorTest { result = testSubject.unDeclarePropertiesAsInputs(component, inputToDelete); } + @Test + public void testUnDeclarePropertiesAsListInputs() throws Exception { + Component component = new Resource(); + InputDefinition inputToDelete = new InputDefinition(); + StorageOperationStatus result; + + Iterator mockIter = Mockito.mock(Iterator.class); + Mockito.when(propertyDeceleratorsMock.iterator()).thenReturn(mockIter); + Mockito.when(mockIter.hasNext()).thenReturn(false); + + // default test + result = testSubject.unDeclarePropertiesAsListInputs(component, inputToDelete); + } + + @Test + public void testGetPropOwnerId() throws Exception { + ComponentInstInputsMap componentInstInputsMap = new ComponentInstInputsMap(); + Map> componentInstanceInputsMap = new HashMap<>(); + List value = new LinkedList<>(); + componentInstanceInputsMap.put("mock", value); + componentInstInputsMap.setComponentInstanceInputsMap(componentInstanceInputsMap); + String result; + + // default test + result = Deencapsulation.invoke(testSubject, "getPropOwnerId", componentInstInputsMap); + } + @Test(expected = IllegalStateException.class) public void testGetPropertyDecelerator() throws Exception { ComponentInstInputsMap componentInstInputsMap = new ComponentInstInputsMap(); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PropertyDeclaratorTestBase.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PropertyDeclaratorTestBase.java index bd21f683ad..f1f4d0aac7 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PropertyDeclaratorTestBase.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/PropertyDeclaratorTestBase.java @@ -77,6 +77,10 @@ public class PropertyDeclaratorTestBase { return String.format("{\"%s\":\"%s\"}", GET_INPUT, value); } + String generateGetInputValueAsListInput(String inputName, String inputProperty) { + return String.format("{\"%s\":[\"%s\",\"INDEX\",\"%s\"]}", GET_INPUT, inputName, inputProperty); + } + private void verifyInputPropertiesList(PropertyDataDefinition updatedProperty, InputDefinition input) { assertThat(input.getProperties()).hasSize(1); assertThat(new ComponentInstanceProperty(updatedProperty)).isEqualTo(input.getProperties().get(0)); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/datamodel/UiComponentDataConverterTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/datamodel/UiComponentDataConverterTest.java index eb123771a9..3922dd8de7 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/datamodel/UiComponentDataConverterTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/datamodel/UiComponentDataConverterTest.java @@ -218,14 +218,16 @@ public class UiComponentDataConverterTest { public void getUiDataTransferFromResourceByParams_policies() { Resource resourceWithPolicies = buildResourceWithPolicies(); UiComponentDataTransfer componentDTO = uiComponentDataConverter.getUiDataTransferFromResourceByParams(resourceWithPolicies, Collections.singletonList("policies")); - assertThat(componentDTO.getPolicies()).isEqualTo(resourceWithPolicies.resolvePoliciesList()); + List expectedPolicies = resourceWithPolicies.resolvePoliciesList(); + assertThat(componentDTO.getPolicies()).containsExactlyInAnyOrder((PolicyDefinition[]) expectedPolicies.toArray(new PolicyDefinition[expectedPolicies.size()])); } @Test public void getUiDataTransferFromServiceByParams_policies() { Service resourceWithPolicies = buildServiceWithPolicies(); UiComponentDataTransfer componentDTO = uiComponentDataConverter.getUiDataTransferFromServiceByParams(resourceWithPolicies, Collections.singletonList("policies")); - assertThat(componentDTO.getPolicies()).isEqualTo(resourceWithPolicies.resolvePoliciesList()); + List expectedPolicies = resourceWithPolicies.resolvePoliciesList(); + assertThat(componentDTO.getPolicies()).containsExactlyInAnyOrder((PolicyDefinition[]) expectedPolicies.toArray(new PolicyDefinition[expectedPolicies.size()])); } @Test diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/InputsServletTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/InputsServletTest.java index 9ff55c22f0..07184704d4 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/InputsServletTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/InputsServletTest.java @@ -1,166 +1,437 @@ -package org.openecomp.sdc.be.servlets; +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 Fujitsu Limited. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.core.Response; +package org.openecomp.sdc.be.servlets; +import fj.data.Either; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.grizzly.http.util.HttpStatus; +import org.junit.Before; import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.openecomp.sdc.be.components.impl.DataTypeBusinessLogic; import org.openecomp.sdc.be.components.impl.InputsBusinessLogic; +import org.openecomp.sdc.be.components.utils.PropertyDataDefinitionBuilder; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; import org.openecomp.sdc.be.model.ComponentInstInputsMap; +import org.openecomp.sdc.be.model.ComponentInstListInput; +import org.openecomp.sdc.be.model.ComponentInstancePropInput; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.exception.ResponseFormat; +import org.springframework.web.context.WebApplicationContext; -import fj.data.Either; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpSession; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +public class InputsServletTest extends JerseySpringBaseTest { + + /* Constants */ + private static final String RESOURCE_ID = "serviceId"; + private static final String USER_ID = "userId"; + private static final String COMPONENT_INSTANCE_ID = "instanceId"; + private static final String COMPONENT_ID = "componentId"; + private static final String INSTANCE_INPUT_ID = "inputId"; + private static final String LISTINPUT_NAME = "listInput"; + private static final String LISTINPUT_SCHEMA_TYPE = "org.onap.datatypes.listinput"; + private static final String LISTINPUT_PROP1_NAME = "prop1"; + private static final String LISTINPUT_PROP1_TYPE = "string"; + private static final String LISTINPUT_PROP2_NAME = "prop2"; + private static final String LISTINPUT_PROP2_TYPE = "integer"; + + /* Test subject */ + private InputsServletForTest testSubject; + + /* Mocks */ + private InputsBusinessLogic inputsBusinessLogic; + private DataTypeBusinessLogic dataTypeBusinessLogic; + private HttpSession httpSession; + private ServletContext servletContext; + private WebApplicationContext webApplicationContext; + private ComponentsUtils componentsUtils; + private ServletUtils servletUtils; + + /** + * This class extends the original InputsServlet + * and provides methods to inject mocks + */ + class InputsServletForTest extends InputsServlet { + public void setComponentsUtils(ComponentsUtils componentsUtils) { + this.componentsUtils = componentsUtils; + } + + public void setServletUtils(ServletUtils servletUtils) { + this.servletUtils = servletUtils; + } + } + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + inputsBusinessLogic = mock(InputsBusinessLogic.class); + dataTypeBusinessLogic = mock(DataTypeBusinessLogic.class); + servletContext = mock(ServletContext.class); + httpSession = mock(HttpSession.class); + webApplicationContext = mock(WebApplicationContext.class); + componentsUtils = mock(ComponentsUtils.class); + servletUtils = mock(ServletUtils.class); + when(request.getSession()).thenReturn(httpSession); + when(httpSession.getServletContext()).thenReturn(servletContext); + when(servletContext.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR)).thenReturn(new WebAppContextWrapper()); + when(servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)).thenReturn(webApplicationContext); + when(webApplicationContext.getBean(InputsBusinessLogic.class)).thenReturn(inputsBusinessLogic); + when(webApplicationContext.getBean(DataTypeBusinessLogic.class)).thenReturn(dataTypeBusinessLogic); + testSubject.setComponentsUtils(componentsUtils); + testSubject.setServletUtils(servletUtils); + when(servletUtils.getComponentsUtils()).thenReturn(componentsUtils); + } + + + @Override + protected ResourceConfig configure() { + testSubject = new InputsServletForTest(); + return super.configure().register(testSubject); + } + + + private InputDefinition setUpListInput() { + InputDefinition listInput = new InputDefinition(); + listInput.setName(LISTINPUT_NAME); + listInput.setType("list"); + SchemaDefinition listInputSchema = new SchemaDefinition(); + listInputSchema.setProperty(new PropertyDataDefinitionBuilder() + .setType(LISTINPUT_SCHEMA_TYPE) + .setIsRequired(false) + .build() + ); + listInput.setSchema(listInputSchema); + return listInput; + } + + private ComponentInstListInput setUpCreateListInputParams() { + ComponentInstListInput componentInstListInput = new ComponentInstListInput(); + + // Create a "list input" + InputDefinition listInput = setUpListInput(); + componentInstListInput.setListInput(listInput); + + // Create ComponentInstancePropInputs + // for inputs in the ComponentInstance + Map> propInputsListMap = new HashMap<>(); + // Add 2 PropInputs. property owner is COMPONENT_INSTANCE_ID + List propInputsList = new ArrayList<>(); + ComponentInstancePropInput propInput = new ComponentInstancePropInput(); + propInput.setName(LISTINPUT_PROP1_NAME); + propInput.setType(LISTINPUT_PROP1_TYPE); + propInput.setUniqueId(COMPONENT_INSTANCE_ID + "." + LISTINPUT_PROP1_NAME); + propInputsList.add(propInput); + propInput = new ComponentInstancePropInput(); + propInput.setName(LISTINPUT_PROP2_NAME); + propInput.setType(LISTINPUT_PROP2_TYPE); + propInput.setUniqueId(COMPONENT_INSTANCE_ID + "." + LISTINPUT_PROP2_NAME); + propInputsList.add(propInput); + propInputsListMap.put(COMPONENT_INSTANCE_ID, propInputsList); + ComponentInstInputsMap componentInstInputsMap = new ComponentInstInputsMap(); + componentInstInputsMap.setComponentInstanceInputsMap(propInputsListMap); + componentInstListInput.setComponentInstInputsMap(componentInstInputsMap); + + return componentInstListInput; + } + + @Test + public void test_createListInput_success() throws Exception { + ComponentInstListInput requestBodyObj = setUpCreateListInputParams(); + Entity entity = Entity.entity(requestBodyObj, MediaType.APPLICATION_JSON); + + // for parseToComponentInstListInput + when(componentsUtils.convertJsonToObjectUsingObjectMapper(any(), any(), eq(ComponentInstListInput.class), + eq(AuditingActionEnum.CREATE_RESOURCE), eq(ComponentTypeEnum.SERVICE))) + .thenReturn(Either.left(requestBodyObj)); + + when(inputsBusinessLogic.createListInput(eq(USER_ID), eq(RESOURCE_ID), eq(ComponentTypeEnum.SERVICE), + any(), eq(true), eq(false))) + .thenReturn(Either.left(Collections.emptyList())); + when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(new ResponseFormat(HttpStatus.OK_200.getStatusCode())); + + Response response = buildCreateListInputCall().post(entity); + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200.getStatusCode()); + verify(inputsBusinessLogic, times(1)).createListInput(USER_ID, RESOURCE_ID, + ComponentTypeEnum.SERVICE, requestBodyObj, true, false); + } + + @Test + public void test_createListInput_fail_parse() throws Exception { + ComponentInstListInput requestBodyObj = setUpCreateListInputParams(); + Entity entity = Entity.entity(requestBodyObj, MediaType.APPLICATION_JSON); + + // for parseToComponentInstListInput + ArgumentCaptor userCaptor = ArgumentCaptor.forClass(User.class); + when(componentsUtils.convertJsonToObjectUsingObjectMapper(any(), userCaptor.capture(), eq(ComponentInstListInput.class), + eq(AuditingActionEnum.CREATE_RESOURCE), eq(ComponentTypeEnum.SERVICE))) + .thenReturn(Either.right(new ResponseFormat(HttpStatus.BAD_REQUEST_400.getStatusCode()))); + + when(inputsBusinessLogic.createListInput(eq(USER_ID), eq(RESOURCE_ID), eq(ComponentTypeEnum.SERVICE), + any(), eq(true), eq(false))) + .thenReturn(Either.left(Collections.emptyList())); + + Response response = buildCreateListInputCall().post(entity); + assertThat(response.getStatus()).isEqualTo(HttpStatus.BAD_REQUEST_400.getStatusCode()); + verify(componentsUtils, times(1)) + .convertJsonToObjectUsingObjectMapper(any(), any(), eq(ComponentInstListInput.class), + eq(AuditingActionEnum.CREATE_RESOURCE), eq(ComponentTypeEnum.SERVICE)); + assertThat(userCaptor.getValue().getUserId()).isEqualTo(USER_ID); + verify(inputsBusinessLogic, never()).createListInput(USER_ID, RESOURCE_ID, + ComponentTypeEnum.SERVICE, requestBodyObj, true, false); + } + + + @Test + public void test_createListInput_fail_createInput() throws Exception { + ComponentInstListInput requestBodyObj = setUpCreateListInputParams(); + Entity entity = Entity.entity(requestBodyObj, MediaType.APPLICATION_JSON); + + // for parseToComponentInstListInput + ArgumentCaptor userCaptor = ArgumentCaptor.forClass(User.class); + when(componentsUtils.convertJsonToObjectUsingObjectMapper(any(), userCaptor.capture(), eq(ComponentInstListInput.class), + eq(AuditingActionEnum.CREATE_RESOURCE), eq(ComponentTypeEnum.SERVICE))) + .thenReturn(Either.left(requestBodyObj)); + + when(inputsBusinessLogic.createListInput(eq(USER_ID), eq(RESOURCE_ID), eq(ComponentTypeEnum.SERVICE), + any(), eq(true), eq(false))) + .thenReturn(Either.right(new ResponseFormat(HttpStatus.BAD_REQUEST_400.getStatusCode()))); + + Response response = buildCreateListInputCall().post(entity); + assertThat(response.getStatus()).isEqualTo(HttpStatus.BAD_REQUEST_400.getStatusCode()); + verify(inputsBusinessLogic, times(1)) + .createListInput(eq(USER_ID), eq(RESOURCE_ID), eq(ComponentTypeEnum.SERVICE), + any(), eq(true), eq(false)); + } + + + @Test + public void test_createListInput_fail_exception() throws Exception { + ComponentInstListInput requestBodyObj = setUpCreateListInputParams(); + Entity entity = Entity.entity(requestBodyObj, MediaType.APPLICATION_JSON); + + when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(new ResponseFormat(HttpStatus.BAD_REQUEST_400.getStatusCode())); + + Response response = buildCreateListInputCall().post(entity); + assertThat(response.getStatus()).isEqualTo(HttpStatus.BAD_REQUEST_400.getStatusCode()); + } + + @Test + public void test_getDataType_success() throws Exception { + when(dataTypeBusinessLogic.getPrivateDataType(eq(RESOURCE_ID),eq(LISTINPUT_SCHEMA_TYPE))).thenReturn(Either.left(new DataTypeDefinition())); + + ResponseFormat responseFormat = new ResponseFormat(); + responseFormat.setStatus(HttpStatus.OK_200.getStatusCode()); + when(componentsUtils.getResponseFormat(eq(ActionStatus.OK))).thenReturn(responseFormat); + + Response response = buildGetDataTypeCall().get(); + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200.getStatusCode()); + } + + @Test + public void test_getDataType_fail() throws Exception { + when(dataTypeBusinessLogic.getPrivateDataType(eq(RESOURCE_ID),eq(LISTINPUT_SCHEMA_TYPE))).thenReturn(Either.right(StorageOperationStatus.BAD_REQUEST)); + + ResponseFormat responseFormat = new ResponseFormat(); + responseFormat.setStatus(HttpStatus.INTERNAL_SERVER_ERROR_500.getStatusCode()); + when(componentsUtils.convertFromStorageResponse(eq(StorageOperationStatus.BAD_REQUEST))).thenReturn(ActionStatus.GENERAL_ERROR); + when(componentsUtils.getResponseFormat(eq(ActionStatus.GENERAL_ERROR))).thenReturn(responseFormat); + + Response response = buildGetDataTypeCall().get(); + assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500.getStatusCode()); + } + + @Test + public void test_getDataType_fail_exception() throws Exception { + when(dataTypeBusinessLogic.getPrivateDataType(eq(RESOURCE_ID),eq(LISTINPUT_SCHEMA_TYPE))).thenReturn(Either.right(StorageOperationStatus.BAD_REQUEST)); + when(componentsUtils.getResponseFormat(eq(ActionStatus.GENERAL_ERROR))).thenReturn(new ResponseFormat(HttpStatus.BAD_REQUEST_400.getStatusCode())); + + Response response = buildGetDataTypeCall().get(); + assertThat(response.getStatus()).isEqualTo(HttpStatus.BAD_REQUEST_400.getStatusCode()); + } + + @Test + public void test_getDataTypes_success() throws Exception { + when(dataTypeBusinessLogic.getPrivateDataTypes(eq(RESOURCE_ID))).thenReturn(Either.left(Collections.emptyList())); + + ResponseFormat responseFormat = new ResponseFormat(); + responseFormat.setStatus(HttpStatus.OK_200.getStatusCode()); + when(componentsUtils.getResponseFormat(eq(ActionStatus.OK))).thenReturn(responseFormat); + + Response response = buildGetDataTypesCall().get(); + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200.getStatusCode()); + } + + @Test + public void test_getDataTypes_fail() throws Exception { + when(dataTypeBusinessLogic.getPrivateDataTypes(eq(RESOURCE_ID))).thenReturn(Either.right(StorageOperationStatus.BAD_REQUEST)); + + ResponseFormat responseFormat = new ResponseFormat(); + responseFormat.setStatus(HttpStatus.INTERNAL_SERVER_ERROR_500.getStatusCode()); + when(componentsUtils.convertFromStorageResponse(eq(StorageOperationStatus.BAD_REQUEST))).thenReturn(ActionStatus.GENERAL_ERROR); + when(componentsUtils.getResponseFormat(eq(ActionStatus.GENERAL_ERROR))).thenReturn(responseFormat); + + Response response = buildGetDataTypesCall().get(); + assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500.getStatusCode()); + } + + @Test + public void test_getDataTypes_fail_exception() throws Exception { + when(dataTypeBusinessLogic.getPrivateDataType(eq(RESOURCE_ID),eq(LISTINPUT_SCHEMA_TYPE))).thenReturn(Either.right(StorageOperationStatus.BAD_REQUEST)); + when(componentsUtils.getResponseFormat(eq(ActionStatus.GENERAL_ERROR))).thenReturn(new ResponseFormat(HttpStatus.BAD_REQUEST_400.getStatusCode())); + + Response response = buildGetDataTypesCall().get(); + assertThat(response.getStatus()).isEqualTo(HttpStatus.BAD_REQUEST_400.getStatusCode()); + } + + + @Test + public void test_deleteDataType_success() throws Exception { + when(dataTypeBusinessLogic.deletePrivateDataType(RESOURCE_ID, LISTINPUT_SCHEMA_TYPE)).thenReturn(Either.left(new DataTypeDefinition())); + + when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(new ResponseFormat(HttpStatus.OK_200.getStatusCode())); + + Response response = buildGetDataTypeCall().delete(); + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200.getStatusCode()); + } + + @Test + public void test_deleteDataType_failure_exception() throws Exception { + when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(new ResponseFormat(HttpStatus.OK_200.getStatusCode())); + when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(new ResponseFormat(HttpStatus.INTERNAL_SERVER_ERROR_500.getStatusCode())); + Response response = buildGetDataTypeCall().delete(); + assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500.getStatusCode()); + verify(componentsUtils, never()).getResponseFormat(ActionStatus.OK); + } + + @Test + public void test_deleteDataType_failure_notFound() throws Exception { + when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(new ResponseFormat(HttpStatus.OK_200.getStatusCode())); + when(dataTypeBusinessLogic.deletePrivateDataType(RESOURCE_ID, LISTINPUT_SCHEMA_TYPE)).thenReturn(Either.right(StorageOperationStatus.NOT_FOUND)); + when(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND)).thenReturn(ActionStatus.ARTIFACT_NOT_FOUND); + when(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND)).thenReturn(new ResponseFormat(HttpStatus.NOT_FOUND_404.getStatusCode())); + Response response = buildGetDataTypeCall().delete(); + assertThat(response.getStatus()).isEqualTo(HttpStatus.NOT_FOUND_404.getStatusCode()); + verify(componentsUtils, never()).getResponseFormat(ActionStatus.OK); + } + + @Test + public void test_deleteInput_success() throws Exception { + when(inputsBusinessLogic.deleteInput(RESOURCE_ID, USER_ID, LISTINPUT_NAME)) + .thenReturn(Either.left(new InputDefinition())); + when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(new ResponseFormat(HttpStatus.OK_200.getStatusCode())); + + // invoke delete call + Response response = target("/v1/catalog/services/{id}/delete/{inputId}/input") + .resolveTemplate("id", RESOURCE_ID) + .resolveTemplate("inputId", LISTINPUT_NAME) + .request(MediaType.APPLICATION_JSON) + .header(Constants.USER_ID_HEADER, USER_ID) + .delete(); + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200.getStatusCode()); + verify(inputsBusinessLogic, times(1)).deleteInput(RESOURCE_ID, USER_ID, LISTINPUT_NAME); + } + + + @Test + public void test_deleteInput_failure_deleteInput() throws Exception { + when(inputsBusinessLogic.deleteInput(RESOURCE_ID, USER_ID, LISTINPUT_NAME)) + .thenReturn(Either.right(new ResponseFormat(HttpStatus.BAD_REQUEST_400.getStatusCode()))); + when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(new ResponseFormat(HttpStatus.OK_200.getStatusCode())); + + // invoke delete call + Response response = target("/v1/catalog/services/{id}/delete/{inputId}/input") + .resolveTemplate("id", RESOURCE_ID) + .resolveTemplate("inputId", LISTINPUT_NAME) + .request(MediaType.APPLICATION_JSON) + .header(Constants.USER_ID_HEADER, USER_ID) + .delete(); + assertThat(response.getStatus()).isEqualTo(HttpStatus.BAD_REQUEST_400.getStatusCode()); + verify(componentsUtils, never()).getResponseFormat(ActionStatus.OK); + } + + + @Test + public void test_deleteInput_failure_exception() throws Exception { + when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(new ResponseFormat(HttpStatus.OK_200.getStatusCode())); + when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)).thenReturn(new ResponseFormat(HttpStatus.BAD_REQUEST_400.getStatusCode())); + + // invoke delete call + Response response = target("/v1/catalog/services/{id}/delete/{inputId}/input") + .resolveTemplate("id", RESOURCE_ID) + .resolveTemplate("inputId", LISTINPUT_NAME) + .request(MediaType.APPLICATION_JSON) + .header(Constants.USER_ID_HEADER, USER_ID) + .delete(); + assertThat(response.getStatus()).isEqualTo(HttpStatus.BAD_REQUEST_400.getStatusCode()); + verify(componentsUtils, never()).getResponseFormat(ActionStatus.OK); + } + + + private Invocation.Builder buildCreateListInputCall() { + return target("/v1/catalog/services/{id}/create/listInput") + .resolveTemplate("id", RESOURCE_ID) + .request(MediaType.APPLICATION_JSON) + .header(Constants.USER_ID_HEADER, USER_ID); + } + + private Invocation.Builder buildGetDataTypeCall() { + return target("/v1/catalog/services/{id}/dataType/{dataTypeName}") + .resolveTemplate("id", RESOURCE_ID) + .resolveTemplate("dataTypeName", LISTINPUT_SCHEMA_TYPE) + .request(MediaType.APPLICATION_JSON) + .header(Constants.USER_ID_HEADER, USER_ID); + } + + private Invocation.Builder buildGetDataTypesCall() { + return target("/v1/catalog/services/{id}/dataTypes") + .resolveTemplate("id", RESOURCE_ID) + .request(MediaType.APPLICATION_JSON) + .header(Constants.USER_ID_HEADER, USER_ID); + } -public class InputsServletTest { - - private InputsServlet createTestSubject() { - return new InputsServlet(); - } - - - @Test - public void testGetComponentInputs() throws Exception { - InputsServlet testSubject; - String componentType = ""; - String componentId = ""; - HttpServletRequest request = null; - String fromName = ""; - int amount = 0; - String userId = ""; - Response result; - - // default test - testSubject = createTestSubject(); - } - - - @Test - public void testUpdateComponentInputs() throws Exception { - InputsServlet testSubject; - String containerComponentType = ""; - String componentId = ""; - String data = ""; - HttpServletRequest request = null; - Response result; - - // default test - testSubject = createTestSubject(); - } - - - @Test - public void testGetComponentInstanceInputs() throws Exception { - InputsServlet testSubject; - String componentType = ""; - String componentId = ""; - String instanceId = ""; - String originComonentUid = ""; - HttpServletRequest request = null; - String userId = ""; - Response result; - - // default test - testSubject = createTestSubject(); - } - - - @Test - public void testGetInputPropertiesForComponentInstance() throws Exception { - InputsServlet testSubject; - String componentType = ""; - String componentId = ""; - String instanceId = ""; - String inputId = ""; - HttpServletRequest request = null; - String userId = ""; - Response result; - - // default test - testSubject = createTestSubject(); - } - - - @Test - public void testGetInputsForComponentInput() throws Exception { - InputsServlet testSubject; - String componentType = ""; - String componentId = ""; - String inputId = ""; - HttpServletRequest request = null; - String userId = ""; - Response result; - - // default test - testSubject = createTestSubject(); - } - - - @Test - public void testGetInputsAndPropertiesForComponentInput() throws Exception { - InputsServlet testSubject; - String componentType = ""; - String componentId = ""; - String inputId = ""; - HttpServletRequest request = null; - String userId = ""; - Response result; - - // default test - testSubject = createTestSubject(); - } - - - @Test - public void testParseToComponentInstanceMap() throws Exception { - InputsServlet testSubject; - String serviceJson = ""; - User user = null; - Either result; - - // default test - testSubject = createTestSubject(); - } - - - @Test - public void testCreateMultipleInputs() throws Exception { - InputsServlet testSubject; - String componentType = ""; - String componentId = ""; - HttpServletRequest request = null; - String userId = ""; - String componentInstInputsMapObj = ""; - Response result; - - // default test - testSubject = createTestSubject(); - } - - - @Test - public void testDeleteInput() throws Exception { - InputsServlet testSubject; - String componentType = ""; - String componentId = ""; - String inputId = ""; - HttpServletRequest request = null; - String userId = ""; - String componentInstInputsMapObj = ""; - Response result; - - // default test - testSubject = createTestSubject(); - } - - - @Test - public void testGetInputBL() throws Exception { - InputsServlet testSubject; - ServletContext context = null; - InputsBusinessLogic result; - - // default test - testSubject = createTestSubject(); - } -} \ No newline at end of file +} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/ToscaExportHandlerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/ToscaExportHandlerTest.java index d46d234595..78ed40a9e6 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/ToscaExportHandlerTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/ToscaExportHandlerTest.java @@ -1,12 +1,14 @@ package org.openecomp.sdc.be.tosca; +import fj.data.Either; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Supplier; - +import java.util.stream.Collectors; +import mockit.Deencapsulation; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Triple; import org.junit.Before; @@ -17,10 +19,12 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.openecomp.sdc.be.components.BeConfDependentTest; +import org.openecomp.sdc.be.components.utils.PropertyDataDefinitionBuilder; import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ForwardingPathElementDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; @@ -56,9 +60,6 @@ import org.openecomp.sdc.be.tosca.model.ToscaNodeType; import org.openecomp.sdc.be.tosca.model.ToscaTemplate; import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement; import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate; - -import fj.data.Either; -import mockit.Deencapsulation; import org.openecomp.sdc.be.tosca.utils.InputConverter; public class ToscaExportHandlerTest extends BeConfDependentTest { @@ -98,6 +99,20 @@ public class ToscaExportHandlerTest extends BeConfDependentTest { CategoryDefinition category = new CategoryDefinition(); List subcategories = new ArrayList<>(); SubCategoryDefinition subcategory = new SubCategoryDefinition(); + List dataTypes = new ArrayList<>(); + DataTypeDefinition dataType = new DataTypeDefinition(); + dataType.setName("dataTypeName"); + dataType.setDerivedFromName("tosca.datatypes.Root"); + PropertyDataDefinition propData = new PropertyDataDefinitionBuilder() + .setName("property") + .setType("type") + .build(); + List propDataList = Arrays.asList(propData); + dataType.setPropertiesData(propDataList); + List propList = propDataList.stream().map(PropertyDefinition::new) + .collect(Collectors.toList()); + dataType.setProperties(propList); + dataTypes.add(dataType); subcategory.setName("name"); subcategories.add(subcategory); @@ -110,6 +125,7 @@ public class ToscaExportHandlerTest extends BeConfDependentTest { resource.setVendorName("vendorName"); resource.setVendorRelease("vendorRelease"); resource.setResourceVendorModelNumber("resourceVendorModelNumber"); + resource.setDataTypes(dataTypes); return resource; } @@ -1193,4 +1209,4 @@ public class ToscaExportHandlerTest extends BeConfDependentTest { // default test result = Deencapsulation.invoke(testSubject, "convertCapabilities", component, nodeType, dataTypes); } -} \ No newline at end of file +} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaDataTypeTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaDataTypeTest.java new file mode 100644 index 0000000000..94a7d055b7 --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaDataTypeTest.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2019 Fujitsu Limited. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.tosca.model; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class ToscaDataTypeTest { + private static final String DERIVED_FROM = "tosca.datatypes.Root"; + private static final String VERSION = "1.1"; + private static final String DESCRIPTION = "data type description"; + private static final String PROPERTY_NAME = "prop1"; + private static final String METADATA_KEY = "foo"; + private static final String METADATA_VALUE = "bar"; + + private ToscaDataType testSubject; + + @Test + public void testToscaDataType() throws Exception { + testSubject = new ToscaDataType(); + testSubject.setDerived_from(DERIVED_FROM); + testSubject.setVersion(VERSION); + testSubject.setDescription(DESCRIPTION); + Map metadata = new HashMap<>(); + metadata.put(METADATA_KEY, METADATA_VALUE); + testSubject.setMetadata(metadata); + Map properties = new HashMap<>(); + properties.put(PROPERTY_NAME, new ToscaProperty()); + testSubject.setProperties(properties); + + assertThat(testSubject.getDerived_from(), is(DERIVED_FROM)); + assertThat(testSubject.getVersion(), is(VERSION)); + assertThat(testSubject.getDescription(), is(DESCRIPTION)); + assertThat(testSubject.getMetadata(), is(metadata)); + assertThat(testSubject.getProperties(), is(properties)); + } +} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateTest.java index 613c7ed457..c250b4eec9 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateTest.java @@ -1,10 +1,12 @@ package org.openecomp.sdc.be.tosca.model; +import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.Test; +import static org.junit.Assert.*; public class ToscaTemplateTest { @@ -122,9 +124,24 @@ public class ToscaTemplateTest { testSubject.setTopology_template(topology_template); } - + @Test + public void testGetSetData_types() throws Exception { + ToscaTemplate testSubject = createTestSubject(); + Map dataTypes = new HashMap<>(); + dataTypes.put("datatype", new ToscaDataType()); + testSubject.setData_types(dataTypes); + assertEquals(dataTypes, testSubject.getData_types()); + } - + + @Test + public void testGetSetInterface_types() throws Exception { + ToscaTemplate testSubject = createTestSubject(); + Map interfaceTypes = new HashMap<>(); + interfaceTypes.put("id", new Object()); + testSubject.setInterface_types(interfaceTypes); + assertEquals(interfaceTypes, testSubject.getInterface_types()); + } } \ No newline at end of file -- cgit 1.2.3-korg