aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-be/src/main
diff options
context:
space:
mode:
authorTalio <tali.orenbach@amdocs.com>2019-01-31 18:00:36 +0200
committerAvi Gaffa <avi.gaffa@amdocs.com>2019-02-04 11:00:09 +0000
commit0953785bfd6a3af5e506f8a55a8520c0fb7ef358 (patch)
tree2f900e3f09a60a5a9a75ddcdd30930d3164eeeed /catalog-be/src/main
parent47c8af4d7241f20755ea97a6119bae2f500cfffa (diff)
Add property mapping feature to ONAP
Add service property assignment Change-Id: I29748ce12bacab06b8bc27f8875b39d80ffe5af7 Issue-ID: SDC-1988 Signed-off-by: Talio <tali.orenbach@amdocs.com>
Diffstat (limited to 'catalog-be/src/main')
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PropertyBusinessLogic.java398
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentPropertyDeclarator.java153
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/property/DefaultPropertyDeclarator.java50
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/property/PropertyDeclarationOrchestrator.java14
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java179
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java2
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentPropertyServlet.java390
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PropertyServlet.java369
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java6
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java4
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java64
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java245
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplate.java17
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InputConverter.java3
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java63
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/externalupload/utils/ServiceUtils.java89
16 files changed, 1427 insertions, 619 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PropertyBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PropertyBusinessLogic.java
index 5f40606177..f49f531e28 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PropertyBusinessLogic.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PropertyBusinessLogic.java
@@ -7,9 +7,9 @@
* 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.
@@ -22,19 +22,27 @@ package org.openecomp.sdc.be.components.impl;
import com.google.gson.JsonElement;
import fj.data.Either;
+import java.util.Map.Entry;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.openecomp.sdc.be.config.BeEcompErrorManager;
import org.openecomp.sdc.be.dao.api.ActionStatus;
import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
import org.openecomp.sdc.be.impl.WebAppContextWrapper;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.ComponentInstanceInterface;
+import org.openecomp.sdc.be.model.ComponentParametersView;
import org.openecomp.sdc.be.model.DataTypeDefinition;
import org.openecomp.sdc.be.model.IComplexDefaultValue;
+import org.openecomp.sdc.be.model.InterfaceDefinition;
import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.Resource;
import org.openecomp.sdc.be.model.operations.api.IElementOperation;
import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
@@ -45,17 +53,13 @@ import org.openecomp.sdc.be.resources.data.EntryData;
import org.openecomp.sdc.common.api.Constants;
import org.openecomp.sdc.common.log.wrappers.Logger;
import org.openecomp.sdc.exception.ResponseFormat;
-import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import javax.servlet.ServletContext;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
+import java.util.*;
import java.util.function.Supplier;
-@Component("propertyBusinessLogic")
+@org.springframework.stereotype.Component("propertyBusinessLogic")
public class PropertyBusinessLogic extends BaseBusinessLogic {
private static final String CREATE_PROPERTY = "CreateProperty";
@@ -77,262 +81,368 @@ public class PropertyBusinessLogic extends BaseBusinessLogic {
}
/**
- * Create new property on resource in graph
+ * Create new property on component in graph
*
- * @param resourceId
+ * @param componentId
* @param propertyName
* @param newPropertyDefinition
* @param userId
* @return either properties or response format
*/
- public Either<EntryData<String, PropertyDefinition>, ResponseFormat> createProperty(String resourceId, String propertyName, PropertyDefinition newPropertyDefinition, String userId) {
+ public Either<EntryData<String, PropertyDefinition>, ResponseFormat> addPropertyToComponent(String componentId,
+ String propertyName,
+ PropertyDefinition newPropertyDefinition,
+ String userId) {
Either<EntryData<String, PropertyDefinition>, ResponseFormat> result = null;
validateUserExists(userId, "create Property", false);
- StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, NodeTypeEnum.Resource);
+ Either<Component, StorageOperationStatus> serviceElement =
+ toscaOperationFacade.getToscaElement(componentId);
+ if (serviceElement.isRight()) {
+ result = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, ""));
+ return result;
+ }
+ Component component = serviceElement.left().value();
+ NodeTypeEnum nodeType = component.getComponentType().getNodeType();
+ StorageOperationStatus lockResult = graphLockOperation.lockComponent(componentId, nodeType );
if (!lockResult.equals(StorageOperationStatus.OK)) {
- BeEcompErrorManager.getInstance().logBeFailedLockObjectError(CREATE_PROPERTY, NodeTypeEnum.Resource.name().toLowerCase(), resourceId);
- log.info("Failed to lock component {}. Error - {}", resourceId, lockResult);
+ BeEcompErrorManager.getInstance().logBeFailedLockObjectError(CREATE_PROPERTY, nodeType.name().toLowerCase(), componentId);
+ log.info("Failed to lock component {}. Error - {}", componentId, lockResult);
result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
return result;
}
try {
- // Get the resource from DB
- Either<Resource, StorageOperationStatus> status = toscaOperationFacade.getToscaElement(resourceId);
- if (status.isRight()) {
- result = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, ""));
- return result;
- }
- Resource resource = status.left().value();
-
- // verify that resource is checked-out and the user is the last
- // updater
- if (!ComponentValidationUtils.canWorkOnResource(resource, userId)) {
+ if (!ComponentValidationUtils.canWorkOnComponent(component, userId)) {
result = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
return result;
}
- // verify property not exist in resource
- List<PropertyDefinition> resourceProperties = resource.getProperties();
+ List<PropertyDefinition> properties = component.getProperties();
- if (resourceProperties != null && isPropertyExist(resourceProperties, resourceId, propertyName, newPropertyDefinition.getType())) {
- result = Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_ALREADY_EXIST, propertyName));
- return result;
+ if(CollectionUtils.isEmpty(properties)) {
+ properties = new ArrayList<>();
}
- Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes = getAllDataTypes(applicationDataTypeCache);
- if (allDataTypes.isRight()) {
- result = Either.right(allDataTypes.right().value());
+ if(isPropertyExistInComponent(properties, propertyName)) {
+
+ result =
+ Either.right(componentsUtils.getResponseFormat(ActionStatus
+ .PROPERTY_ALREADY_EXIST, propertyName));
return result;
- }
- Map<String, DataTypeDefinition> dataTypes = allDataTypes.left().value();
+ } else {
- // validate property default values
- Either<Boolean, ResponseFormat> defaultValuesValidation = validatePropertyDefaultValue(newPropertyDefinition, dataTypes);
- if (defaultValuesValidation.isRight()) {
- result = Either.right(defaultValuesValidation.right().value());
- return result;
- }
- convertProperty(newPropertyDefinition, allDataTypes);
+ Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes = getAllDataTypes(applicationDataTypeCache);
+ if (allDataTypes.isRight()) {
+ result = Either.right(allDataTypes.right().value());
+ return result;
+ }
+ Map<String, DataTypeDefinition> dataTypes = allDataTypes.left().value();
- // add the new property to resource on graph
- // need to get StorageOpaerationStatus and convert to ActionStatus
- // from componentsUtils
- Either<PropertyDefinition, StorageOperationStatus> either = toscaOperationFacade.addPropertyToResource(propertyName, newPropertyDefinition, resource);
- if (either.isRight()) {
- result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(either.right().value()), resource.getName()));
- return result;
+ // validate property default values
+ Either<Boolean, ResponseFormat> defaultValuesValidation = validatePropertyDefaultValue(newPropertyDefinition, dataTypes);
+ if (defaultValuesValidation.isRight()) {
+ result = Either.right(defaultValuesValidation.right().value());
+ return result;
+ }
+ // convert property
+ ToscaPropertyType type = getType(newPropertyDefinition.getType());
+ if (type != null) {
+ PropertyValueConverter converter = type.getConverter();
+ // get inner type
+ String innerType = null;
+ if (newPropertyDefinition != null) {
+ SchemaDefinition schema = newPropertyDefinition.getSchema();
+ if (schema != null) {
+ PropertyDataDefinition prop = schema.getProperty();
+ if (prop != null) {
+ innerType = prop.getType();
+ }
+ }
+ String convertedValue = null;
+ if (newPropertyDefinition.getDefaultValue() != null) {
+ convertedValue = converter.convert(
+ (String) newPropertyDefinition.getDefaultValue(), innerType, allDataTypes.left().value());
+ newPropertyDefinition.setDefaultValue(convertedValue);
+ }
+ }
+ }
+ Either<PropertyDefinition, StorageOperationStatus> addPropertyEither =
+ toscaOperationFacade
+ .addPropertyToComponent(propertyName, newPropertyDefinition, component);
+
+ if (addPropertyEither.isRight()) {
+ log.info("Failed to add new property {}. Error - {}", componentId,
+ addPropertyEither.right().value());
+ result = Either.right(componentsUtils.getResponseFormat(ActionStatus
+ .GENERAL_ERROR));
+ return result;
+ }
}
- PropertyDefinition createdPropertyDefinition = either.left().value();
- EntryData<String, PropertyDefinition> property = new EntryData<>(propertyName, createdPropertyDefinition);
- result = Either.left(property);
+ result = Either.left(new EntryData<>(propertyName, newPropertyDefinition));
return result;
} finally {
commitOrRollback(result);
// unlock component
- graphLockOperation.unlockComponent(resourceId, NodeTypeEnum.Resource);
+ graphLockOperation.unlockComponent(componentId, nodeType);
}
}
- private void convertProperty(PropertyDefinition newPropertyDefinition, Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes) {
- ToscaPropertyType type = getType(newPropertyDefinition.getType());
- if (type != null) {
- String innerType = null;
- SchemaDefinition schema = newPropertyDefinition.getSchema();
- if (schema != null && schema.getProperty() != null) {
- innerType = schema.getProperty().getType();
- }
- if (newPropertyDefinition.getDefaultValue() != null) {
- newPropertyDefinition.setDefaultValue(
- type.getConverter().convert(
- newPropertyDefinition.getDefaultValue(), innerType, allDataTypes.left().value()));
- }
- }
- }
-
/**
- * Get property of resource
+ * Get property of component
*
- * @param resourceId
+ * @param componentId
* @param propertyId
* @param userId
* @return either properties or response format
*/
- public Either<Entry<String, PropertyDefinition>, ResponseFormat> getProperty(String resourceId, String propertyId, String userId) {
+
+ public Either<Map.Entry<String, PropertyDefinition>, ResponseFormat> getComponentProperty(String componentId, String propertyId, String userId) {
validateUserExists(userId, "create Component Instance", false);
// Get the resource from DB
- Either<Resource, StorageOperationStatus> status = toscaOperationFacade.getToscaElement(resourceId);
+ Either<Component, StorageOperationStatus> status =
+ toscaOperationFacade.getToscaElement(componentId);
if (status.isRight()) {
return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, ""));
}
- Resource resource = status.left().value();
-
- // verify property exist in resource
- List<PropertyDefinition> properties = resource.getProperties();
- if (properties == null) {
+ Component component = status.left().value();
+ List<PropertyDefinition> properties = component.getProperties();
+ if(CollectionUtils.isEmpty(properties)) {
return Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, ""));
}
- for (PropertyDefinition property : properties) {
- if (property.getUniqueId().equals(propertyId) ) {
- Map<String, PropertyDefinition> propMap = new HashMap<>();
- propMap.put(property.getName(), property);
- return Either.left(propMap.entrySet().iterator().next());
+
+ for(PropertyDefinition property : properties) {
+ if(property.getUniqueId().equals(propertyId)) {
+ return Either.left(new EntryData<>(property.getName(), property));
}
}
return Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, ""));
}
+
+ public Either<List<PropertyDefinition>, ResponseFormat> getPropertiesList(String componentId,
+ String userId) {
+ validateUserExists(userId, "create Component Instance", false);
+
+ // Get the resource from DB
+ ComponentParametersView filter = new ComponentParametersView(true);
+ filter.setIgnoreProperties(false);
+ Either<Component, StorageOperationStatus> status =
+ toscaOperationFacade.getToscaElement(componentId);
+ if (status.isRight()) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, ""));
+ }
+ Component component = status.left().value();
+ List<PropertyDefinition> properties = component.getProperties();
+
+ return Either.left(properties);
+ }
+
+
/**
- * delete property of resource from graph
+ * delete property of component from graph
*
- * @param resourceId
+ * @param componentId
* @param propertyId
* @param userId
* @return either properties or response format
*/
- public Either<Entry<String, PropertyDefinition>, ResponseFormat> deleteProperty(String resourceId, String propertyId, String userId) {
- Either<Entry<String, PropertyDefinition>, ResponseFormat> result = null;
+ public Either<Map.Entry<String, PropertyDefinition>, ResponseFormat> deletePropertyFromComponent(String componentId, String propertyId, String userId) {
+
+ Either<Map.Entry<String, PropertyDefinition>, ResponseFormat> result = null;
validateUserExists(userId, "delete Property", false);
- StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, NodeTypeEnum.Resource);
+ // Get the resource from DB
+ Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId);
+ if (getComponentRes.isRight()) {
+ result = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, ""));
+ return result;
+ }
+ Component component = getComponentRes.left().value();
+ NodeTypeEnum nodeType = component.getComponentType().getNodeType();
+ StorageOperationStatus lockResult = graphLockOperation.lockComponent(componentId, nodeType);
if (!lockResult.equals(StorageOperationStatus.OK)) {
- BeEcompErrorManager.getInstance().logBeFailedLockObjectError(CREATE_PROPERTY, NodeTypeEnum.Resource.name().toLowerCase(), resourceId);
+ BeEcompErrorManager.getInstance().logBeFailedLockObjectError(CREATE_PROPERTY, nodeType.name().toLowerCase(),
+ componentId);
result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
return result;
}
try {
-
- // Get the resource from DB
- Either<Resource, StorageOperationStatus> getResourceRes = toscaOperationFacade.getToscaElement(resourceId);
- if (getResourceRes.isRight()) {
- result = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, ""));
- return result;
- }
- Resource resource = getResourceRes.left().value();
-
// verify that resource is checked-out and the user is the last
// updater
- if (!ComponentValidationUtils.canWorkOnResource(resource, userId)) {
+ if (!ComponentValidationUtils.canWorkOnComponent(component, userId)) {
result = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
return result;
}
// verify property exist in resource
- Either<Entry<String, PropertyDefinition>, ResponseFormat> statusGetProperty = getProperty(resourceId, propertyId, userId);
+ Either<Map.Entry<String, PropertyDefinition>, ResponseFormat> statusGetProperty =
+ getComponentProperty(componentId, propertyId, userId);
if (statusGetProperty.isRight()) {
result = Either.right(statusGetProperty.right().value());
return result;
}
- StorageOperationStatus status = toscaOperationFacade.deletePropertyOfResource(resource, statusGetProperty.left().value().getKey());
+ Map.Entry<String, PropertyDefinition> propertyDefinitionEntry = statusGetProperty.left().value();
+
+ // verify that the property is not used by operation
+ if (isPropertyUsedByOperation(component, propertyDefinitionEntry.getValue())) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus
+ .PROPERTY_USED_BY_OPERATION));
+ }
+
+ StorageOperationStatus status =
+ toscaOperationFacade.deletePropertyOfComponent(component, propertyDefinitionEntry.getKey());
if (status != StorageOperationStatus.OK) {
- result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status), resource.getName()));
+ result = Either.right(componentsUtils.getResponseFormat(componentsUtils
+ .convertFromStorageResponse(status), component.getName()));
return result;
}
- result = Either.left(statusGetProperty.left().value());
+ result = Either.left(propertyDefinitionEntry);
return result;
} finally {
commitOrRollback(result);
// unlock component
- graphLockOperation.unlockComponent(resourceId, NodeTypeEnum.Resource);
+ graphLockOperation.unlockComponent(componentId, nodeType);
+ }
+ }
+
+ public boolean isPropertyUsedByOperation(Component component,
+ PropertyDefinition propertyDefinitionEntry) {
+
+ // Component's own interfaces
+ Map<String, InterfaceDefinition> interfaces = component.getInterfaces();
+ if(MapUtils.isNotEmpty(interfaces)){
+ for(Map.Entry<String, InterfaceDefinition> interfaceEntry : interfaces.entrySet()) {
+ if (isPropertyExistInOperationInterface(propertyDefinitionEntry, interfaceEntry.getValue())) {
+ return true;
+ }
+ }
+ }
+
+ // Component's child's component interfaces
+ if(isPropertyUsedInCIInterfaces(component.getComponentInstancesInterfaces(), propertyDefinitionEntry)){
+ return true;
+ }
+
+ // Component's parent's component interfaces
+ Either<List<Component>, StorageOperationStatus> componentList = toscaOperationFacade.getParentComponents(component.getUniqueId());
+ if(componentList.isLeft()){
+ for (Component parentComponent : componentList.left().value()) {
+ if(isPropertyUsedInCIInterfaces(parentComponent.getComponentInstancesInterfaces(), propertyDefinitionEntry)){
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private boolean isPropertyUsedInCIInterfaces(Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces, PropertyDefinition propertyDefinitionEntry){
+ if(MapUtils.isNotEmpty(componentInstanceInterfaces)){
+ for (Entry<String, List<ComponentInstanceInterface>> interfaceEntry : componentInstanceInterfaces.entrySet()) {
+ for (ComponentInstanceInterface instanceInterface : interfaceEntry.getValue()) {
+ if (isPropertyExistInOperationInterface(propertyDefinitionEntry, instanceInterface)) {
+ return true;
+ }
+ }
+ }
}
+ return false;
+ }
+
+ private boolean isPropertyExistInOperationInterface(PropertyDefinition propertyDefinition,
+ InterfaceDefinition interfaceDefinition) {
+ Map<String, OperationDataDefinition> operations =
+ interfaceDefinition.getOperations();
+ for(Map.Entry<String, OperationDataDefinition> operationEntry : operations
+ .entrySet()) {
+ Optional<OperationInputDefinition> inputWithDeletedPropertyCandidate =
+ getInputWithDeclaredProperty(propertyDefinition, operationEntry);
+
+ if(inputWithDeletedPropertyCandidate.isPresent()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private Optional<OperationInputDefinition> getInputWithDeclaredProperty(PropertyDefinition propertyDefinition,
+ Map.Entry<String, OperationDataDefinition> operationEntry) {
+ ListDataDefinition<OperationInputDefinition> inputs =
+ operationEntry.getValue().getInputs();
+ List<OperationInputDefinition> operationInputsList =
+ Objects.isNull(inputs) ? null : inputs.getListToscaDataDefinition();
+
+ if(CollectionUtils.isEmpty(operationInputsList)) {
+ return Optional.empty();
+ }
+
+ return operationInputsList.stream().filter(input -> input.getInputId().equals(propertyDefinition.getUniqueId())).findAny();
}
/**
* update property
*
- * @param resourceId
+ * @param componentId
* @param propertyId
* @param newPropertyDefinition
* @param userId
* @return either properties or response format
*/
- public Either<EntryData<String, PropertyDefinition>, ResponseFormat> updateProperty(String resourceId, String propertyId, PropertyDefinition newPropertyDefinition, String userId) {
+
+ public Either<EntryData<String, PropertyDefinition>, ResponseFormat> updateComponentProperty(String componentId,
+ String propertyId,
+ PropertyDefinition newPropertyDefinition,
+ String userId) {
Either<EntryData<String, PropertyDefinition>, ResponseFormat> result = null;
- Either<Resource, StorageOperationStatus> status = toscaOperationFacade.getToscaElement(resourceId);
+ Either<Component, StorageOperationStatus> status = toscaOperationFacade.getToscaElement(
+ componentId);
if (status.isRight()) {
return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, ""));
}
- Resource resource = status.left().value();
+ Component component = status.left().value();
+ NodeTypeEnum nodeType = component.getComponentType().getNodeType();
- if (!ComponentValidationUtils.canWorkOnResource(resource, userId)) {
+ if (!ComponentValidationUtils.canWorkOnComponent(component, userId)) {
return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
}
- StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, NodeTypeEnum.Resource);
+ StorageOperationStatus lockResult = graphLockOperation.lockComponent(componentId, nodeType);
if (!lockResult.equals(StorageOperationStatus.OK)) {
- BeEcompErrorManager.getInstance().logBeFailedLockObjectError(CREATE_PROPERTY, NodeTypeEnum.Resource.name().toLowerCase(), resourceId);
+ BeEcompErrorManager.getInstance().logBeFailedLockObjectError(CREATE_PROPERTY, nodeType.name().toLowerCase(),
+ componentId);
result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
return result;
}
try {
- Either<Entry<String, PropertyDefinition>, ResponseFormat> statusGetProperty = getProperty(resourceId, propertyId, userId);
+ Either<Map.Entry<String, PropertyDefinition>, ResponseFormat> statusGetProperty =
+ getComponentProperty(componentId, propertyId, userId);
if (statusGetProperty.isRight()) {
result = Either.right(statusGetProperty.right().value());
return result;
}
String propertyName = statusGetProperty.left().value().getKey();
- Either<Map<String, DataTypeDefinition>, ResponseFormat> allDataTypes = getAllDataTypes(applicationDataTypeCache);
- if (allDataTypes.isRight()) {
- result = Either.right(allDataTypes.right().value());
- return result;
- }
- Map<String, DataTypeDefinition> dataTypes = allDataTypes.left().value();
-
- Either<Boolean, ResponseFormat> defaultValuesValidation = validatePropertyDefaultValue(newPropertyDefinition, dataTypes);
- if (defaultValuesValidation.isRight()) {
- result = Either.right(defaultValuesValidation.right().value());
- return result;
- }
-
- Either<PropertyDefinition, StorageOperationStatus> either = handleProperty(newPropertyDefinition, dataTypes);
- if (either.isRight()) {
- log.debug("Problem while updating property with id {}. Reason - {}", propertyId, either.right().value());
- result = Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(either.right().value()), resource.getName()));
- return result;
- }
-
-
- either = toscaOperationFacade.updatePropertyOfResource(resource, newPropertyDefinition);
+ Either<PropertyDefinition, StorageOperationStatus> either =
+ toscaOperationFacade.updatePropertyOfComponent(component, newPropertyDefinition);
if (either.isRight()) {
- result = Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(either.right().value()), resource.getName()));
+ result = Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(either.right().value()), component.getName()));
return result;
}
@@ -342,18 +452,30 @@ public class PropertyBusinessLogic extends BaseBusinessLogic {
} finally {
commitOrRollback(result);
- graphLockOperation.unlockComponent(resourceId, NodeTypeEnum.Resource);
+ graphLockOperation.unlockComponent(componentId, nodeType);
}
}
+ private boolean isPropertyExistInComponent(List<PropertyDefinition> properties, String propertyName) {
+ if(CollectionUtils.isEmpty(properties)) {
+ return false;
+ }
+
+ Optional<PropertyDefinition> propertyCandidate =
+ properties.stream().filter(property -> property.getName().equals(propertyName))
+ .findAny();
+
+ return propertyCandidate.isPresent();
+ }
+
private boolean isPropertyExist(List<PropertyDefinition> properties, String resourceUid, String propertyName, String propertyType) {
boolean result = false;
if (!CollectionUtils.isEmpty(properties)) {
for (PropertyDefinition propertyDefinition : properties) {
if ( propertyDefinition.getName().equals(propertyName) &&
- (propertyDefinition.getParentUniqueId().equals(resourceUid) || !propertyDefinition.getType().equals(propertyType)) ) {
+ (propertyDefinition.getParentUniqueId().equals(resourceUid) || !propertyDefinition.getType().equals(propertyType)) ) {
result = true;
break;
}
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
new file mode 100644
index 0000000000..7f49e389ef
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentPropertyDeclarator.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.components.property;
+
+import fj.data.Either;
+import org.apache.commons.collections.CollectionUtils;
+import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic;
+import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.impl.ComponentsUtils;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
+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 java.util.Optional;
+
+@org.springframework.stereotype.Component
+public class ComponentPropertyDeclarator extends DefaultPropertyDeclarator<Component, PropertyDataDefinition> {
+
+ private ToscaOperationFacade toscaOperationFacade;
+ PropertyBusinessLogic propertyBL;
+
+
+ public ComponentPropertyDeclarator(ComponentsUtils componentsUtils,
+ PropertyOperation propertyOperation,
+ ToscaOperationFacade toscaOperationFacade,
+ PropertyBusinessLogic propertyBL) {
+ super(componentsUtils, propertyOperation);
+ this.toscaOperationFacade = toscaOperationFacade;
+ this.propertyBL = propertyBL;
+ }
+
+ @Override
+ PropertyDataDefinition createDeclaredProperty(PropertyDataDefinition prop) {
+ return new PropertyDataDefinition(prop);
+ }
+
+ @Override
+ Either<?, StorageOperationStatus> updatePropertiesValues(Component component,
+ String propertiesOwnerId,
+ List<PropertyDataDefinition> properties) {
+ if(CollectionUtils.isNotEmpty(properties)) {
+ for(PropertyDataDefinition property : properties) {
+ Either<PropertyDefinition, StorageOperationStatus>
+ storageStatus = toscaOperationFacade
+ .updatePropertyOfComponent(component, new PropertyDefinition(property));
+ if(storageStatus.isRight()) {
+ return Either.right(storageStatus.right().value());
+ }
+ }
+ }
+ return Either.left(properties);
+ }
+
+ @Override
+ Optional<Component> resolvePropertiesOwner(Component component, String propertiesOwnerId) {
+ return Optional.of( component);
+ }
+
+ @Override
+ void addPropertiesListToInput(PropertyDataDefinition declaredProp,
+ InputDefinition input) {
+
+ List<ComponentInstanceProperty> propertiesList = input.getProperties();
+ if(propertiesList == null) {
+ propertiesList = new ArrayList<>(); // adding the property with the new value for UI
+ }
+ propertiesList.add(new ComponentInstanceProperty(declaredProp));
+ input.setProperties(propertiesList);
+ }
+
+ @Override
+ public StorageOperationStatus unDeclarePropertiesAsInputs(Component component,
+ InputDefinition input) {
+ PropertyDefinition propertyDefinition = new PropertyDefinition(input);
+
+ if(propertyBL.isPropertyUsedByOperation(component, propertyDefinition)) {
+ return StorageOperationStatus.DECLARED_INPUT_USED_BY_OPERATION;
+ }
+
+ Optional<PropertyDefinition> propertyToUpdateCandidate =
+ getDeclaredPropertyByInputId(component, input.getUniqueId());
+
+ if(propertyToUpdateCandidate.isPresent()) {
+ PropertyDefinition propertyToUpdate = propertyToUpdateCandidate.get();
+ return unDeclareInput(component, input, propertyToUpdate);
+ }
+
+
+ return StorageOperationStatus.OK;
+ }
+
+ private StorageOperationStatus unDeclareInput(Component component,
+ InputDefinition input,
+ PropertyDefinition propertyToUpdate) {
+ prepareValueBeforeDelete(input, propertyToUpdate, Collections.emptyList());
+ propertyToUpdate.setValue(input.getDefaultValue());
+ Either<PropertyDefinition, StorageOperationStatus> status = toscaOperationFacade
+ .updatePropertyOfComponent(component, propertyToUpdate);
+ if(status.isRight()) {
+ return status.right().value();
+ }
+
+ return StorageOperationStatus.OK;
+ }
+
+ private Optional<PropertyDefinition> getDeclaredPropertyByInputId(Component component,
+ String inputId) {
+ List<PropertyDefinition> properties = component.getProperties();
+
+ if(CollectionUtils.isEmpty(properties)) {
+ return Optional.empty();
+ }
+
+ for(PropertyDefinition propertyDefinition : properties) {
+ List<GetInputValueDataDefinition> getInputValues = propertyDefinition.getGetInputValues();
+ if(CollectionUtils.isEmpty(getInputValues)) {
+ continue;
+ }
+
+ Optional<GetInputValueDataDefinition> getInputCandidate =
+ getInputValues.stream().filter(getInput -> getInput.getInputId().equals(inputId))
+ .findAny();
+
+ if(getInputCandidate.isPresent()) {
+ return Optional.of(propertyDefinition);
+ }
+ }
+
+ return Optional.empty();
+ }
+}
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 a5ba0003d2..437ae2d67d 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
@@ -87,20 +87,44 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties
}
private InputDefinition createInput(String componentId, PROPERTYOWNER propertiesOwner, ComponentInstancePropInput propInput, PropertyDataDefinition prop) {
- String generatedInputName = generateInputName(propertiesOwner.getNormalizedName(), propInput);
+ String generatedInputName = generateInputName(propertiesOwner instanceof
+ Service ? null : propertiesOwner.getNormalizedName(),
+ propInput);
return createInputFromProperty(componentId, propertiesOwner, generatedInputName, propInput, prop);
}
private String generateInputName(String inputName, ComponentInstancePropInput propInput) {
+ String declaredInputName = inputName;
String[] parsedPropNames = propInput.getParsedPropNames();
+
if(parsedPropNames != null){
- for(String str: parsedPropNames){
- inputName += "_" + str;
- }
+ declaredInputName = handleInputName(inputName, parsedPropNames);
} else {
- inputName += "_" + propInput.getName();
+ String[] propName = {propInput.getName()};
+ declaredInputName = handleInputName(inputName, propName);
}
- return inputName;
+
+ return declaredInputName;
+ }
+
+ private String handleInputName(String inputName, String[] parsedPropNames) {
+ String prefix;
+ int startingIndex;
+
+ if(Objects.isNull(inputName)) {
+ prefix = parsedPropNames[0];
+ startingIndex = 1;
+ } else {
+ prefix = inputName;
+ startingIndex = 0;
+ }
+
+ while(startingIndex < parsedPropNames.length){
+ prefix += "_" + parsedPropNames[startingIndex];
+ startingIndex ++;
+ }
+
+ return prefix;
}
private PropertyDataDefinition resolveProperty(List<PROPERTYTYPE> propertiesToCreate, ComponentInstancePropInput propInput) {
@@ -131,14 +155,20 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties
input.setPropertyId(propInput.getUniqueId());
input.setValue(null);
changePropertyValueToGetInputValue(inputName, parsedPropNames, input, prop, complexProperty);
- ((IComponentInstanceConnectedElement)prop).setComponentInstanceId(propertiesOwner.getUniqueId());
- ((IComponentInstanceConnectedElement)prop).setComponentInstanceName(propertiesOwner.getName());
+
+ if(prop instanceof IComponentInstanceConnectedElement) {
+ ((IComponentInstanceConnectedElement) prop)
+ .setComponentInstanceId(propertiesOwner.getUniqueId());
+ ((IComponentInstanceConnectedElement) prop)
+ .setComponentInstanceName(propertiesOwner.getName());
+ }
return input;
}
private void changePropertyValueToGetInputValue(String inputName, String[] parsedPropNames, InputDefinition input, PropertyDataDefinition prop, boolean complexProperty) {
JSONObject jobject = new JSONObject();
- if(prop.getValue() == null || prop.getValue().isEmpty()){
+ String value = (String) prop.getValue();
+ if(value == null || value.isEmpty()){
if(complexProperty){
jobject = createJSONValueForProperty(parsedPropNames.length -1, parsedPropNames, jobject, inputName);
@@ -153,7 +183,7 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties
}else{
- String value = prop.getValue();
+ //String value = value;
Object objValue = new Yaml().load(value);
if( objValue instanceof Map || objValue instanceof List){
if(!complexProperty){
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 937e2ccfc8..babddc4da1 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
@@ -22,14 +22,21 @@ public class PropertyDeclarationOrchestrator {
private ComponentInstancePropertyDeclarator componentInstancePropertyDeclarator;
private PolicyPropertyDeclarator policyPropertyDeclarator;
private GroupPropertyDeclarator groupPropertyDeclarator;
+ private ComponentPropertyDeclarator servicePropertyDeclarator;
private List<PropertyDeclarator> propertyDeclarators;
- public PropertyDeclarationOrchestrator(ComponentInstanceInputPropertyDeclarator componentInstanceInputPropertyDeclarator, ComponentInstancePropertyDeclarator componentInstancePropertyDeclarator, PolicyPropertyDeclarator policyPropertyDeclarator, GroupPropertyDeclarator groupPropertyDeclarator) {
+ public PropertyDeclarationOrchestrator(
+ ComponentInstanceInputPropertyDeclarator componentInstanceInputPropertyDeclarator,
+ ComponentInstancePropertyDeclarator componentInstancePropertyDeclarator,
+ PolicyPropertyDeclarator policyPropertyDeclarator,
+ GroupPropertyDeclarator groupPropertyDeclarator,
+ ComponentPropertyDeclarator servicePropertyDeclarator) {
this.componentInstanceInputPropertyDeclarator = componentInstanceInputPropertyDeclarator;
this.componentInstancePropertyDeclarator = componentInstancePropertyDeclarator;
this.policyPropertyDeclarator = policyPropertyDeclarator;
this.groupPropertyDeclarator = groupPropertyDeclarator;
- propertyDeclarators = Arrays.asList(componentInstanceInputPropertyDeclarator, componentInstancePropertyDeclarator, policyPropertyDeclarator, groupPropertyDeclarator);
+ this.servicePropertyDeclarator = servicePropertyDeclarator;
+ propertyDeclarators = Arrays.asList(componentInstanceInputPropertyDeclarator, componentInstancePropertyDeclarator, policyPropertyDeclarator, groupPropertyDeclarator, servicePropertyDeclarator);
}
public Either<List<InputDefinition>, StorageOperationStatus> declarePropertiesToInputs(Component component, ComponentInstInputsMap componentInstInputsMap) {
@@ -64,6 +71,9 @@ public class PropertyDeclarationOrchestrator {
if (isNotEmpty(componentInstInputsMap.getGroupProperties())) {
return groupPropertyDeclarator;
}
+ if(isNotEmpty(componentInstInputsMap.getServiceProperties())) {
+ return servicePropertyDeclarator;
+ }
throw new IllegalStateException("there are no properties selected for declaration");
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java
index 5b8d6dcc17..4502012bd9 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java
@@ -23,8 +23,27 @@ package org.openecomp.sdc.be.servlets;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
import fj.data.Either;
-import org.openecomp.sdc.be.components.impl.*;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic;
+import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic;
+import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
+import org.openecomp.sdc.be.components.impl.ElementBusinessLogic;
+import org.openecomp.sdc.be.components.impl.GroupBusinessLogic;
+import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic;
+import org.openecomp.sdc.be.components.impl.MonitoringBusinessLogic;
+import org.openecomp.sdc.be.components.impl.PolicyBusinessLogic;
+import org.openecomp.sdc.be.components.impl.PolicyTypeBusinessLogic;
+import org.openecomp.sdc.be.components.impl.ProductBusinessLogic;
+import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic;
+import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
+import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
import org.openecomp.sdc.be.components.scheduledtasks.ComponentsCleanBusinessLogic;
import org.openecomp.sdc.be.components.upgrade.UpgradeBusinessLogic;
@@ -35,8 +54,11 @@ import org.openecomp.sdc.be.ecomp.converters.AssetMetadataConverter;
import org.openecomp.sdc.be.impl.ComponentsUtils;
import org.openecomp.sdc.be.impl.WebAppContextWrapper;
import org.openecomp.sdc.be.model.PropertyConstraint;
+import org.openecomp.sdc.be.model.PropertyDefinition;
import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.model.operations.impl.PropertyOperation;
import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintJacksonDeserializer;
+import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
import org.openecomp.sdc.be.user.UserBusinessLogic;
import org.openecomp.sdc.common.api.Constants;
@@ -51,8 +73,12 @@ import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
import java.util.function.Supplier;
public class BeGenericServlet extends BasicServlet {
@@ -79,8 +105,8 @@ public class BeGenericServlet extends BasicServlet {
private static Response buildOkResponseStatic(Object entity) {
return Response.status(Response.Status.OK)
- .entity(entity)
- .build();
+ .entity(entity)
+ .build();
}
protected Response buildOkResponse(ResponseFormat errorResponseWrapper, Object entity) {
@@ -215,8 +241,8 @@ public class BeGenericServlet extends BasicServlet {
protected String getContentDispositionValue(String artifactFileName) {
return new StringBuilder().append("attachment; filename=\"").append(artifactFileName).append("\"").toString();
}
-
-
+
+
protected ComponentBusinessLogic getComponentBL(ComponentTypeEnum componentTypeEnum, ServletContext context) {
ComponentBusinessLogic businessLogic;
@@ -243,8 +269,8 @@ public class BeGenericServlet extends BasicServlet {
<T> void convertJsonToObjectOfClass(String json, Wrapper<T> policyWrapper, Class<T> clazz, Wrapper<Response> errorWrapper) {
T object = null;
ObjectMapper mapper = new ObjectMapper()
- .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
- .configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
+ .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+ .configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
try {
log.trace("Starting to convert json to object. Json=\n{}", json);
@@ -266,4 +292,143 @@ public class BeGenericServlet extends BasicServlet {
errorWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)));
}
}
+
+ protected Either<Map<String, PropertyDefinition>, ActionStatus> getPropertyModel(String componentId,
+ String data) {
+ JSONParser parser = new JSONParser();
+ JSONObject root;
+ try {
+ Map<String, PropertyDefinition> properties = new HashMap<String, PropertyDefinition>();
+ root = (JSONObject) parser.parse(data);
+
+ Set entrySet = root.entrySet();
+ Iterator iterator = entrySet.iterator();
+ while (iterator.hasNext()) {
+ Entry next = (Entry) iterator.next();
+ String propertyName = (String) next.getKey();
+ JSONObject value = (JSONObject) next.getValue();
+ String jsonString = value.toJSONString();
+ Either<PropertyDefinition, ActionStatus> convertJsonToObject = convertJsonToObject(jsonString, PropertyDefinition.class);
+ if (convertJsonToObject.isRight()) {
+ return Either.right(convertJsonToObject.right().value());
+ }
+ PropertyDefinition propertyDefinition = convertJsonToObject.left().value();
+ String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(componentId, (String) propertyName);
+ propertyDefinition.setUniqueId(uniqueId);
+ properties.put(propertyName, propertyDefinition);
+ }
+
+ return Either.left(properties);
+ } catch (ParseException e) {
+ log.info("Property conetnt is invalid - {}", data);
+ return Either.right(ActionStatus.INVALID_CONTENT);
+ }
+ }
+
+ protected Either<Map<String, PropertyDefinition>, ActionStatus> getPropertiesListForUpdate(String data) {
+
+ Map<String, PropertyDefinition> properties = new HashMap<>();
+ JSONParser parser = new JSONParser();
+ JSONArray jsonArray;
+
+ try {
+ jsonArray = (JSONArray) parser.parse(data);
+ for (Object jsonElement : jsonArray) {
+ String propertyAsString = jsonElement.toString();
+ Either<PropertyDefinition, ActionStatus> convertJsonToObject = convertJsonToObject(propertyAsString, PropertyDefinition.class);
+
+ if (convertJsonToObject.isRight()) {
+ return Either.right(convertJsonToObject.right().value());
+ }
+
+ PropertyDefinition propertyDefinition = convertJsonToObject.left().value();
+ properties.put(propertyDefinition.getName(), propertyDefinition);
+ }
+
+ return Either.left(properties);
+ } catch (Exception e) {
+ log.info("Property content is invalid - {}", data);
+ return Either.right(ActionStatus.INVALID_CONTENT);
+ }
+
+ }
+
+
+ protected String propertyToJson(Map.Entry<String, PropertyDefinition> property) {
+ JSONObject root = new JSONObject();
+ String propertyName = property.getKey();
+ PropertyDefinition propertyDefinition = property.getValue();
+ JSONObject propertyDefinitionO = getPropertyDefinitionJSONObject(propertyDefinition);
+ root.put(propertyName, propertyDefinitionO);
+ propertyDefinition.getType();
+ return root.toString();
+ }
+
+ private JSONObject getPropertyDefinitionJSONObject(PropertyDefinition propertyDefinition) {
+
+ Either<String, ActionStatus> either = convertObjectToJson(propertyDefinition);
+ if (either.isRight()) {
+ return new JSONObject();
+ }
+ String value = either.left().value();
+ try {
+ JSONObject root = (JSONObject) new JSONParser().parse(value);
+ return root;
+ } catch (ParseException e) {
+ log.info("failed to convert input to json");
+ log.debug("failed to convert to json", e);
+ return new JSONObject();
+ }
+
+ }
+
+ protected <T> Either<T, ActionStatus> convertJsonToObject(String data, Class<T> clazz) {
+ T t = null;
+ Type constraintType = new TypeToken<PropertyConstraint>() {
+ }.getType();
+ Gson
+ gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyOperation.PropertyConstraintDeserialiser()).create();
+ try {
+ log.trace("convert json to object. json=\n {}", data);
+ t = gson.fromJson(data, clazz);
+ if (t == null) {
+ log.info("object is null after converting from json");
+ return Either.right(ActionStatus.INVALID_CONTENT);
+ }
+ } catch (Exception e) {
+ // INVALID JSON
+ log.info("failed to convert from json");
+ log.debug("failed to convert from json", e);
+ return Either.right(ActionStatus.INVALID_CONTENT);
+ }
+ return Either.left(t);
+ }
+
+ private <T> Either<String, ActionStatus> convertObjectToJson(PropertyDefinition propertyDefinition) {
+ Type constraintType = new TypeToken<PropertyConstraint>() {
+ }.getType();
+ Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyOperation.PropertyConstraintSerialiser()).create();
+ try {
+ log.trace("convert object to json. propertyDefinition= {}", propertyDefinition);
+ String json = gson.toJson(propertyDefinition);
+ if (json == null) {
+ log.info("object is null after converting to json");
+ return Either.right(ActionStatus.INVALID_CONTENT);
+ }
+ return Either.left(json);
+ } catch (Exception e) {
+ // INVALID JSON
+ log.info("failed to convert to json");
+ log.debug("failed to convert fto json", e);
+ return Either.right(ActionStatus.INVALID_CONTENT);
+ }
+
+ }
+
+ protected PropertyBusinessLogic getPropertyBL(ServletContext context) {
+ WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
+ WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
+ PropertyBusinessLogic propertytBl = webApplicationContext.getBean(PropertyBusinessLogic.class);
+ return propertytBl;
+ }
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java
index 042303e2c3..b5e28148da 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java
@@ -1139,7 +1139,7 @@ public class ComponentInstanceServlet extends AbstractValidationsServlet {
return Either.left(requirementCapabilityRelDef);
}
- private <T> Either<T, ActionStatus> convertJsonToObject(String data, Class<T> clazz) {
+ public <T> Either<T, ActionStatus> convertJsonToObject(String data, Class<T> clazz) {
try {
log.trace("convert json to object. json=\n {}", data);
T t;
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentPropertyServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentPropertyServlet.java
new file mode 100644
index 0000000000..0edce61bae
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentPropertyServlet.java
@@ -0,0 +1,390 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.servlets;
+
+import com.jcabi.aspects.Loggable;
+import fj.data.Either;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic;
+import org.openecomp.sdc.be.config.BeEcompErrorManager;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.resources.data.EntryData;
+import org.openecomp.sdc.common.api.Constants;
+import org.openecomp.sdc.exception.ResponseFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Singleton;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.List;
+import java.util.Map;
+
+@Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
+@Path("/v1/catalog")
+@Api(value = "Component Property Servlet", description = "Property Servlet - used to create properties in Service and Resource")
+@Singleton
+public class ComponentPropertyServlet extends BeGenericServlet {
+
+ private static final Logger log = LoggerFactory.getLogger(ComponentPropertyServlet.class);
+
+ @POST
+ @Path("services/{serviceId}/properties")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Create Service Property", httpMethod = "POST", notes = "Returns created service property", response = Response.class)
+ @ApiResponses(value = { @ApiResponse(code = 201, message = "Service property created"),
+ @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 409, message = "Service property already exist") })
+ public Response createPropertyInService(@ApiParam(value = "service id to update with new property", required = true) @PathParam("serviceId") final String serviceId,
+ @ApiParam(value = "Service property to be created", required = true) String data,
+ @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+ return createProperty(serviceId, data, request, userId);
+ }
+
+ @POST
+ @Path("resources/{resourceId}/properties")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Create Resource Property", httpMethod = "POST", notes = "Returns created service property", response = Response.class)
+ @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource property created"),
+ @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 409, message = "Resource property already exist") })
+ public Response createPropertyInResource(@ApiParam(value = "Resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId,
+ @ApiParam(value = "Resource property to be created", required = true) String data,
+ @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+ return createProperty(resourceId, data, request, userId);
+ }
+
+
+ @GET
+ @Path("services/{serviceId}/properties/{propertyId}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Get Service Property", httpMethod = "GET", notes = "Returns property of service", response = Response.class)
+ @ApiResponses(value = { @ApiResponse(code = 200, message = "property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 404, message = "Service property not found") })
+ public Response getPropertyInService(@ApiParam(value = "service id of property", required = true)
+ @PathParam("serviceId") final String serviceId, @ApiParam(value = "property id to get", required = true) @PathParam("propertyId") final String propertyId,
+ @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+ return getProperty(serviceId, propertyId, request, userId);
+ }
+
+ @GET
+ @Path("resources/{resourceId}/properties/{propertyId}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Get Resource Property", httpMethod = "GET", notes = "Returns property of resource", response = Response.class)
+ @ApiResponses(value = { @ApiResponse(code = 200, message = "property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 404, message = "Resource property not found") })
+ public Response getPropertyInResource(@ApiParam(value = "resource id of property", required = true)
+ @PathParam("resourceId") final String resourceId, @ApiParam(value = "property id to get", required = true) @PathParam("propertyId") final String propertyId,
+ @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+ return getProperty(resourceId, propertyId, request, userId);
+ }
+
+ @GET
+ @Path("services/{serviceId}/properties")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Get Service Property", httpMethod = "GET", notes = "Returns property list of service", response = Response.class)
+ @ApiResponses(value = { @ApiResponse(code = 200, message = "property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 404, message = "Service property not found") })
+ public Response getPropertyListInService(@ApiParam(value = "service id of property", required = true) @PathParam("serviceId") final String serviceId,
+ @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+ return getPropertyList(serviceId, request, userId);
+ }
+
+ @GET
+ @Path("resources/{resourceId}/properties")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Get Resource Property", httpMethod = "GET", notes = "Returns property list of resource", response = Response.class)
+ @ApiResponses(value = { @ApiResponse(code = 200, message = "property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 404, message = "Resource property not found") })
+ public Response getPropertyListInResource(@ApiParam(value = "resource id of property", required = true) @PathParam("resourceId") final String resourceId,
+ @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+ return getPropertyList(resourceId, request, userId);
+ }
+
+ @DELETE
+ @Path("services/{serviceId}/properties/{propertyId}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Delete Service Property", httpMethod = "DELETE", notes = "Returns deleted property", response = Response.class)
+ @ApiResponses(value = { @ApiResponse(code = 204, message = "deleted property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 404, message = "Service property not found") })
+ public Response deletePropertyInService(@ApiParam(value = "service id of property", required = true) @PathParam("serviceId") final String serviceId,
+ @ApiParam(value = "Property id to delete", required = true) @PathParam("propertyId") final String propertyId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+ return deleteProperty(serviceId, propertyId, request, userId);
+ }
+
+ @DELETE
+ @Path("resources/{resourceId}/properties/{propertyId}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Delete Resource Property", httpMethod = "DELETE", notes = "Returns deleted property", response = Response.class)
+ @ApiResponses(value = { @ApiResponse(code = 204, message = "deleted property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 404, message = "Resource property not found") })
+ public Response deletePropertyInResource(@ApiParam(value = "resource id of property", required = true) @PathParam("resourceId") final String resourceId,
+ @ApiParam(value = "Property id to delete", required = true) @PathParam("propertyId") final String propertyId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+ return deleteProperty(resourceId, propertyId, request, userId);
+ }
+
+ @PUT
+ @Path("services/{serviceId}/properties")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Update Service Property", httpMethod = "PUT", notes = "Returns updated property", response = Response.class)
+ @ApiResponses(value = { @ApiResponse(code = 200, message = "Service property updated"),
+ @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
+ public Response updatePropertyInService(@ApiParam(value = "service id to update with new property", required = true) @PathParam("serviceId") final String serviceId,
+ @ApiParam(value = "Service property to update", required = true) String data, @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+ return updateProperty(serviceId, data, request, userId);
+ }
+
+ @PUT
+ @Path("resources/{resourceId}/properties")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Update Resource Property", httpMethod = "PUT", notes = "Returns updated property", response = Response.class)
+ @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource property updated"),
+ @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
+ public Response updatePropertyInResource(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId,
+ @ApiParam(value = "Resource property to update", required = true) String data, @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+ return updateProperty(resourceId, data, request, userId);
+ }
+
+ private Response createProperty(String componentId, String data, HttpServletRequest request,String userId) {
+ ServletContext context = request.getSession().getServletContext();
+
+ String url = request.getMethod() + " " + request.getRequestURI();
+ log.debug("Start handle request of {} modifier id is {} data is {}", url, userId, data);
+
+ try{
+ Either<Map<String, PropertyDefinition>, ActionStatus> propertyDefinition =
+ getPropertyModel(componentId, data);
+ if (propertyDefinition.isRight()) {
+ ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(propertyDefinition.right().value());
+ return buildErrorResponse(responseFormat);
+ }
+
+ Map<String, PropertyDefinition> properties = propertyDefinition.left().value();
+ if (properties == null || properties.size() != 1) {
+ log.info("Property content is invalid - {}", data);
+ ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
+ return buildErrorResponse(responseFormat);
+ }
+
+ Map.Entry<String, PropertyDefinition> entry = properties.entrySet().iterator().next();
+ PropertyDefinition newPropertyDefinition = entry.getValue();
+ newPropertyDefinition.setParentUniqueId(componentId);
+ String propertyName = newPropertyDefinition.getName();
+
+ PropertyBusinessLogic propertyBL = getPropertyBL(context);
+ Either<EntryData<String, PropertyDefinition>, ResponseFormat> addPropertyEither =
+ propertyBL.addPropertyToComponent(componentId, propertyName, newPropertyDefinition, userId);
+
+ if(addPropertyEither.isRight()) {
+ return buildErrorResponse(addPropertyEither.right().value());
+ }
+
+ return buildOkResponse(newPropertyDefinition);
+
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Property");
+ log.debug("create property failed with exception", e);
+ ResponseFormat responseFormat =
+ getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
+ return buildErrorResponse(responseFormat);
+ }
+ }
+
+
+ private Response updateProperty(String componentId, String data, HttpServletRequest request, String userId) {
+ ServletContext context = request.getSession().getServletContext();
+
+ String url = request.getMethod() + " " + request.getRequestURI();
+ log.debug("Start handle request of {}", url);
+
+ // get modifier id
+ User modifier = new User();
+ modifier.setUserId(userId);
+ log.debug("modifier id is {}", userId);
+//
+ try {
+ // convert json to PropertyDefinition
+
+ Either<Map<String, PropertyDefinition>, ActionStatus> propertiesListEither =
+ getPropertiesListForUpdate(data);
+ if (propertiesListEither.isRight()) {
+ ResponseFormat responseFormat =
+ getComponentsUtils().getResponseFormat(propertiesListEither.right().value());
+ return buildErrorResponse(responseFormat);
+ }
+ Map<String, PropertyDefinition> properties = propertiesListEither.left().value();
+ if (properties == null) {
+ log.info("Property content is invalid - {}", data);
+ ResponseFormat responseFormat =
+ getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
+ return buildErrorResponse(responseFormat);
+ }
+
+ // update property
+
+ PropertyBusinessLogic businessLogic = getPropertyBL(context);
+ for(PropertyDefinition propertyDefinition : properties.values()) {
+ Either<EntryData<String, PropertyDefinition>, ResponseFormat> status =
+ businessLogic.updateComponentProperty(
+ componentId, propertyDefinition.getUniqueId(), propertyDefinition, userId);
+ if (status.isRight()) {
+ log.info("Failed to update Property. Reason - ", status.right().value());
+ return buildErrorResponse(status.right().value());
+ }
+ EntryData<String, PropertyDefinition> property = status.left().value();
+ PropertyDefinition updatedPropertyDefinition = property.getValue();
+
+ log.debug("Property id {} updated successfully ", updatedPropertyDefinition.getUniqueId());
+ }
+
+ ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
+ return buildOkResponse(responseFormat, properties);
+
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Property");
+ log.debug("update property failed with exception", e);
+ ResponseFormat responseFormat =
+ getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
+ return buildErrorResponse(responseFormat);
+
+ }
+ }
+
+ private Response getProperty(String componentId, String propertyId, HttpServletRequest request, String userId) {
+ ServletContext context = request.getSession().getServletContext();
+
+ String url = request.getMethod() + " " + request.getRequestURI();
+ log.debug("Start handle request of {} modifier id is {}", url, userId);
+
+ try {
+ PropertyBusinessLogic propertyBL = getPropertyBL(context);
+ Either<Map.Entry<String, PropertyDefinition>, ResponseFormat> retrievedPropertyEither =
+ propertyBL.getComponentProperty(componentId, propertyId, userId);
+
+ if(retrievedPropertyEither.isRight()) {
+ return buildErrorResponse(retrievedPropertyEither.right().value());
+ }
+
+ return buildOkResponse(retrievedPropertyEither.left().value());
+
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Property");
+ log.debug("get property failed with exception", e);
+ ResponseFormat responseFormat =
+ getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
+ return buildErrorResponse(responseFormat);
+ }
+ }
+ private Response getPropertyList(String componentId, HttpServletRequest request, String userId) {
+ ServletContext context = request.getSession().getServletContext();
+
+ String url = request.getMethod() + " " + request.getRequestURI();
+ log.debug("Start handle request of {} modifier id is {}", url, userId);
+
+ try {
+ PropertyBusinessLogic propertyBL = getPropertyBL(context);
+ Either<List<PropertyDefinition>, ResponseFormat> propertiesListEither =
+ propertyBL.getPropertiesList(componentId, userId);
+
+ if(propertiesListEither.isRight()) {
+ return buildErrorResponse(propertiesListEither.right().value());
+ }
+
+ return buildOkResponse(propertiesListEither.left().value());
+
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Property");
+ log.debug("get property failed with exception", e);
+ ResponseFormat responseFormat =
+ getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
+ return buildErrorResponse(responseFormat);
+ }
+ }
+ private Response deleteProperty(String componentId, String propertyId, HttpServletRequest request, String userId) {
+ ServletContext context = request.getSession().getServletContext();
+
+ String url = request.getMethod() + " " + request.getRequestURI();
+ log.debug("Start handle request of {} modifier id is {}", url, userId);
+
+ try {
+
+ // delete the property
+ PropertyBusinessLogic businessLogic = getPropertyBL(context);
+ Either<Map.Entry<String, PropertyDefinition>, ResponseFormat> status =
+ businessLogic.deletePropertyFromComponent(componentId, propertyId, userId);
+ if (status.isRight()) {
+ log.debug("Failed to delete Property. Reason - ", status.right().value());
+ return buildErrorResponse(status.right().value());
+ }
+ Map.Entry<String, PropertyDefinition> property = status.left().value();
+ String name = property.getKey();
+ PropertyDefinition propertyDefinition = property.getValue();
+
+ log.debug("Property {} deleted successfully with id {}", name, propertyDefinition.getUniqueId());
+ ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT);
+ return buildOkResponse(responseFormat, propertyToJson(property));
+
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Property");
+ log.debug("delete property failed with exception", e);
+ ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
+ return buildErrorResponse(responseFormat);
+
+ }
+ }
+
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PropertyServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PropertyServlet.java
deleted file mode 100644
index 12d788dd45..0000000000
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PropertyServlet.java
+++ /dev/null
@@ -1,369 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. 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.servlets;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.reflect.TypeToken;
-import com.jcabi.aspects.Loggable;
-import fj.data.Either;
-import io.swagger.annotations.*;
-import org.json.simple.JSONObject;
-import org.json.simple.parser.JSONParser;
-import org.json.simple.parser.ParseException;
-import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic;
-import org.openecomp.sdc.be.config.BeEcompErrorManager;
-import org.openecomp.sdc.be.dao.api.ActionStatus;
-import org.openecomp.sdc.be.impl.WebAppContextWrapper;
-import org.openecomp.sdc.be.model.PropertyConstraint;
-import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.User;
-import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser;
-import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintSerialiser;
-import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
-import org.openecomp.sdc.be.resources.data.EntryData;
-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;
-
-import javax.inject.Singleton;
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.*;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import java.lang.reflect.Type;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-@Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
-@Path("/v1/catalog")
-@Api(value = "Resource Property Servlet", description = "Resource Property Servlet")
-@Singleton
-public class PropertyServlet extends BeGenericServlet {
-
- private static final Logger log = Logger.getLogger(PropertyServlet.class.getName());
-
- @POST
- @Path("resources/{resourceId}/properties")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- @ApiOperation(value = "Create Resource Property", httpMethod = "POST", notes = "Returns created resource property", response = Response.class)
- @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource property created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
- @ApiResponse(code = 409, message = "Resource property already exist") })
- public Response createProperty(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId, @ApiParam(value = "Resource property to be created", required = true) String data,
- @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
-
- ServletContext context = request.getSession().getServletContext();
-
- String url = request.getMethod() + " " + request.getRequestURI();
- log.debug("Start handle request of {} modifier id is {} data is {}", url, userId, data);
-
- try {
- // convert json to PropertyDefinition
- Either<Map<String, PropertyDefinition>, ActionStatus> either = getPropertyModel(resourceId, data);
- if (either.isRight()) {
- ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(either.right().value());
- return buildErrorResponse(responseFormat);
- }
- Map<String, PropertyDefinition> properties = either.left().value();
- if (properties == null || properties.size() != 1) {
- log.info("Property conetnt is invalid - {}", data);
- ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
- return buildErrorResponse(responseFormat);
- }
- Entry<String, PropertyDefinition> entry = properties.entrySet().iterator().next();
- String propertyName = entry.getKey();
- PropertyDefinition newPropertyDefinition = entry.getValue();
-
- // create the new property
- PropertyBusinessLogic businessLogic = getPropertyBL(context);
- Either<EntryData<String, PropertyDefinition>, ResponseFormat> status = businessLogic.createProperty(resourceId, propertyName, newPropertyDefinition, userId);
- if (status.isRight()) {
- log.info("Failed to create Property. Reason - ", status.right().value());
- return buildErrorResponse(status.right().value());
- }
- EntryData<String, PropertyDefinition> property = status.left().value();
- String name = property.getKey();
- PropertyDefinition propertyDefinition = property.getValue();
-
- log.debug("Property {} created successfully with id {}", name, propertyDefinition.getUniqueId());
- ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED);
- return buildOkResponse(responseFormat, propertyToJson(property));
-
- } catch (Exception e) {
- BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Property");
- log.debug("create property failed with exception", e);
- ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
- return buildErrorResponse(responseFormat);
-
- }
- }
-
- @GET
- @Path("resources/{resourceId}/properties/{propertyId}")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- @ApiOperation(value = "Create Resource Property", httpMethod = "GET", notes = "Returns property of resource", response = Response.class)
- @ApiResponses(value = { @ApiResponse(code = 200, message = "property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
- @ApiResponse(code = 404, message = "Resource property not found") })
- public Response getProperty(@ApiParam(value = "resource id of property", required = true) @PathParam("resourceId") final String resourceId, @ApiParam(value = "proerty id to get", required = true) @PathParam("propertyId") final String propertyId,
- @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
-
- ServletContext context = request.getSession().getServletContext();
-
- String url = request.getMethod() + " " + request.getRequestURI();
- log.debug("Start handle request of {}, modifier id is {}", url, userId);
-
- try {
-
- //
- PropertyBusinessLogic businessLogic = getPropertyBL(context);
- Either<Entry<String, PropertyDefinition>, ResponseFormat> status = businessLogic.getProperty(resourceId, propertyId, userId);
-
- if (status.isRight()) {
- log.info("Failed to get Property. Reason - ", status.right().value());
- return buildErrorResponse(status.right().value());
- }
- Entry<String, PropertyDefinition> property = status.left().value();
- ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
- return buildOkResponse(responseFormat, propertyToJson(property));
- } catch (Exception e) {
- BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Property");
- log.debug("get property failed with exception", e);
- ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
- return buildErrorResponse(responseFormat);
-
- }
- }
-
- @DELETE
- @Path("resources/{resourceId}/properties/{propertyId}")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- @ApiOperation(value = "Create Resource Property", httpMethod = "DELETE", notes = "Returns deleted property", response = Response.class)
- @ApiResponses(value = { @ApiResponse(code = 204, message = "deleted property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
- @ApiResponse(code = 404, message = "Resource property not found") })
- public Response deleteProperty(@ApiParam(value = "resource id of property", required = true) @PathParam("resourceId") final String resourceId,
- @ApiParam(value = "Property id to delete", required = true) @PathParam("propertyId") final String propertyId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
-
- ServletContext context = request.getSession().getServletContext();
-
- String url = request.getMethod() + " " + request.getRequestURI();
- log.debug("Start handle request of {} modifier id is {}", url, userId);
-
- try {
-
- // delete the property
- PropertyBusinessLogic businessLogic = getPropertyBL(context);
- Either<Entry<String, PropertyDefinition>, ResponseFormat> status = businessLogic.deleteProperty(resourceId, propertyId, userId);
- if (status.isRight()) {
- log.debug("Failed to delete Property. Reason - ", status.right().value());
- return buildErrorResponse(status.right().value());
- }
- Entry<String, PropertyDefinition> property = status.left().value();
- String name = property.getKey();
- PropertyDefinition propertyDefinition = property.getValue();
-
- log.debug("Property {} deleted successfully with id {}", name, propertyDefinition.getUniqueId());
- ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT);
- return buildOkResponse(responseFormat, propertyToJson(property));
-
- } catch (Exception e) {
- BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Property");
- log.debug("delete property failed with exception", e);
- ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
- return buildErrorResponse(responseFormat);
-
- }
- }
-
- @PUT
- @Path("resources/{resourceId}/properties/{propertyId}")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- @ApiOperation(value = "Update Resource Property", httpMethod = "PUT", notes = "Returns updated property", response = Response.class)
- @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource property updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") })
- public Response updateProperty(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId,
- @ApiParam(value = "proerty id to update", required = true) @PathParam("propertyId") final String propertyId, @ApiParam(value = "Resource property to update", required = true) String data, @Context final HttpServletRequest request,
- @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
-
- ServletContext context = request.getSession().getServletContext();
-
- String url = request.getMethod() + " " + request.getRequestURI();
- log.debug("Start handle request of {}", url);
-
- // get modifier id
- User modifier = new User();
- modifier.setUserId(userId);
- log.debug("modifier id is {}", userId);
-
- try {
- // convert json to PropertyDefinition
- Either<Map<String, PropertyDefinition>, ActionStatus> either = getPropertyModel(resourceId, data);
- if (either.isRight()) {
- ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(either.right().value());
- return buildErrorResponse(responseFormat);
- }
- Map<String, PropertyDefinition> properties = either.left().value();
- if (properties == null || properties.size() != 1) {
- log.info("Property conetnt is invalid - {}", data);
- ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT);
- return buildErrorResponse(responseFormat);
- }
- Entry<String, PropertyDefinition> entry = properties.entrySet().iterator().next();
- PropertyDefinition newPropertyDefinition = entry.getValue();
-
- // update property
- PropertyBusinessLogic businessLogic = getPropertyBL(context);
- Either<EntryData<String, PropertyDefinition>, ResponseFormat> status = businessLogic.updateProperty(resourceId, propertyId, newPropertyDefinition, userId);
- if (status.isRight()) {
- log.info("Failed to update Property. Reason - ", status.right().value());
- return buildErrorResponse(status.right().value());
- }
- EntryData<String, PropertyDefinition> property = status.left().value();
- PropertyDefinition propertyDefinition = property.getValue();
-
- log.debug("Property id {} updated successfully ", propertyDefinition.getUniqueId());
- ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK);
- return buildOkResponse(responseFormat, propertyToJson(property));
-
- } catch (Exception e) {
- BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Property");
- log.debug("update property failed with exception", e);
- ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
- return buildErrorResponse(responseFormat);
-
- }
- }
-
- private Either<Map<String, PropertyDefinition>, ActionStatus> getPropertyModel(String resourceId, String data) {
- JSONParser parser = new JSONParser();
- JSONObject root;
- try {
- Map<String, PropertyDefinition> properties = new HashMap<>();
- root = (JSONObject) parser.parse(data);
-
- Set entrySet = root.entrySet();
- Iterator iterator = entrySet.iterator();
- while (iterator.hasNext()) {
- Entry next = (Entry) iterator.next();
- String propertyName = (String) next.getKey();
- JSONObject value = (JSONObject) next.getValue();
- String jsonString = value.toJSONString();
- Either<PropertyDefinition, ActionStatus> convertJsonToObject = convertJsonToObject(jsonString, PropertyDefinition.class);
- if (convertJsonToObject.isRight()) {
- return Either.right(convertJsonToObject.right().value());
- }
- PropertyDefinition propertyDefinition = convertJsonToObject.left().value();
- String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId, (String) propertyName);
- propertyDefinition.setUniqueId(uniqueId);
- properties.put(propertyName, propertyDefinition);
- }
-
- return Either.left(properties);
- } catch (ParseException e) {
- log.info("Property conetnt is invalid - {}", data);
- return Either.right(ActionStatus.INVALID_CONTENT);
- }
- }
-
- private String propertyToJson(Map.Entry<String, PropertyDefinition> property) {
- JSONObject root = new JSONObject();
- String propertyName = property.getKey();
- PropertyDefinition propertyDefinition = property.getValue();
- JSONObject propertyDefinitionO = getPropertyDefinitionJSONObject(propertyDefinition);
- root.put(propertyName, propertyDefinitionO);
- propertyDefinition.getType();
- return root.toString();
- }
-
- private JSONObject getPropertyDefinitionJSONObject(PropertyDefinition propertyDefinition) {
-
- Either<String, ActionStatus> either = convertObjectToJson(propertyDefinition);
- if (either.isRight()) {
- return new JSONObject();
- }
- String value = either.left().value();
- try {
- return (JSONObject) new JSONParser().parse(value);
- } catch (ParseException e) {
- log.info("failed to convert input to json");
- log.debug("failed to convert to json", e);
- return new JSONObject();
- }
-
- }
-
- private <T> Either<T, ActionStatus> convertJsonToObject(String data, Class<T> clazz) {
- T t = null;
- Type constraintType = new TypeToken<PropertyConstraint>() {
- }.getType();
- Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()).create();
- try {
- log.trace("convert json to object. json=\n {}", data);
- t = gson.fromJson(data, clazz);
- if (t == null) {
- log.info("object is null after converting from json");
- return Either.right(ActionStatus.INVALID_CONTENT);
- }
- } catch (Exception e) {
- // INVALID JSON
- log.info("failed to convert from json");
- log.debug("failed to convert from json", e);
- return Either.right(ActionStatus.INVALID_CONTENT);
- }
- return Either.left(t);
- }
-
- private <T> Either<String, ActionStatus> convertObjectToJson(PropertyDefinition propertyDefinition) {
- Type constraintType = new TypeToken<PropertyConstraint>() {
- }.getType();
- Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintSerialiser()).create();
- try {
- log.trace("convert object to json. propertyDefinition= {}", propertyDefinition);
- String json = gson.toJson(propertyDefinition);
- if (json == null) {
- log.info("object is null after converting to json");
- return Either.right(ActionStatus.INVALID_CONTENT);
- }
- return Either.left(json);
- } catch (Exception e) {
- // INVALID JSON
- log.info("failed to convert to json");
- log.debug("failed to convert fto json", e);
- return Either.right(ActionStatus.INVALID_CONTENT);
- }
-
- }
-
- private PropertyBusinessLogic getPropertyBL(ServletContext context) {
- WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
- WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
- return webApplicationContext.getBean(PropertyBusinessLogic.class);
- }
-
-}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java
index ddb405779d..00b04a4ffc 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java
@@ -105,12 +105,6 @@ public class TypesFetchServlet extends AbstractValidationsServlet {
}
}
- private PropertyBusinessLogic getPropertyBL(ServletContext context) {
- WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
- WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
- return webApplicationContext.getBean(PropertyBusinessLogic.class);
- }
-
@GET
@Path("interfaceLifecycleTypes")
@Consumes(MediaType.APPLICATION_JSON)
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java
index 6a06c943a0..04119fed7b 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java
@@ -488,7 +488,7 @@ public class CapabilityRequirementConverter {
if (isNotEmpty(properties)) {
Map<String, ToscaProperty> toscaProperties = new HashMap<>();
for (PropertyDefinition property : properties) {
- ToscaProperty toscaProperty = PropertyConvertor.getInstance().convertProperty(dataTypes, property, true);
+ ToscaProperty toscaProperty = PropertyConvertor.getInstance().convertProperty(dataTypes, property, PropertyConvertor.PropertyType.CAPABILITY);
toscaProperties.put(property.getName(), toscaProperty);
}
toscaCapability.setProperties(toscaProperties);
@@ -520,7 +520,7 @@ public class CapabilityRequirementConverter {
if (isNotEmpty(properties)) {
Map<String, ToscaProperty> toscaProperties = new HashMap<>();
for (PropertyDefinition property : properties) {
- ToscaProperty toscaProperty = PropertyConvertor.getInstance().convertProperty(dataTypes, property, true);
+ ToscaProperty toscaProperty = PropertyConvertor.getInstance().convertProperty(dataTypes, property, PropertyConvertor.PropertyType.CAPABILITY);
toscaProperties.put(property.getName(), toscaProperty);
}
toscaCapability.setProperties(toscaProperties);
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 d128d5349f..04c7c69daa 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
@@ -20,11 +20,13 @@
package org.openecomp.sdc.be.tosca;
-import com.google.gson.Gson;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParser;
-import com.google.gson.stream.JsonReader;
-import fj.data.Either;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Supplier;
+
import org.apache.commons.lang3.StringUtils;
import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
@@ -35,6 +37,7 @@ import org.openecomp.sdc.be.model.Resource;
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;
+import org.openecomp.sdc.be.model.tosca.converters.ToscaStringConvertor;
import org.openecomp.sdc.be.model.tosca.converters.ToscaValueBaseConverter;
import org.openecomp.sdc.be.model.tosca.converters.ToscaValueConverter;
import org.openecomp.sdc.be.tosca.model.EntrySchema;
@@ -42,18 +45,24 @@ import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
import org.openecomp.sdc.be.tosca.model.ToscaProperty;
import org.openecomp.sdc.common.log.wrappers.Logger;
-import java.io.StringReader;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Supplier;
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+import com.google.gson.stream.JsonReader;
+
+import fj.data.Either;
public class PropertyConvertor {
private static PropertyConvertor instance;
private JsonParser jsonParser = new JsonParser();
private static final Logger log = Logger.getLogger(PropertyConvertor.class);
+ public enum PropertyType {
+ CAPABILITY,
+ INPUT,
+ PROPERTY
+ }
Gson gson = new Gson();
- protected PropertyConvertor() {
+ public PropertyConvertor() {
}
@@ -74,7 +83,7 @@ public class PropertyConvertor {
// take only the properties of this resource
props.stream().filter(p -> p.getOwnerId() == null || p.getOwnerId().equals(component.getUniqueId())).forEach(property -> {
- properties.put(property.getName(), convertProperty(dataTypes, property, false));
+ properties.put(property.getName(), convertProperty(dataTypes, property, PropertyType.PROPERTY));
});
if (!properties.isEmpty()) {
toscaNodeType.setProperties(properties);
@@ -84,7 +93,7 @@ public class PropertyConvertor {
return Either.left(toscaNodeType);
}
- public ToscaProperty convertProperty(Map<String, DataTypeDefinition> dataTypes, PropertyDataDefinition property, boolean isCapabiltyProperty) {
+ public ToscaProperty convertProperty(Map<String, DataTypeDefinition> dataTypes, PropertyDefinition property, PropertyType propertyType) {
ToscaProperty prop = new ToscaProperty();
String innerType = null;
@@ -96,22 +105,35 @@ public class PropertyConvertor {
eschema.setDescription(schema.getProperty().getDescription());
prop.setEntry_schema(eschema);
}
- return getToscaProperty(dataTypes, property, isCapabiltyProperty, prop, innerType);
+ return getToscaProperty(dataTypes, property, prop, innerType, propertyType);
}
- private ToscaProperty getToscaProperty(Map<String, DataTypeDefinition> dataTypes, PropertyDataDefinition property, boolean isCapabiltyProperty, ToscaProperty prop, String innerType) {
+ private ToscaProperty getToscaProperty(Map<String, DataTypeDefinition> dataTypes,
+ PropertyDataDefinition property,
+ ToscaProperty prop,
+ String innerType,
+ PropertyType propertyType) {
log.trace("try to convert property {} from type {} with default value [{}]", property.getName(), property.getType(), property.getDefaultValue());
- Object convertedObj = convertToToscaObject(property.getType(), property.getDefaultValue(), innerType, dataTypes, false);
+ String defaultValue = property.getDefaultValue();
+ if(Objects.isNull(defaultValue)) {
+ defaultValue = property.getValue();
+ }
+ Object convertedObj =
+ convertToToscaObject(property.getType(), defaultValue, innerType, dataTypes, false);
if (convertedObj != null) {
prop.setDefaultp(convertedObj);
}
prop.setType(property.getType());
prop.setDescription(property.getDescription());
- if (isCapabiltyProperty) {
- prop.setStatus(property.getStatus());
- }
prop.setRequired(property.isRequired());
+ switch (propertyType) {
+ case CAPABILITY:
+ prop.setStatus(property.getStatus());
+ break;
+ default:
+ break;
+ }
return prop;
}
@@ -198,9 +220,9 @@ public class PropertyConvertor {
}
private boolean valueStartsWithNonJsonChar(String value) {
- return value.startsWith("/") || value.startsWith(":") || value.startsWith("#");
+ return value.startsWith("/") || value.startsWith(":");
}
-
+
public void convertAndAddValue(Map<String, DataTypeDefinition> dataTypes,
Map<String, Object> props, PropertyDataDefinition prop, Supplier<String> supplier) {
Object convertedValue = convertValue(dataTypes, prop, supplier);
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 d0286d72d9..ecead12478 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
@@ -20,10 +20,11 @@
package org.openecomp.sdc.be.tosca;
-import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.addInterfaceDefinitionElement;
-import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.addInterfaceTypeElement;
-
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
import fj.data.Either;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.ImmutableTriple;
@@ -32,48 +33,24 @@ import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundExcept
import org.openecomp.sdc.be.config.ConfigurationManager;
import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
-import org.openecomp.sdc.be.model.ArtifactDefinition;
-import org.openecomp.sdc.be.model.CapabilityDefinition;
-import org.openecomp.sdc.be.model.Component;
-import org.openecomp.sdc.be.model.ComponentInstance;
-import org.openecomp.sdc.be.model.ComponentInstanceInput;
-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.GroupInstance;
-import org.openecomp.sdc.be.model.InputDefinition;
-import org.openecomp.sdc.be.model.InterfaceDefinition;
-import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.RelationshipInfo;
-import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
-import org.openecomp.sdc.be.model.RequirementDefinition;
-import org.openecomp.sdc.be.model.Resource;
-import org.openecomp.sdc.be.model.Service;
+import org.openecomp.sdc.be.model.*;
import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
import org.openecomp.sdc.be.model.category.CategoryDefinition;
import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
-import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
-import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
-import org.openecomp.sdc.be.tosca.model.ToscaCapability;
-import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate;
-import org.openecomp.sdc.be.tosca.model.ToscaMetadata;
-import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
-import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
-import org.openecomp.sdc.be.tosca.model.ToscaPolicyTemplate;
-import org.openecomp.sdc.be.tosca.model.ToscaProperty;
-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 org.openecomp.sdc.be.model.tosca.converters.ToscaValueBaseConverter;
+import org.openecomp.sdc.be.tosca.model.*;
import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
import org.openecomp.sdc.be.tosca.utils.InputConverter;
+import org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil;
import org.openecomp.sdc.common.log.wrappers.Logger;
-import org.openecomp.sdc.exception.ResponseFormat;
+import org.openecomp.sdc.externalupload.utils.ServiceUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
@@ -89,15 +66,8 @@ import org.yaml.snakeyaml.representer.Represent;
import org.yaml.snakeyaml.representer.Representer;
import java.beans.IntrospectionException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@@ -105,6 +75,8 @@ 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;
@org.springframework.stereotype.Component("tosca-export-handler")
public class ToscaExportHandler {
@@ -145,6 +117,8 @@ public class ToscaExportHandler {
private static final List<Map<String, Map<String, String>>> DEFAULT_IMPORTS = ConfigurationManager
.getConfigurationManager().getConfiguration().getDefaultImports();
+ public ToscaExportHandler(){}
+
public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
Either<ToscaTemplate, ToscaError> toscaTemplateRes = convertToToscaTemplate(component);
@@ -274,12 +248,16 @@ public class ToscaExportHandler {
}
List<ComponentInstance> componentInstances = component.getComponentInstances();
- Map<String, List<ComponentInstanceProperty>> componentInstancesProperties = component
- .getComponentInstancesProperties();
+ Map<String, List<ComponentInstanceProperty>> componentInstancesProperties =
+ component.getComponentInstancesProperties();
+ Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces =
+ component.getComponentInstancesInterfaces();
if (componentInstances != null && !componentInstances.isEmpty()) {
- Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates = convertNodeTemplates(component,
- componentInstances, componentInstancesProperties, componentCache, dataTypes, topologyTemplate);
+ Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates =
+ convertNodeTemplates(component, componentInstances,
+ componentInstancesProperties, componentInstanceInterfaces,
+ componentCache, dataTypes, topologyTemplate);
if (nodeTemplates.isRight()) {
return Either.right(nodeTemplates.right().value());
}
@@ -335,7 +313,27 @@ public class ToscaExportHandler {
return Either.left(toscaNode);
}
- private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
+ private Either<ToscaTopolgyTemplate, ToscaError> fillInputs(Component component,
+ ToscaTopolgyTemplate topologyTemplate, Map<String, DataTypeDefinition> dataTypes) {
+ if (log.isDebugEnabled()) {
+ log.debug("fillInputs for component {}", component.getUniqueId());
+ }
+ List<InputDefinition> inputDef = component.getInputs();
+ Map<String, ToscaProperty> inputs = new HashMap<>();
+
+ if (inputDef != null) {
+ inputDef.forEach(i -> {
+ ToscaProperty property = propertyConvertor.convertProperty(dataTypes, i, PropertyConvertor.PropertyType.INPUT);
+ inputs.put(i.getName(), property);
+ });
+ if (!inputs.isEmpty()) {
+ topologyTemplate.setInputs(inputs);
+ }
+ }
+ return Either.left(topologyTemplate);
+ }
+
+ private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) {
Map<String, ToscaGroupTemplate> groups = groupExportParser.getGroups(component);
@@ -436,8 +434,6 @@ public class ToscaExportHandler {
Map<String, Component> componentCache = new HashMap<>();
if (!ModelConverter.isAtomicComponent(component)) {
- List<ComponentInstance> componentInstances = component.getComponentInstances();
-
List<Map<String, Map<String, String>>> additionalImports = toscaTemplate.getImports() == null
? new ArrayList<>(DEFAULT_IMPORTS) : new ArrayList<>(toscaTemplate.getImports());
@@ -457,6 +453,7 @@ public class ToscaExportHandler {
additionalImports.add(importsListMember);
}
}
+ List<ComponentInstance> componentInstances = component.getComponentInstances();
if (componentInstances != null && !componentInstances.isEmpty()) {
componentInstances.forEach(ci -> createDependency(componentCache, additionalImports, dependecies, ci));
}
@@ -582,20 +579,35 @@ public class ToscaExportHandler {
Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
List<InputDefinition> inputDef = component.getInputs();
- Map<String, ToscaProperty> inputs = new HashMap<>();
- addInterfaceDefinitionElement(component, toscaNodeType, isAssociatedResourceComponent);
+ Map<String, ToscaProperty> mergedProperties = new HashMap<>();
+ addInterfaceDefinitionElement(component, toscaNodeType, dataTypes, isAssociatedResourceComponent);
if (inputDef != null) {
- inputDef.forEach(i -> {
- ToscaProperty property = propertyConvertor.convertProperty(dataTypes, i, false);
- inputs.put(i.getName(), property);
- });
- if (!inputs.isEmpty()) {
- toscaNodeType.setProperties(inputs);
- }
+ addInputsToProperties(dataTypes, inputDef, mergedProperties);
+ }
+
+ if(CollectionUtils.isNotEmpty(component.getProperties())) {
+ List<PropertyDefinition> properties = component.getProperties();
+ mergedProperties = properties.stream().collect(Collectors.toMap(
+ PropertyDataDefinition::getName,
+ property -> propertyConvertor.convertProperty(dataTypes, property, PropertyConvertor.PropertyType.PROPERTY)));
}
+ if (!mergedProperties.isEmpty()) {
+ toscaNodeType.setProperties(mergedProperties);
+ }
+ // Extracted to method for code reuse
return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
}
+ private void addInputsToProperties(Map<String, DataTypeDefinition> dataTypes,
+ List<InputDefinition> inputDef,
+ Map<String, ToscaProperty> mergedProperties) {
+ for(InputDefinition input : inputDef) {
+ ToscaProperty property = propertyConvertor.convertProperty(dataTypes, input, PropertyConvertor.PropertyType.INPUT);
+ mergedProperties.put(input.getName(), property);
+ }
+ }
+
+
private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache, Component component, ToscaTemplate toscaNode,
Map<String, ToscaNodeType> nodeTypes, ToscaNodeType toscaNodeType,
Map<String, DataTypeDefinition> dataTypes) {
@@ -635,9 +647,11 @@ public class ToscaExportHandler {
return Either.left(toscaNode);
}
- private Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(Component component,
+ protected Either<Map<String, ToscaNodeTemplate>, ToscaError> convertNodeTemplates(
+ Component component,
List<ComponentInstance> componentInstances,
Map<String, List<ComponentInstanceProperty>> componentInstancesProperties,
+ Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
Map<String, Component> componentCache, Map<String, DataTypeDefinition> dataTypes,
ToscaTopolgyTemplate topologyTemplate) {
@@ -704,7 +718,11 @@ public class ToscaExportHandler {
addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId,
props);
}
- if (!props.isEmpty()) {
+ //M3[00001] - NODE TEMPLATE INTERFACES - START
+ handleInstanceInterfaces(componentInstanceInterfaces, componentInstance, dataTypes, nodeTemplate,
+ instanceUniqueId, component);
+ //M3[00001] - NODE TEMPLATE INTERFACES - END
+ if (props != null && !props.isEmpty()) {
nodeTemplate.setProperties(props);
}
@@ -749,6 +767,70 @@ public class ToscaExportHandler {
return convertNodeTemplatesRes;
}
+ private void handleInstanceInterfaces(
+ Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces,
+ ComponentInstance componentInstance, Map<String, DataTypeDefinition> dataTypes, ToscaNodeTemplate nodeTemplate,
+ String instanceUniqueId,
+ Component parentComponent) {
+
+ Map<String, Object> interfaces;
+
+ // we need to handle service proxy interfaces
+ if(isComponentOfTypeServiceProxy(componentInstance)) {
+ if(MapUtils.isEmpty(componentInstanceInterfaces)
+ || !componentInstanceInterfaces.containsKey(instanceUniqueId)) {
+ interfaces = null;
+ } else {
+ List<ComponentInstanceInterface> currServiceInterfaces =
+ componentInstanceInterfaces.get(instanceUniqueId);
+
+ Map<String, InterfaceDefinition> tmpInterfaces = new HashMap<>();
+ currServiceInterfaces.forEach(instInterface -> tmpInterfaces.put(instInterface
+ .getUniqueId(), instInterface));
+
+ interfaces = InterfacesOperationsToscaUtil
+ .getInterfacesMap(parentComponent, tmpInterfaces, dataTypes, true, true);
+ }
+ } else {
+ interfaces =
+ getComponentInstanceInterfaceInstances(componentInstanceInterfaces,
+ componentInstance, instanceUniqueId);
+ }
+ nodeTemplate.setInterfaces(interfaces);
+ }
+
+ private boolean isComponentOfTypeServiceProxy(ComponentInstance componentInstance) {
+ return Objects.nonNull(componentInstance.getOriginType())
+ && componentInstance.getOriginType().getValue().equals("Service Proxy");
+ }
+
+ //M3[00001] - NODE TEMPLATE INTERFACES - START
+ private Map<String, Object> getComponentInstanceInterfaceInstances(Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaces,
+ ComponentInstance componentInstance,
+ String instanceUniqueId) {
+ if(MapUtils.isEmpty(componentInstancesInterfaces)) {
+ return null;
+ }
+
+ List<ComponentInstanceInterface> componentInstanceInterfaces =
+ componentInstancesInterfaces.get(instanceUniqueId);
+
+ if(CollectionUtils.isEmpty(componentInstanceInterfaces)) {
+ return null;
+ }
+
+ Map<String, Object> interfaces = new HashMap<>();
+ for(ComponentInstanceInterface componentInstanceInterface : componentInstanceInterfaces) {
+ interfaces.put(componentInstanceInterface.getInterfaceId(),
+ removeOperationsKeyFromInterface(componentInstanceInterface.getInterfaceInstanceDataDefinition()));
+ }
+
+ componentInstance.setInterfaces(interfaces);
+
+ return interfaces;
+ }
+ //M3[00001] - NODE TEMPLATE INTERFACES - END
+
private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
String instanceUniqueId, Map<String, Object> props) {
@@ -791,6 +873,34 @@ public class ToscaExportHandler {
}
}
+ /**
+ * @param dataTypes
+ * @param componentInstance
+ * @param props
+ * @param prop
+ * @param supplier
+ */
+ private void convertAndAddValue(Map<String, DataTypeDefinition> dataTypes, ComponentInstance componentInstance,
+ Map<String, Object> props, PropertyDefinition prop, Supplier<String> supplier) {
+ Object convertedValue = convertValue(dataTypes, componentInstance, prop, supplier);
+ if (!ToscaValueBaseConverter.isEmptyObjectValue(convertedValue)) {
+ props.put(prop.getName(), convertedValue);
+ }
+ }
+
+ private <T extends PropertyDefinition> Object convertValue(Map<String, DataTypeDefinition> dataTypes,
+ ComponentInstance componentInstance, T input, Supplier<String> supplier) {
+ log.debug("Convert property or input value {} for instance {}", input.getName(),
+ componentInstance.getUniqueId());
+ String propertyType = input.getType();
+ String innerType = null;
+ if (input.getSchema() != null && input.getSchema().getProperty() != null) {
+ innerType = input.getSchema().getProperty().getType();
+ }
+ return propertyConvertor.convertToToscaObject(propertyType, supplier.get(), innerType,
+ dataTypes, true);
+ }
+
private ToscaNodeType createNodeType(Component component) {
ToscaNodeType toscaNodeType = new ToscaNodeType();
if (ModelConverter.isAtomicComponent(component)) {
@@ -1128,5 +1238,22 @@ public class ToscaExportHandler {
}
}
+ private Object removeOperationsKeyFromInterface(Object interfaceInstanceDataDefinition) {
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
+
+ Map<String, Object> interfaceAsMap = ServiceUtils.getObjectAsMap(interfaceInstanceDataDefinition);
+ Map<String, Object> operations = (Map<String, Object>) interfaceAsMap.remove("operations");
+ interfaceAsMap.remove("empty");
+
+ if(MapUtils.isNotEmpty(operations)) {
+ interfaceAsMap.putAll(operations);
+ }
+
+ Object interfaceObject = objectMapper.convertValue(interfaceAsMap, Object.class);
+
+ return interfaceObject;
+
+ }
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplate.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplate.java
index c27944e8ee..b67a2cf233 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplate.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplate.java
@@ -20,6 +20,9 @@
package org.openecomp.sdc.be.tosca.model;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -30,6 +33,7 @@ public class ToscaNodeTemplate {
private Map<String, Object> properties;
private List<Map<String, ToscaTemplateRequirement>> requirements;
private Map<String, ToscaTemplateCapability> capabilities;
+ private Map<String, Object> interfaces;
public String getType() {
return type;
@@ -78,4 +82,17 @@ public class ToscaNodeTemplate {
public void setDescription(String description) {
this.description = description;
}
+
+ public void setInterfaces(
+ Map<String, Object> interfaces) {
+ this.interfaces = interfaces;
+ }
+
+ public void addInterface(String interfaceName, Object interfaceDataDefinition) {
+ if (MapUtils.isEmpty(this.interfaces)) {
+ this.interfaces = new HashMap<>();
+ }
+
+ this.interfaces.put(interfaceName, interfaceDataDefinition);
+ }
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InputConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InputConverter.java
index f6619b9aaa..c7e4d9b635 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InputConverter.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InputConverter.java
@@ -42,7 +42,8 @@ public class InputConverter {
if (inputDef != null) {
inputDef.forEach(i -> {
//Extract input the same as property
- ToscaProperty toscaProperty = propertyConvertor.convertProperty(dataTypes, i, false);
+ ToscaProperty toscaProperty = propertyConvertor.convertProperty(dataTypes, i,
+ PropertyConvertor.PropertyType.INPUT);
//now that we have Tosca property we create new object called tosca input which drives from it
ToscaInput toscaInput = new ToscaInput(toscaProperty);
List<Annotation> annotations = i.getAnnotations();
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java
index 106aa58133..a72f57d61c 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java
@@ -30,6 +30,7 @@ import org.apache.commons.collections.MapUtils;
import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.DataTypeDefinition;
import org.openecomp.sdc.be.model.InterfaceDefinition;
import org.openecomp.sdc.be.model.Product;
import org.openecomp.sdc.be.tosca.model.ToscaInterfaceDefinition;
@@ -103,6 +104,7 @@ public class InterfacesOperationsToscaUtil {
* @param nodeType to which the interfaces element will be added
*/
public static void addInterfaceDefinitionElement(Component component, ToscaNodeType nodeType,
+ Map<String, DataTypeDefinition> dataTypes,
boolean isAssociatedResourceComponent) {
if (component instanceof Product) {
return;
@@ -111,6 +113,28 @@ public class InterfacesOperationsToscaUtil {
if (MapUtils.isEmpty(interfaces)) {
return;
}
+ Map<String, Object> toscaInterfaceDefinitions = getInterfacesMap(component, dataTypes,
+ isAssociatedResourceComponent);
+ if (MapUtils.isNotEmpty(toscaInterfaceDefinitions)) {
+ nodeType.setInterfaces(toscaInterfaceDefinitions);
+ }
+ }
+
+ private static Map<String, Object> getInterfacesMap(Component component,
+ Map<String, DataTypeDefinition> dataTypes,
+ boolean isAssociatedResourceComponent) {
+ return getInterfacesMap(component, component.getInterfaces(), dataTypes, isAssociatedResourceComponent, false);
+ }
+
+ public static Map<String, Object> getInterfacesMap(Component component,
+ Map<String, InterfaceDefinition> interfaces,
+ Map<String, DataTypeDefinition> dataTypes,
+ boolean isAssociatedResourceComponent,
+ boolean isServiceProxyInterface) {
+ if(MapUtils.isEmpty(interfaces)) {
+ return null;
+ }
+
Map<String, Object> toscaInterfaceDefinitions = new HashMap<>();
for (InterfaceDefinition interfaceDefinition : interfaces.values()) {
ToscaInterfaceDefinition toscaInterfaceDefinition = new ToscaInterfaceDefinition();
@@ -137,13 +161,46 @@ public class InterfacesOperationsToscaUtil {
toscaInterfaceDefinition.setOperations(toscaOperations);
Map<String, Object> interfaceDefAsMap = getObjectAsMap(toscaInterfaceDefinition);
Map<String, Object> operationsMap = (Map<String, Object>) interfaceDefAsMap.remove(OPERATIONS_KEY);
- handleDefaults(operationsMap);
+ if (isServiceProxyInterface) {
+ handleServiceProxyOperationInputValue(operationsMap, interfaceType);
+ } else {
+ handleDefaults(operationsMap);
+ }
interfaceDefAsMap.putAll(operationsMap);
toscaInterfaceDefinitions.put(getLastPartOfName(interfaceType), interfaceDefAsMap);
}
- if (MapUtils.isNotEmpty(toscaInterfaceDefinitions)) {
- nodeType.setInterfaces(toscaInterfaceDefinitions);
+
+ return toscaInterfaceDefinitions;
+ }
+
+ private static void handleServiceProxyOperationInputValue(Map<String, Object> operationsMap, String parentKey) {
+ for (Map.Entry<String, Object> operationEntry : operationsMap.entrySet()) {
+ final Object value = operationEntry.getValue();
+ final String key = operationEntry.getKey();
+ if (value instanceof Map) {
+ if ("inputs".equals(parentKey)) {
+ Object defaultValue = getDefaultValue((Map<String, Object>) value);
+ operationsMap.put(key, defaultValue);
+ } else {
+ handleServiceProxyOperationInputValue((Map<String, Object>) value, key);
+ }
+ }
+ }
+ }
+
+ private static Object getDefaultValue(Map<String, Object> inputValueMap) {
+ Object defaultValue = null;
+ for (Map.Entry<String, Object> operationEntry : inputValueMap.entrySet()) {
+ final Object value = operationEntry.getValue();
+ if (value instanceof Map) {
+ getDefaultValue((Map<String, Object>) value);
+ }
+ final String key = operationEntry.getKey();
+ if (key.equals(DEFAULTP)) {
+ defaultValue = inputValueMap.remove(key);
+ }
}
+ return defaultValue;
}
/*
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/externalupload/utils/ServiceUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/externalupload/utils/ServiceUtils.java
new file mode 100644
index 0000000000..ba6f9c233c
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/externalupload/utils/ServiceUtils.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.externalupload.utils;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.commons.beanutils.BeanUtils;
+
+import java.lang.reflect.Field;
+import java.util.*;
+
+public class ServiceUtils {
+ private static final char[] CHARS = new char[]{
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+ private static final String TYPE = "type";
+ private static final String NODE = "node";
+
+ public static <T> Optional<T> createObjectUsingSetters(Object objectCandidate,
+ Class<T> classToCreate)
+ throws Exception {
+ if (Objects.isNull(objectCandidate)) {
+ return Optional.empty();
+ }
+
+ Map<String, Object> objectAsMap = getObjectAsMap(objectCandidate);
+ T result = classToCreate.newInstance();
+
+ List<Field> declaredFields = getAllFields(classToCreate);
+ for( Field field : declaredFields){
+ if(isComplexClass(field)){
+ Optional<?> objectUsingSetters =
+ createObjectUsingSetters(objectAsMap.get(field.getName()), field.getType());
+ if( objectUsingSetters.isPresent()){
+ objectAsMap.remove(field.getName());
+ objectAsMap.put(field.getName(), objectUsingSetters.get());
+ }
+ }
+ }
+ BeanUtils.populate(result, objectAsMap);
+
+ return Optional.of(result);
+ }
+
+ private static <T> List<Field> getAllFields(Class<T> clazz) {
+ List<Field> fields = new ArrayList<>();
+ for(Class<?> c = clazz; c != null; c = c.getSuperclass()) {
+ fields.addAll(Arrays.asList(c.getDeclaredFields()));
+ }
+
+ return fields;
+ }
+
+ private static boolean isComplexClass(Field field) {
+ return !field.getType().equals(Map.class)
+ && !field.getType().equals(String.class)
+ && !field.getType().equals(Integer.class)
+ && !field.getType().equals(Float.class)
+ && !field.getType().equals(Double.class)
+ && !field.getType().equals(Set.class)
+ && !field.getType().equals(Object.class)
+ && !field.getType().equals(List.class);
+ }
+ public static Map<String, Object> getObjectAsMap(Object obj) {
+ return new ObjectMapper().convertValue(obj, Map.class);
+ }
+
+ public static Set<String> getClassFieldNames(Class<? extends Object> classType) {
+ Set<String> fieldNames = new HashSet<>();
+ List<Field> allFields = getAllFields(classType);
+ allFields.forEach(field -> fieldNames.add(field.getName()));
+
+ return fieldNames;
+ }
+} \ No newline at end of file