aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-be/src/main
diff options
context:
space:
mode:
authorojasdubey <ojas.dubey@amdocs.com>2019-03-18 11:55:56 +0530
committerojasdubey <ojas.dubey@amdocs.com>2019-03-18 12:18:42 +0530
commit2ca2fc5c0da1eb862fcd79d1f9345aa89e62b396 (patch)
tree15d2cf2c7d6e9024430f735addf9e947d2814830 /catalog-be/src/main
parent532b6da80ebd6977aa27300ab3cbe7b21d88609a (diff)
Service Consumption BE
1. Service consumption feature backend implementation 2. Operation output bug fix for delete operation not allowed for mapped operation output Change-Id: Ib2554eed4f940b003955263a0c8bf795a23cac9a Issue-ID: SDC-1990 Signed-off-by: ojasdubey <ojas.dubey@amdocs.com>
Diffstat (limited to 'catalog-be/src/main')
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java3
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java18
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java156
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PropertyBusinessLogic.java17
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java453
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceInputsRedeclareHandler.java4
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceInterfacesMerge.java72
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceMergeDataBusinessLogic.java1
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/DataForMergeHolder.java10
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/property/DefaultPropertyDeclarator.java17
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java104
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java191
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java103
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java3
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceConsumptionServlet.java245
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java82
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java89
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/types/ServiceConsumptionData.java56
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/types/ServiceConsumptionSource.java49
-rw-r--r--catalog-be/src/main/resources/config/error-configuration.yaml14
20 files changed, 1412 insertions, 275 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java
index dfdae9be5e..d9a0c46fa9 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java
@@ -332,6 +332,9 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
resourceInstance.setProperties(ProxyServicePropertiesUtils.getProperties(service));
+ List<InputDefinition> serviceInputs = service.getInputs();
+ resourceInstance.setInputs(serviceInputs);
+
String name = service.getNormalizedName() + ToscaOperationFacade.PROXY_SUFFIX;
String toscaResourceName = ((Resource) proxyTemplate).getToscaResourceName();
int lastIndexOf = toscaResourceName.lastIndexOf('.');
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java
index 8a111f359e..357eb14ed0 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java
@@ -20,6 +20,13 @@
package org.openecomp.sdc.be.components.impl;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
import fj.data.Either;
import org.openecomp.sdc.be.components.property.PropertyDeclarationOrchestrator;
import org.openecomp.sdc.be.components.validation.ComponentValidations;
@@ -30,7 +37,13 @@ import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
-import org.openecomp.sdc.be.model.*;
+import org.openecomp.sdc.be.model.ComponentInstInputsMap;
+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.InputDefinition;
import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
@@ -40,8 +53,6 @@ import org.openecomp.sdc.exception.ResponseFormat;
import org.springframework.stereotype.Component;
import javax.inject.Inject;
-import java.util.*;
-import java.util.stream.Collectors;
@Component("inputsBusinessLogic")
public class InputsBusinessLogic extends BaseBusinessLogic {
@@ -279,6 +290,7 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
return Either.right(updateInputObjectValue.right().value());
}
String newValue = updateInputObjectValue.left().value();
+ currInput.setValue(newValue);
currInput.setDefaultValue(newValue);
currInput.setOwnerId(userId);
Either<InputDefinition, StorageOperationStatus> status = toscaOperationFacade.updateInputOfComponent(component, currInput);
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java
index 2fb7b0f09e..71d79e0410 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java
@@ -17,9 +17,17 @@
package org.openecomp.sdc.be.components.impl;
-import fj.data.Either;
+import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.createMappedInputPropertyDefaultValue;
+import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.createMappedOutputDefaultValue;
+import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getInterfaceDefinitionFromComponentByInterfaceId;
+import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getInterfaceDefinitionFromComponentByInterfaceType;
+import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getOperationFromInterfaceDefinition;
+import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToComponentInput;
+import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.SELF;
+
+import com.google.gson.Gson;
+
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -29,14 +37,21 @@ import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
-import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
+
+import fj.data.Either;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
import org.openecomp.sdc.be.components.validation.InterfaceOperationValidation;
import org.openecomp.sdc.be.dao.api.ActionStatus;
import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao;
import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus;
+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.enums.NodeTypeEnum;
import org.openecomp.sdc.be.model.ArtifactDefinition;
+import org.openecomp.sdc.be.model.ComponentInstanceInterface;
+import org.openecomp.sdc.be.model.InputDefinition;
import org.openecomp.sdc.be.model.InterfaceDefinition;
import org.openecomp.sdc.be.model.Operation;
import org.openecomp.sdc.be.model.User;
@@ -83,9 +98,8 @@ public class InterfaceOperationBusinessLogic extends BaseBusinessLogic {
}
try {
- Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
- .getInterfaceDefinitionFromComponentByInterfaceId(
- storedComponent, interfaceId);
+ Optional<InterfaceDefinition> optionalInterface = getInterfaceDefinitionFromComponentByInterfaceId(
+ storedComponent, interfaceId);
if (!optionalInterface.isPresent()) {
return Either.right(
componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceId));
@@ -95,13 +109,19 @@ public class InterfaceOperationBusinessLogic extends BaseBusinessLogic {
Map<String, Operation> operationsCollection = new HashMap<>();
for (String operationId : operationsToDelete) {
Optional<Map.Entry<String, Operation>> optionalOperation =
- InterfaceOperationUtils.getOperationFromInterfaceDefinition(interfaceDefinition, operationId);
+ getOperationFromInterfaceDefinition(interfaceDefinition, operationId);
if (!optionalOperation.isPresent()) {
return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND,
storedComponent.getUniqueId()));
}
Operation storedOperation = optionalOperation.get().getValue();
+ Either<Boolean, ResponseFormat> validateDeleteOperationContainsNoMappedOutputResponse =
+ interfaceOperationValidation.validateDeleteOperationContainsNoMappedOutput(storedOperation,
+ storedComponent, interfaceDefinition);
+ if (validateDeleteOperationContainsNoMappedOutputResponse.isRight()) {
+ return Either.right(validateDeleteOperationContainsNoMappedOutputResponse.right().value());
+ }
String artifactUuId = storedOperation.getImplementation().getArtifactUUID();
CassandraOperationStatus cassandraStatus = artifactCassandraDao.deleteArtifact(artifactUuId);
if (cassandraStatus != CassandraOperationStatus.OK) {
@@ -190,9 +210,8 @@ public class InterfaceOperationBusinessLogic extends BaseBusinessLogic {
}
try {
- Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
- .getInterfaceDefinitionFromComponentByInterfaceId(
- storedComponent, interfaceId);
+ Optional<InterfaceDefinition> optionalInterface = getInterfaceDefinitionFromComponentByInterfaceId(
+ storedComponent, interfaceId);
if (!optionalInterface.isPresent()) {
return Either.right(
componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceId));
@@ -201,7 +220,7 @@ public class InterfaceOperationBusinessLogic extends BaseBusinessLogic {
for (String operationId : operationsToGet) {
Optional<Map.Entry<String, Operation>> optionalOperation =
- InterfaceOperationUtils.getOperationFromInterfaceDefinition(interfaceDefinition, operationId);
+ getOperationFromInterfaceDefinition(interfaceDefinition, operationId);
if (!optionalOperation.isPresent()) {
return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND,
storedComponent.getUniqueId()));
@@ -257,7 +276,7 @@ public class InterfaceOperationBusinessLogic extends BaseBusinessLogic {
Map<String, Operation> operationsCollection = new HashMap<>();
for (InterfaceDefinition inputInterfaceDefinition : interfaceDefinitions) {
Optional<InterfaceDefinition> optionalInterface =
- InterfaceOperationUtils.getInterfaceDefinitionFromComponentByInterfaceType(
+ getInterfaceDefinitionFromComponentByInterfaceType(
storedComponent, inputInterfaceDefinition.getType());
Either<Boolean, ResponseFormat> interfaceOperationValidationResponseEither =
interfaceOperationValidation
@@ -287,7 +306,7 @@ public class InterfaceOperationBusinessLogic extends BaseBusinessLogic {
addOperationToInterface(interfaceDef, operation);
} else {
Optional<Map.Entry<String, Operation>> optionalOperation =
- InterfaceOperationUtils.getOperationFromInterfaceDefinition(interfaceDef,
+ getOperationFromInterfaceDefinition(interfaceDef,
operation.getUniqueId());
if (!optionalOperation.isPresent()) {
titanDao.rollback();
@@ -364,31 +383,53 @@ public class InterfaceOperationBusinessLogic extends BaseBusinessLogic {
InterfaceDefinition storedInterfaceDef) {
if (storedInterfaceDef != null) {
return Either.left(storedInterfaceDef);
- } else {
- interfaceDefinition.setUniqueId(UUID.randomUUID().toString());
- interfaceDefinition.setToscaResourceName(interfaceDefinition.getType());
- Either<List<InterfaceDefinition>, StorageOperationStatus> interfaceCreateEither =
- interfaceOperation.addInterfaces(component.getUniqueId(),
- Collections.singletonList(interfaceDefinition));
- if (interfaceCreateEither.isRight()) {
- titanDao.rollback();
- return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(
- interfaceCreateEither.right().value(), component.getComponentType())));
- }
- return Either.left(interfaceCreateEither.left().value().get(0));
}
+ interfaceDefinition.setUniqueId(UUID.randomUUID().toString());
+ interfaceDefinition.setToscaResourceName(interfaceDefinition.getType());
+ Either<List<InterfaceDefinition>, StorageOperationStatus> interfaceCreateEither =
+ interfaceOperation.addInterfaces(component.getUniqueId(),
+ Collections.singletonList(interfaceDefinition));
+ if (interfaceCreateEither.isRight()) {
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(
+ interfaceCreateEither.right().value(), component.getComponentType())));
+ }
+ return Either.left(interfaceCreateEither.left().value().get(0));
}
private void updateOperationInputDefs(org.openecomp.sdc.be.model.Component component,
- Collection<Operation> interfaceOperations) {
+ Collection<Operation> interfaceOperations) {
interfaceOperations.stream().filter(operation -> Objects.nonNull(operation.getInputs())).forEach(
operation -> operation.getInputs().getListToscaDataDefinition().forEach(
- inp -> component.getInputs().stream().filter(in -> inp.getInputId().equals(in.getUniqueId()))
- .forEach(in -> {
- inp.setDefaultValue(in.getDefaultValue());
- inp.setValue(in.getValue());
- inp.setSchema(in.getSchema());
- })));
+ inp -> component.getInputs()
+ .forEach(in -> updateOperationInputDefinition(component, inp, in))));
+ }
+
+ private void updateOperationInputDefinition(org.openecomp.sdc.be.model.Component component,
+ OperationInputDefinition operationInput,
+ InputDefinition componentInput) {
+ if (operationInput.getInputId().equals(componentInput.getUniqueId())) {
+ //Set the default value, value and schema only for inputs mapped to component inputs
+ operationInput.setDefaultValue(componentInput.getDefaultValue());
+ operationInput.setToscaDefaultValue(getInputToscaDefaultValue(operationInput, component));
+ operationInput.setValue(componentInput.getValue());
+ operationInput.setSchema(componentInput.getSchema());
+ }
+ //Set the tosca default value for inputs mapped to component inputs as well as other outputs
+ operationInput.setToscaDefaultValue(getInputToscaDefaultValue(operationInput, component));
+ }
+
+ private String getInputToscaDefaultValue(OperationInputDefinition input,
+ org.openecomp.sdc.be.model.Component component) {
+ Map<String, List<String>> defaultInputValue;
+ if (isOperationInputMappedToComponentInput(input, component.getInputs())) {
+ String propertyName = input.getInputId().substring(input.getInputId().indexOf('.') + 1);
+ defaultInputValue = createMappedInputPropertyDefaultValue(propertyName);
+ } else {
+ //Currently inputs can only be mapped to a declared input or an other operation outputs
+ defaultInputValue = createMappedOutputDefaultValue(SELF, input.getInputId());
+ }
+ return new Gson().toJson(defaultInputValue);
}
private void addOperationToInterface(InterfaceDefinition interfaceDefinition, Operation interfaceOperation) {
@@ -420,4 +461,55 @@ public class InterfaceOperationBusinessLogic extends BaseBusinessLogic {
UPDATE_INTERFACE_OPERATION, lock);
}
+ public Either<List<OperationInputDefinition>, ResponseFormat> getInputsListForOperation(String componentId,
+ String componentInstanceId, String interfaceId, String operationId, User user) {
+ Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither = getComponentDetails(componentId);
+ if (componentEither.isRight()){
+ return Either.right(componentEither.right().value());
+ }
+
+ org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
+ validateUserExists(user.getUserId(), GET_INTERFACE_OPERATION, true);
+
+ Either<Boolean, ResponseFormat> lockResult = lockComponentResult(true, storedComponent, GET_INTERFACE_OPERATION);
+ if (lockResult.isRight()) {
+ return Either.right(lockResult.right().value());
+ }
+
+ try{
+ org.openecomp.sdc.be.model.Component parentComponent = componentEither.left().value();
+ Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces =
+ parentComponent.getComponentInstancesInterfaces();
+ if(MapUtils.isEmpty(componentInstanceInterfaces)) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND,
+ componentInstanceId));
+ }
+
+ List<ComponentInstanceInterface> componentInstanceInterfaceList =
+ componentInstanceInterfaces.get(componentInstanceId);
+ for(ComponentInstanceInterface componentInstanceInterface : componentInstanceInterfaceList) {
+ if(componentInstanceInterface.getInterfaceId().equals(interfaceId)){
+ Map<String, OperationDataDefinition> operations = componentInstanceInterface.getOperations();
+ if(MapUtils.isNotEmpty(operations) && operations.containsKey(operationId)) {
+ ListDataDefinition<OperationInputDefinition> inputs = operations.get(operationId).getInputs();
+ return Either.left(CollectionUtils.isEmpty(inputs.getListToscaDataDefinition())
+ ? new ArrayList<>() : inputs.getListToscaDataDefinition());
+ }
+ }
+ }
+ return Either.left(new ArrayList<>());
+ }
+ catch (Exception e) {
+ LOGGER.error(EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION, "get", e);
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND));
+ }
+ finally {
+ if (lockResult.isLeft() && lockResult.left().value()) {
+ graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
+ NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
+ }
+ }
+ }
+
}
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 0439dd5ef6..3c49e21471 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
@@ -28,10 +28,20 @@ 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.*;
+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.*;
+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.operations.api.IElementOperation;
import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
@@ -377,7 +387,8 @@ public class PropertyBusinessLogic extends BaseBusinessLogic {
return Optional.empty();
}
- return operationInputsList.stream().filter(input -> input.getInputId().equals(propertyDefinition.getUniqueId())).findAny();
+ return operationInputsList.stream().filter(input -> input.getInputId().equals(propertyDefinition.getUniqueId())
+ || (input.getSourceProperty() != null && input.getSourceProperty().equals(propertyDefinition.getUniqueId()))).findAny();
}
/**
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java
index dfe1467a9c..65b1f12c03 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java
@@ -25,6 +25,7 @@ import com.google.common.base.Strings;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import fj.data.Either;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
@@ -36,6 +37,7 @@ import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
+import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
import org.openecomp.sdc.be.components.validation.NodeFilterValidator;
import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
import org.openecomp.sdc.be.config.BeEcompErrorManager;
@@ -47,9 +49,14 @@ import org.openecomp.sdc.be.datamodel.ServiceRelations;
import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
+import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition;
import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
import org.openecomp.sdc.be.datatypes.enums.InstantiationTypes;
+import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo;
@@ -65,11 +72,16 @@ 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.impl.UniqueIdBuilder;
import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
+import org.openecomp.sdc.be.model.tosca.ToscaFunctions;
+import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
+import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
import org.openecomp.sdc.be.resources.data.auditing.*;
import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
+import org.openecomp.sdc.be.types.ServiceConsumptionData;
+import org.openecomp.sdc.be.types.ServiceConsumptionSource;
import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
import org.openecomp.sdc.be.user.Role;
import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
@@ -83,6 +95,7 @@ import org.openecomp.sdc.common.util.ThreadLocalsHolder;
import org.openecomp.sdc.common.util.ValidationUtils;
import org.openecomp.sdc.exception.ResponseFormat;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
import org.springframework.web.context.WebApplicationContext;
import javax.servlet.ServletContext;
@@ -95,7 +108,12 @@ import java.util.stream.Collectors;
import static org.apache.commons.collections.CollectionUtils.isEmpty;
import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
+import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getOperationOutputName;
+import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToOtherOperationOutput;
import static org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum.UPDATE_SERVICE_METADATA;
+import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.SELF;
+import static org.openecomp.sdc.be.types.ServiceConsumptionSource.SERVICE_INPUT;
+import static org.openecomp.sdc.be.types.ServiceConsumptionSource.STATIC;
@org.springframework.stereotype.Component("serviceBusinessLogic")
public class ServiceBusinessLogic extends ComponentBusinessLogic {
@@ -227,6 +245,441 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
}
+ public Either<List<Operation>, ResponseFormat> addServiceConsumptionData(String serviceId,
+ String serviceInstanceId,
+ String operationId,
+ List<ServiceConsumptionData> serviceConsumptionDataList,
+ String userId) {
+ List<Operation> operationList = new ArrayList<>();
+
+ Either<Service, StorageOperationStatus> serviceEither =
+ toscaOperationFacade.getToscaElement(serviceId);
+ if(serviceEither.isRight()) {
+ return Either.right(componentsUtils.getResponseFormat
+ (serviceEither.right().value()));
+ }
+
+ Service service = serviceEither.left().value();
+
+
+ StorageOperationStatus storageOperationStatus =
+ graphLockOperation.lockComponent(service.getUniqueId(), NodeTypeEnum.Service);
+ if (storageOperationStatus != StorageOperationStatus.OK) {
+ return Either.right(componentsUtils.getResponseFormat(storageOperationStatus));
+ }
+
+ try {
+ for (ServiceConsumptionData serviceConsumptionData : serviceConsumptionDataList) {
+ Either<Operation, ResponseFormat> operationEither =
+ addPropertyServiceConsumption(serviceId, serviceInstanceId, operationId,
+ userId, serviceConsumptionData);
+
+ if (operationEither.isRight()) {
+ return Either.right(operationEither.right().value());
+ }
+
+ operationList.add(operationEither.left().value());
+ }
+
+ titanDao.commit();
+ return Either.left(operationList);
+ } catch (Exception e) {
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+
+ } finally {
+ graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
+
+ }
+ }
+
+ public Either <Operation, ResponseFormat> addPropertyServiceConsumption(String serviceId,
+ String serviceInstanceId,
+ String operationId,
+ String userId,
+ ServiceConsumptionData serviceConsumptionData) {
+ validateUserExists(userId, "create Property", false);
+
+ Either<Service, StorageOperationStatus> serviceEither =
+ toscaOperationFacade.getToscaElement(serviceId);
+ if(serviceEither.isRight()) {
+ return Either.right(componentsUtils.getResponseFormat(serviceEither.right
+ ().value()));
+ }
+
+ Service parentService = serviceEither.left().value();
+
+ List<ComponentInstance> componentInstances = parentService.getComponentInstances();
+ if(CollectionUtils.isEmpty(componentInstances)) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus
+ .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
+ }
+
+ Optional<ComponentInstance> serviceInstanceCandidate =
+ componentInstances.stream().filter(instance -> instance.getUniqueId().equals
+ (serviceInstanceId)).findAny();
+
+ if(!serviceInstanceCandidate.isPresent()) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus
+ .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
+ }
+
+ Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaces =
+ parentService.getComponentInstancesInterfaces();
+ if(MapUtils.isEmpty(componentInstancesInterfaces)) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus
+ .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
+ }
+
+ List<InterfaceDefinition> interfaces = new ArrayList<>();
+ for(ComponentInstanceInterface componentInstanceInterface :
+ componentInstancesInterfaces.get(serviceInstanceId)) {
+ interfaces.add(componentInstanceInterface);
+ }
+
+ ComponentInstance serviceInstance = serviceInstanceCandidate.get();
+ Optional<InterfaceDefinition> interfaceCandidate = InterfaceOperationUtils
+ .getInterfaceDefinitionFromOperationId(interfaces, operationId);
+
+ if(!interfaceCandidate.isPresent()) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus
+ .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
+ }
+
+ InterfaceDefinition interfaceDefinition = interfaceCandidate.get();
+ Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
+ if(MapUtils.isEmpty(operations)) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus
+ .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
+ }
+
+ Operation operation = operations.get(operationId);
+ Either<Operation, ResponseFormat> operationEither = Either.left(operation);
+
+ ListDataDefinition<OperationInputDefinition> inputs = operation.getInputs();
+ Optional<OperationInputDefinition> inputCandidate =
+ getOperationInputByInputId(serviceConsumptionData, inputs);
+
+ if(!inputCandidate.isPresent()) {
+ return Either.right(new ResponseFormat(HttpStatus.NOT_FOUND.value()));
+ }
+
+ OperationInputDefinition operationInputDefinition = inputCandidate.get();
+
+ // add data to operation
+
+ if(Objects.nonNull(serviceConsumptionData.getValue())) {
+ operationEither =
+ handleConsumptionValue(parentService, serviceInstanceId, serviceConsumptionData, operation,
+ operationInputDefinition);
+ }
+
+ if(operationEither.isRight()) {
+ return Either.right(operationEither.right().value());
+ }
+
+ Operation updatedOperation = operationEither.left().value();
+ operations.remove(operationId);
+ operations.put(operationId, updatedOperation);
+ interfaceDefinition.setOperationsMap(operations);
+
+ parentService.getComponentInstances().remove(serviceInstance);
+ if(CollectionUtils.isEmpty(parentService.getComponentInstances())) {
+ parentService.setComponentInstances(new ArrayList<>());
+ }
+
+ Map<String, Object> instanceInterfaces =
+ MapUtils.isEmpty(serviceInstance.getInterfaces())? new HashMap<>() : serviceInstance.getInterfaces();
+ instanceInterfaces.remove(interfaceDefinition.getUniqueId());
+ instanceInterfaces.put(interfaceDefinition.getUniqueId(), interfaceDefinition);
+ serviceInstance.setInterfaces(instanceInterfaces);
+
+ removeComponentInstanceInterfaceByInterfaceId(interfaceDefinition.getUniqueId(), componentInstancesInterfaces.get(serviceInstanceId));
+ componentInstancesInterfaces.get(serviceInstanceId).add(new ComponentInstanceInterface(interfaceDefinition.getUniqueId(), interfaceDefinition));
+
+ parentService.getComponentInstances().add(serviceInstance);
+
+ StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(parentService, serviceInstanceId);
+
+ if(status != StorageOperationStatus.OK) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus
+ .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
+ }
+
+ return Either.left(operation);
+ }
+
+ private void removeComponentInstanceInterfaceByInterfaceId(String interfaceIdToRemove,
+ List<ComponentInstanceInterface> instanceInterfaces) {
+ if(CollectionUtils.isEmpty(instanceInterfaces)) {
+ return;
+ }
+
+ Optional<ComponentInstanceInterface> interfaceToRemove =
+ instanceInterfaces.stream().filter(instInterface -> instInterface.getUniqueId().equals
+ (interfaceIdToRemove)).findAny();
+
+ if(interfaceToRemove.isPresent()) {
+ instanceInterfaces.remove(interfaceToRemove.get());
+ }
+
+ }
+
+ private Either<Operation, ResponseFormat> handleConsumptionValue(Service containerService,
+ String serviceInstanceId,
+ ServiceConsumptionData serviceConsumptionData,
+ Operation operation,
+ OperationInputDefinition
+ operationInputDefinition) {
+ String source = serviceConsumptionData.getSource();
+ String consumptionValue = serviceConsumptionData.getValue();
+ String type = serviceConsumptionData.getType();
+ String operationIdentifier = consumptionValue.contains(".")
+ ? consumptionValue.substring(0, consumptionValue.lastIndexOf('.'))
+ : consumptionValue;
+
+ ServiceConsumptionSource sourceValue = ServiceConsumptionSource.getSourceValue(source);
+
+ if(STATIC.equals(sourceValue)) {
+ return handleConsumptionStaticValue(consumptionValue, type, operation,
+ operationInputDefinition);
+ }
+
+ if (Objects.isNull(sourceValue)) {
+ List<PropertyDefinition> propertyDefinitions;
+ String componentName;
+ List<OperationOutputDefinition> outputs = null;
+ if (source.equals(containerService.getUniqueId())) {
+ Either<Service, StorageOperationStatus> serviceToTakePropEither =
+ toscaOperationFacade.getToscaElement(source);
+ if (serviceToTakePropEither.isRight()) {
+ return Either.right(componentsUtils.getResponseFormat(serviceToTakePropEither.right().value()));
+ }
+ Service service = serviceToTakePropEither.left().value();
+ operationInputDefinition.setSource(service.getUniqueId());
+ sourceValue = SERVICE_INPUT;
+ propertyDefinitions = service.getProperties();
+ componentName = service.getName();
+ outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier,
+ service.getInterfaces()).getListToscaDataDefinition();
+ } else {
+ Optional<ComponentInstance> getComponentInstance = containerService.getComponentInstanceById(source);
+ if(!getComponentInstance.isPresent()){
+ return Either.right(componentsUtils.getResponseFormat(
+ ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, source));
+ }
+ ComponentInstance componentInstance = getComponentInstance.get();
+ operationInputDefinition.setSource(componentInstance.getUniqueId());
+ propertyDefinitions = componentInstance.getProperties();
+ componentName = source.equals(serviceInstanceId) ? SELF : componentInstance.getName();
+ if (MapUtils.isNotEmpty(componentInstance.getInterfaces())) {
+ Map<String, InterfaceDataDefinition> componentInstanceInterfaces =
+ componentInstance.getInterfaces().entrySet().stream()
+ .collect(Collectors.toMap((Map.Entry::getKey),
+ (interfaceEntry -> (InterfaceDataDefinition) interfaceEntry.getValue())));
+ outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier,
+ componentInstanceInterfaces).getListToscaDataDefinition();
+ }
+ }
+
+ if(sourceValue == ServiceConsumptionSource.SERVICE_INPUT) {
+ //The operation input in service consumption has been mapped to an input in the parent service
+ return handleConsumptionInputValue(consumptionValue, containerService, operation,
+ operationInputDefinition);
+ }
+ return handleConsumptionPropertyValue(operation, operationInputDefinition,
+ serviceConsumptionData, propertyDefinitions, outputs, consumptionValue, componentName);
+ }
+
+ operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.SOURCE, source);
+ operationInputDefinition.setSource(source);
+
+ return Either.left(operation);
+ }
+
+ private Optional<OperationInputDefinition> getOperationInputByInputId(ServiceConsumptionData serviceConsumptionData,
+ ListDataDefinition<OperationInputDefinition> inputs) {
+
+ if(CollectionUtils.isEmpty(inputs.getListToscaDataDefinition())) {
+ return Optional.empty();
+ }
+
+ return inputs.getListToscaDataDefinition().stream().filter(operationInput -> operationInput.getInputId().equals
+ (serviceConsumptionData.getInputId()))
+ .findAny();
+ }
+
+ private Either<Operation, ResponseFormat> handleConsumptionPropertyValue(
+ Operation operation, OperationInputDefinition operationInputDefinition,
+ ServiceConsumptionData serviceConsumptionData, List<PropertyDefinition> properties,
+ List<OperationOutputDefinition> outputs, String consumptionValue, String componentName) {
+
+ if (CollectionUtils.isEmpty(properties) && CollectionUtils.isEmpty(outputs)) {
+ return Either.left(operation);
+ }
+
+ if (CollectionUtils.isNotEmpty(outputs)
+ && isOperationInputMappedToOtherOperationOutput(getOperationOutputName(consumptionValue), outputs)) {
+ return handleConsumptionInputMappedToOperationOutput(operation, operationInputDefinition, outputs,
+ consumptionValue, componentName);
+ }
+
+ if (CollectionUtils.isNotEmpty(properties)) {
+ return handleConsumptionInputMappedToProperty(operation, operationInputDefinition, serviceConsumptionData,
+ properties, componentName);
+ }
+ return Either.left(operation);
+ }
+
+ private Either<Operation, ResponseFormat> handleConsumptionInputMappedToProperty(Operation operation,
+ OperationInputDefinition operationInputDefinition, ServiceConsumptionData serviceConsumptionData,
+ List<PropertyDefinition> properties, String componentName) {
+ Optional<PropertyDefinition> servicePropertyCandidate =
+ properties.stream().filter(property -> property.getName()
+ .equals(serviceConsumptionData.getValue())).findAny();
+
+ if (servicePropertyCandidate.isPresent()) {
+ boolean isInputTypeSimilarToOperation =
+ isAssignedValueFromValidType(operationInputDefinition.getType(),
+ servicePropertyCandidate.get());
+
+ if (!isInputTypeSimilarToOperation) {
+ return Either.right(componentsUtils.getResponseFormat(
+ ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
+ }
+
+ addPropertyToInputValue(componentName, operation, operationInputDefinition,
+ servicePropertyCandidate.get());
+ }
+ return Either.left(operation);
+ }
+
+ private Either<Operation, ResponseFormat> handleConsumptionInputMappedToOperationOutput(Operation operation,
+ OperationInputDefinition operationInputDefinition, List<OperationOutputDefinition> outputs,
+ String consumptionValue, String componentName) {
+ String outputName = getOperationOutputName(consumptionValue);
+ Optional<OperationOutputDefinition> servicePropertyOutputCandidate = outputs.stream()
+ .filter(output -> output.getName().equals(outputName)).findAny();
+ if (servicePropertyOutputCandidate.isPresent()) {
+ boolean isInputTypeSimilarToOperation =
+ isAssignedValueFromValidType(operationInputDefinition.getType(),
+ servicePropertyOutputCandidate.get());
+ if (!isInputTypeSimilarToOperation) {
+ return Either.right(componentsUtils.getResponseFormat(
+ ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
+ }
+ addOutputToInputValue(componentName, consumptionValue, operation, operationInputDefinition);
+ }
+ return Either.left(operation);
+ }
+
+ private void addPropertyToInputValue(String componentName, Operation operation,
+ OperationInputDefinition operationInputDefinition,
+ PropertyDefinition serviceProperty) {
+ Map<String, List<String>> getProperty = new HashMap<>();
+ List<String> getPropertyValues = new ArrayList<>();
+ getPropertyValues.add(componentName);
+ getPropertyValues.add(serviceProperty.getName());
+ getProperty.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), getPropertyValues);
+
+ operationInputDefinition.setSourceProperty(serviceProperty.getUniqueId());
+ operation.getInputs().delete(operationInputDefinition);
+ operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_PROPERTY,
+ getPropertyValues);
+ operationInputDefinition.setValue((new Gson()).toJson(getProperty));
+ operation.getInputs().add(operationInputDefinition);
+ }
+
+ private void addOutputToInputValue(String componentName, String consumptionValue,
+ Operation operation, OperationInputDefinition operationInputDefinition) {
+ Map<String, List<String>> getOperationOutput =
+ InterfaceOperationUtils.createMappedOutputDefaultValue(componentName, consumptionValue);
+ operation.getInputs().delete(operationInputDefinition);
+ operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_OPERATION_OUTPUT,
+ getOperationOutput);
+ operationInputDefinition.setValue((new Gson()).toJson(getOperationOutput));
+ operation.getInputs().add(operationInputDefinition);
+ }
+
+ public Either<Operation, ResponseFormat> handleConsumptionStaticValue(String value, String type,
+ Operation operation,
+ OperationInputDefinition
+ operationInputDefinition) {
+ boolean isInputTypeSimilarToOperation =
+ isAssignedValueFromValidType(type, value);
+
+ if(!isInputTypeSimilarToOperation) {
+ return Either.right(componentsUtils.getResponseFormat(
+ ActionStatus.INVALID_CONSUMPTION_TYPE, type));
+ }
+ addStaticValueToInputOperation(value, operation, operationInputDefinition);
+
+ return Either.left(operation);
+ }
+
+ private void addStaticValueToInputOperation(String value, Operation operation,
+ OperationInputDefinition operationInputDefinition) {
+ operation.getInputs().delete(operationInputDefinition);
+ operationInputDefinition.setSource(STATIC.getSource());
+ operationInputDefinition.setSourceProperty(null);
+ operationInputDefinition.setValue(value);
+ operation.getInputs().add(operationInputDefinition);
+ }
+
+ private Either<Operation, ResponseFormat> handleConsumptionInputValue(String inputId,
+ Service service,
+ Operation operation,
+ OperationInputDefinition
+ operationInputDefinition) {
+ List<InputDefinition> serviceInputs = service.getInputs();
+ Optional<InputDefinition> inputForValue =
+ serviceInputs.stream().filter(input -> input.getUniqueId().contains(inputId)).findAny();
+
+ if(inputForValue.isPresent()) {
+ boolean isInputTypeSimilarToOperation =
+ isAssignedValueFromValidType(operationInputDefinition.getType(), inputForValue.get());
+
+ if(!isInputTypeSimilarToOperation) {
+ return Either.right(componentsUtils.getResponseFormat(
+ ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
+ }
+ addGetInputValueToOperationInput(operation, operationInputDefinition, inputForValue.get());
+ }
+
+ return Either.left(operation);
+ }
+
+
+ private boolean isAssignedValueFromValidType(String operationInputType, Object actualValue) {
+ if (actualValue instanceof String) {
+ // validate static value
+ ToscaPropertyType actualType = ToscaPropertyType.isValidType(operationInputType);
+ PropertyTypeValidator validator = actualType.getValidator();
+ return validator.isValid((String)actualValue, operationInputType);
+ } else if (actualValue instanceof PropertyDefinition) {
+ // validate input / property value
+ String actualType = ((PropertyDefinition) actualValue).getType();
+ return actualType.equalsIgnoreCase(operationInputType);
+ } else if (actualValue instanceof OperationOutputDefinition) {
+ // validate input / output value
+ String actualType = ((OperationOutputDefinition) actualValue).getType();
+ return actualType.equalsIgnoreCase(operationInputType);
+ }
+ return false;
+ }
+
+ private void addGetInputValueToOperationInput(Operation operation,
+ OperationInputDefinition operationInputDefinition,
+ InputDefinition inputForValue) {
+ operation.getInputs().delete(operationInputDefinition);
+ Map<String, String> getInputMap = new HashMap<>();
+ getInputMap.put(ToscaFunctions.GET_INPUT.getFunctionName(), inputForValue.getName());
+ operationInputDefinition.setSourceProperty(inputForValue.getUniqueId());
+ operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_INPUT, getInputMap);
+ operationInputDefinition.setValue(new Gson().toJson(getInputMap));
+ operation.getInputs().add(operationInputDefinition);
+ }
+
private Either<List<Map<String, Object>>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) {
// First Query
Either<List<ResourceAdminEvent>, ActionStatus> eitherprevVerAudit = auditCassandraDao.getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion);
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceInputsRedeclareHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceInputsRedeclareHandler.java
index a60b0f0773..c09fb91d1f 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceInputsRedeclareHandler.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceInputsRedeclareHandler.java
@@ -21,6 +21,7 @@ import static java.util.Collections.singletonMap;
import static java.util.stream.Collectors.toList;
import static org.apache.commons.collections.CollectionUtils.isEmpty;
import static org.openecomp.sdc.be.dao.utils.MapUtil.toMap;
+import static org.openecomp.sdc.be.utils.PropertyDefinitionUtils.resolveGetInputProperties;
@org.springframework.stereotype.Component
public class ComponentInstanceInputsRedeclareHandler {
@@ -43,7 +44,8 @@ public class ComponentInstanceInputsRedeclareHandler {
Map<String, List<PropertyDataDefinition>> allPropertiesForInstance = getAllGetPropertiesForInstance(container, newInstanceId);
List<InputDefinition> previouslyDeclaredInputs = declaredInputsResolver.getPreviouslyDeclaredInputsToMerge(oldInputs, container, allPropertiesForInstance);
inputsValuesMergingBusinessLogic.mergeComponentInputs(oldInputs, previouslyDeclaredInputs);
- updateInputsAnnotations(allPropertiesForInstance.get(newInstanceId), newInstanceOriginType, previouslyDeclaredInputs);
+ Map<String, List<PropertyDataDefinition>> getInputProperties = resolveGetInputProperties(allPropertiesForInstance);
+ updateInputsAnnotations(getInputProperties.get(newInstanceId), newInstanceOriginType, previouslyDeclaredInputs);
return updateInputs(container.getUniqueId(), previouslyDeclaredInputs);
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceInterfacesMerge.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceInterfacesMerge.java
new file mode 100644
index 0000000000..60e60b0408
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceInterfacesMerge.java
@@ -0,0 +1,72 @@
+package org.openecomp.sdc.be.components.merge.instance;
+
+import fj.data.Either;
+import java.util.List;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
+import org.openecomp.sdc.be.impl.ComponentsUtils;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.ComponentInstance;
+import org.openecomp.sdc.be.model.ComponentInstanceInterface;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.exception.ResponseFormat;
+import org.springframework.beans.factory.annotation.Autowired;
+
+@org.springframework.stereotype.Component("ComponentInstanceInterfacesMerge")
+public class ComponentInstanceInterfacesMerge implements ComponentInstanceMergeInterface {
+
+ @Autowired
+ private ComponentsUtils componentsUtils;
+
+ @Autowired
+ private ToscaOperationFacade toscaOperationFacade;
+
+ @Override
+ public void saveDataBeforeMerge(DataForMergeHolder dataHolder, Component containerComponent, ComponentInstance currentResourceInstance, Component originComponent) {
+ dataHolder.setOrigInstanceNode(originComponent);
+ dataHolder.setOrigComponentInstanceInterfaces(containerComponent.safeGetComponentInstanceInterfaces(currentResourceInstance.getUniqueId()));
+ }
+
+ @Override
+ public Either<Component, ResponseFormat> mergeDataAfterCreate(User user, DataForMergeHolder dataHolder, Component updatedContainerComponent, String newInstanceId) {
+ List<ComponentInstanceInterface> origInstanceInterfaces = dataHolder.getOrigComponentInstanceInterfaces();
+ ActionStatus mergeStatus = mergeComponentInstanceInterfaces(updatedContainerComponent, newInstanceId, origInstanceInterfaces);
+ return Either.iif(!ActionStatus.OK.equals(mergeStatus), () -> componentsUtils.getResponseFormat(mergeStatus), () -> updatedContainerComponent);
+ }
+
+ private ActionStatus mergeComponentInstanceInterfaces(Component currentComponent, String instanceId, List<ComponentInstanceInterface> prevInstanceInterfaces) {
+ if (CollectionUtils.isEmpty(prevInstanceInterfaces) || MapUtils.isEmpty(currentComponent.getComponentInstancesInterfaces())) {
+ return ActionStatus.OK;
+ }
+
+ if(CollectionUtils.isEmpty(currentComponent.getComponentInstancesInterfaces().get(instanceId))){
+ return ActionStatus.OK;
+ }
+
+ currentComponent.getComponentInstancesInterfaces().get(instanceId).stream()
+ .forEach(newInterfaceDef -> newInterfaceDef.getOperationsMap().values()
+ .forEach(newOperationDef -> prevInstanceInterfaces.stream().filter(in -> in.getUniqueId().equals(newInterfaceDef.getUniqueId()))
+ .forEach(prevInterfaceDef -> prevInterfaceDef.getOperationsMap().values().stream().filter(in1 -> in1.getUniqueId().equals(newOperationDef.getUniqueId()))
+ .forEach(oldOperationDef -> mergeOperationInputDefinitions(oldOperationDef.getInputs(), newOperationDef.getInputs())))));
+
+ StorageOperationStatus updateStatus = toscaOperationFacade.updateComponentInstanceInterfaces(currentComponent, instanceId);
+ return componentsUtils.convertFromStorageResponse(updateStatus);
+ }
+
+
+ private void mergeOperationInputDefinitions(ListDataDefinition<OperationInputDefinition> origInputs, ListDataDefinition<OperationInputDefinition> newInputs){
+ newInputs.getListToscaDataDefinition()
+ .forEach(inp -> origInputs.getListToscaDataDefinition().stream().filter(in -> in.getInputId().equals(inp.getInputId()))
+ .forEach(in -> {
+ inp.setSourceProperty(in.getSourceProperty());
+ inp.setSource(in.getSource());
+ inp.setValue(in.getValue());
+ }));
+ }
+
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceMergeDataBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceMergeDataBusinessLogic.java
index 81e2f4ce7b..31b3207d6c 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceMergeDataBusinessLogic.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/ComponentInstanceMergeDataBusinessLogic.java
@@ -92,6 +92,7 @@ public class ComponentInstanceMergeDataBusinessLogic {
filter.setIgnoreCapabiltyProperties(false);
filter.setIgnoreArtifacts(false);
filter.setIgnoreForwardingPath(false);
+ filter.setIgnoreComponentInstancesInterfaces(false);
return toscaOperationFacade.getToscaElement(containerComponentId, filter);
}
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/DataForMergeHolder.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/DataForMergeHolder.java
index 7388819ebf..b159cd510c 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/DataForMergeHolder.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/instance/DataForMergeHolder.java
@@ -22,6 +22,7 @@ public class DataForMergeHolder {
private Component origInstanceNode;
private Component currInstanceNode;
private String origComponentInstId;
+ private List<ComponentInstanceInterface> origComponentInstanceInterfaces;
public DataForMergeHolder() {
origComponentInstanceInputs = new ArrayList<>();
@@ -30,6 +31,7 @@ public class DataForMergeHolder {
origCompInstDeploymentArtifactsCreatedOnTheInstance = new HashMap<>();
origCompInstDeploymentArtifactsCreatedOnTheInstance = new HashMap<>();
origInstanceCapabilities = new ArrayList<>();
+ origComponentInstanceInterfaces = new ArrayList<>();
}
List<ArtifactDefinition> getOrigComponentInstanceHeatEnvArtifacts() {
@@ -155,4 +157,12 @@ public class DataForMergeHolder {
public void setOrigComponentInstId(String origComponentInstId) {
this.origComponentInstId = origComponentInstId;
}
+
+ public List<ComponentInstanceInterface> getOrigComponentInstanceInterfaces() {
+ return origComponentInstanceInterfaces;
+ }
+
+ public void setOrigComponentInstanceInterfaces(List<ComponentInstanceInterface> origComponentInstanceInterfaces) {
+ this.origComponentInstanceInterfaces = origComponentInstanceInterfaces;
+ }
}
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 06e8db0f05..bd7a58c48a 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
@@ -75,8 +75,6 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties
private InputDefinition declarePropertyInput(String componentId, PROPERTYOWNER propertiesOwner, List<PROPERTYTYPE> declaredProperties, ComponentInstancePropInput propInput) {
PropertyDataDefinition prop = resolveProperty(declaredProperties, propInput);
- propInput.setOwnerId(null);
- propInput.setParentUniqueId(null);
InputDefinition inputDefinition = createInput(componentId, propertiesOwner, propInput, prop);
PROPERTYTYPE declaredProperty = createDeclaredProperty(prop);
if(!declaredProperties.contains(declaredProperty)){
@@ -86,15 +84,19 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties
return inputDefinition;
}
- private InputDefinition createInput(String componentId, PROPERTYOWNER propertiesOwner, ComponentInstancePropInput propInput, PropertyDataDefinition prop) {
- String generatedInputName = generateInputName(propertiesOwner instanceof
- Service ? null : propertiesOwner.getNormalizedName(),
- propInput);
+ private InputDefinition createInput(String componentId, PROPERTYOWNER propertiesOwner,
+ ComponentInstancePropInput propInput, PropertyDataDefinition prop) {
+ String generatedInputPrefix = propertiesOwner.getNormalizedName();
+ if (propertiesOwner.getUniqueId().equals(propInput.getParentUniqueId())) {
+ //Creating input from property create on self using add property..Do not add the prefix
+ generatedInputPrefix = null;
+ }
+ String generatedInputName = generateInputName(generatedInputPrefix, propInput);
return createInputFromProperty(componentId, propertiesOwner, generatedInputName, propInput, prop);
}
private String generateInputName(String inputName, ComponentInstancePropInput propInput) {
- String declaredInputName = inputName;
+ String declaredInputName;
String[] parsedPropNames = propInput.getParsedPropNames();
if(parsedPropNames != null){
@@ -154,7 +156,6 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties
input.setInputPath(propertiesName);
input.setInstanceUniqueId(propertiesOwner.getUniqueId());
input.setPropertyId(propInput.getUniqueId());
- input.setValue(null);
changePropertyValueToGetInputValue(inputName, parsedPropNames, input, prop, complexProperty);
if(prop instanceof IComponentInstanceConnectedElement) {
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java
index 6615e9ef37..2727a8b94a 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java
@@ -16,17 +16,27 @@
package org.openecomp.sdc.be.components.utils;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
+import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
+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.OperationOutputDefinition;
import org.openecomp.sdc.be.model.Component;
import org.openecomp.sdc.be.model.InputDefinition;
import org.openecomp.sdc.be.model.InterfaceDefinition;
import org.openecomp.sdc.be.model.Operation;
+import org.openecomp.sdc.be.model.tosca.ToscaFunctions;
+import org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil;
public class InterfaceOperationUtils {
@@ -66,7 +76,17 @@ public class InterfaceOperationUtils {
.filter(entry -> entry.getValue().getUniqueId().equals(operationId)).findAny();
}
- public static boolean isOperationInputMappedToComponentProperty(OperationInputDefinition input,
+ public static Optional<InterfaceDefinition> getInterfaceDefinitionFromOperationId(List<InterfaceDefinition> interfaces,
+ String operationId) {
+ if (CollectionUtils.isEmpty(interfaces)) {
+ return Optional.empty();
+ }
+ return interfaces.stream()
+ .filter(interfaceDefinition -> interfaceDefinition.getOperationsMap().containsKey(operationId))
+ .findAny();
+ }
+
+ public static boolean isOperationInputMappedToComponentInput(OperationInputDefinition input,
List<InputDefinition> inputs) {
if (CollectionUtils.isEmpty(inputs)) {
return false;
@@ -77,5 +97,87 @@ public class InterfaceOperationUtils {
input.getInputId().substring(0, input.getInputId().lastIndexOf('.'))))) ;
}
+ public static boolean isOperationInputMappedToOtherOperationOutput(String outputName,
+ List<OperationOutputDefinition>
+ otherOperationOutputs) {
+ if (CollectionUtils.isEmpty(otherOperationOutputs)) {
+ return false;
+ }
+ return otherOperationOutputs.stream()
+ .anyMatch(output -> output.getName().equals(outputName));
+
+ }
+ public static Map<String, List<String>> createMappedInputPropertyDefaultValue(String propertyName) {
+ Map<String, List<String>> getPropertyMap = new HashMap<>();
+ List<String> values = new ArrayList<>();
+ values.add(InterfacesOperationsToscaUtil.SELF);
+ if (Objects.nonNull(propertyName) && !propertyName.isEmpty()) {
+ values.addAll(Arrays.asList(propertyName.split("\\.")));
+ }
+ getPropertyMap.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), values);
+ return getPropertyMap;
+ }
+
+ /**
+ * Get the list of outputs of other operations of all the interfaces in the component.
+ * @param currentOperationIdentifier Fully qualified operation name e.g. org.test.interfaces.node.lifecycle.Abc.stop
+ * @param componentInterfaces VF or service interfaces
+ */
+
+ public static ListDataDefinition<OperationOutputDefinition> getOtherOperationOutputsOfComponent(
+ String currentOperationIdentifier, Map<String, ? extends InterfaceDataDefinition> componentInterfaces) {
+ ListDataDefinition<OperationOutputDefinition> componentOutputs = new ListDataDefinition<>();
+ if (MapUtils.isEmpty(componentInterfaces)) {
+ return componentOutputs;
+ }
+ for (Map.Entry<String, ? extends InterfaceDataDefinition> interfaceDefinitionEntry :
+ componentInterfaces.entrySet()) {
+ String interfaceName = interfaceDefinitionEntry.getKey();
+ final Map<String, OperationDataDefinition> operations = interfaceDefinitionEntry.getValue().getOperations();
+ if (MapUtils.isEmpty(operations)) {
+ continue;
+ }
+ for (Map.Entry<String, OperationDataDefinition> operationEntry : operations.entrySet()) {
+ ListDataDefinition<OperationOutputDefinition> outputs = operationEntry.getValue().getOutputs();
+ String expectedOperationIdentifier = interfaceName + "." + operationEntry.getKey();
+ if (!currentOperationIdentifier.equals(expectedOperationIdentifier) && !outputs.isEmpty()) {
+ outputs.getListToscaDataDefinition().forEach(componentOutputs::add);
+ }
+ }
+ }
+ return componentOutputs;
+ }
+
+ /**
+ * Create the value for operation input mapped to an operation output.
+ * @param propertyName the mapped other operation output full name
+ * @return input map for tosca
+ */
+ public static Map<String, List<String>> createMappedOutputDefaultValue(String componentName, String propertyName) {
+ Map<String, List<String>> getOperationOutputMap = new HashMap<>();
+ //For operation input mapped to other operation output parameter, the mapped property value
+ // should be of the format <interface name>.<operation name>.<output parameter name>
+ // Operation name and output param name should not contain "."
+ List<String> defaultMappedOperationOutputValue = new ArrayList<>();
+ String[] tokens = propertyName.split("\\.");
+ if (tokens.length > 2) {
+ defaultMappedOperationOutputValue.add(componentName);
+ String outputPropertyName = tokens[tokens.length - 1];
+ String operationName = tokens[tokens.length - 2];
+ String mappedPropertyInterfaceType =
+ propertyName.substring(0, propertyName.indexOf(operationName + '.' + outputPropertyName) - 1);
+ defaultMappedOperationOutputValue.addAll(Arrays.asList(mappedPropertyInterfaceType, operationName,
+ outputPropertyName));
+ getOperationOutputMap.put(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName(),
+ defaultMappedOperationOutputValue);
+ }
+ return getOperationOutputMap;
+ }
+
+ public static String getOperationOutputName(String fullOutputIdentifier) {
+ return fullOutputIdentifier.contains(".")
+ ? fullOutputIdentifier.substring(fullOutputIdentifier.lastIndexOf('.') + 1)
+ : fullOutputIdentifier;
+ }
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java
index 250fc03c21..f84c9a4d86 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java
@@ -16,10 +16,12 @@
package org.openecomp.sdc.be.components.validation;
-import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToComponentProperty;
+import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getOperationOutputName;
+import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getOtherOperationOutputsOfComponent;
+import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToComponentInput;
import com.google.common.collect.Sets;
-import fj.data.Either;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -32,10 +34,13 @@ import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+
+import fj.data.Either;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
+import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
import org.openecomp.sdc.be.dao.api.ActionStatus;
import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
@@ -90,16 +95,49 @@ public class InterfaceOperationValidation {
return Either.left(Boolean.TRUE);
}
+ public Either<Boolean, ResponseFormat> validateDeleteOperationContainsNoMappedOutput(
+ Operation interfaceOperationToDelete, org.openecomp.sdc.be.model.Component component,
+ InterfaceDefinition storedInterfaceDefinition) {
+ ResponseFormatManager responseFormatManager = getResponseFormatManager();
+ List<OperationOutputDefinition> existingOperationOutputs =
+ getInterfaceOperationOutputs(interfaceOperationToDelete.getUniqueId(), component.getInterfaces());
+ if (existingOperationOutputs.isEmpty()) {
+ return Either.left(Boolean.TRUE);
+ }
+ String mappedOutputPrefix = storedInterfaceDefinition.getType() + "." + interfaceOperationToDelete.getName();
+ List<OperationInputDefinition> interfaceOperationInputs =
+ getOtherOperationInputsOfComponent(mappedOutputPrefix, component.getInterfaces());
+ Set<String> mappedOutputsInDeletedOperation = new HashSet<>();
+ Set<String> existingOperationOutputNames = existingOperationOutputs.stream()
+ .map(OperationOutputDefinition::getName)
+ .collect(Collectors.toSet());
+ for (String existingOperationOutputName : existingOperationOutputNames) {
+ Set<String> matchedOutputsMappedToInputs = interfaceOperationInputs.stream()
+ .filter(operationInputDefinition -> operationInputDefinition.getInputId()
+ .equals(mappedOutputPrefix + "." + existingOperationOutputName))
+ .map(operationInputDefinition -> getOperationOutputName(operationInputDefinition.getInputId()))
+ .collect(Collectors.toSet());
+ mappedOutputsInDeletedOperation.addAll(matchedOutputsMappedToInputs);
+ }
+
+ if (CollectionUtils.isNotEmpty(mappedOutputsInDeletedOperation)) {
+ return getMappedOutputErrorResponse(responseFormatManager, mappedOutputsInDeletedOperation,
+ "Cannot delete interface operation with output(s) '{}' mapped to another operation input",
+ ActionStatus.INTERFACE_OPERATION_DELETE_WITH_MAPPED_OUTPUT);
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
private Either<Boolean, ResponseFormat> validateAllowedOperationCountOnLocalInterfaceType(
InterfaceDefinition inputInterfaceDefinition, InterfaceDefinition storedInterfaceDefinition,
Map<String, InterfaceDefinition> globalInterfaceTypes, boolean isUpdate) {
boolean isInterfaceTypeExistInGlobalType =
globalInterfaceTypes.values().stream().map(InterfaceDefinition::getType)
- .anyMatch(type -> type.equalsIgnoreCase(inputInterfaceDefinition.getType()));
- if (!isInterfaceTypeExistInGlobalType && (inputInterfaceDefinition.getOperations().size() > 1
- || (!isUpdate && storedInterfaceDefinition != null
- && storedInterfaceDefinition.getType().equalsIgnoreCase(inputInterfaceDefinition.getType())))) {
+ .anyMatch(type -> type.equalsIgnoreCase(inputInterfaceDefinition.getType()));
+ if (!isInterfaceTypeExistInGlobalType
+ && isValidOperationOnLocalInterfaceType(inputInterfaceDefinition, storedInterfaceDefinition,
+ isUpdate)) {
return Either.right(getResponseFormatManager()
.getResponseFormat(ActionStatus.INTERFACE_OPERATION_INVALID_FOR_LOCAL_TYPE,
inputInterfaceDefinition.getType()));
@@ -108,22 +146,32 @@ public class InterfaceOperationValidation {
return Either.left(Boolean.TRUE);
}
+ private boolean isValidOperationOnLocalInterfaceType(InterfaceDefinition inputInterfaceDefinition,
+ InterfaceDefinition storedInterfaceDefinition,
+ boolean isUpdate) {
+ return inputInterfaceDefinition.getOperations().size() > 1
+ || (!isUpdate && storedInterfaceDefinition != null
+ && storedInterfaceDefinition.getType()
+ .equalsIgnoreCase(inputInterfaceDefinition.getType()));
+ }
+
private Either<Boolean, ResponseFormat> validateAllowedOperationsOnGlobalInterfaceType(
InterfaceDefinition interfaceDefinition, Map<String, InterfaceDefinition> globalInterfaceTypes) {
- if (globalInterfaceTypes != null) {
- boolean isOperationValidOnGlobalInterfaceType = Stream.of(interfaceDefinition)
- .filter(interfaceDef -> globalInterfaceTypes.values().stream().anyMatch(interfaceDef1 ->
- interfaceDef1.getType().equalsIgnoreCase(interfaceDef.getType())))
- .flatMap(interfaceDef -> interfaceDef.getOperationsMap().values().stream().map(Operation::getName))
- .allMatch(operationName -> globalInterfaceTypes.values().stream()
- .flatMap(interfaceDef -> interfaceDef.getOperationsMap().keySet().stream())
- .anyMatch(opName -> opName.equalsIgnoreCase(operationName)));
- if (!isOperationValidOnGlobalInterfaceType) {
- return Either.right(getResponseFormatManager()
- .getResponseFormat(ActionStatus.INTERFACE_OPERATION_INVALID_FOR_GLOBAL_TYPE,
- interfaceDefinition.getType()));
- }
+ if (globalInterfaceTypes == null) {
+ return Either.left(Boolean.TRUE);
+ }
+ boolean isOperationValidOnGlobalInterfaceType = Stream.of(interfaceDefinition)
+ .filter(interfaceDef -> globalInterfaceTypes.values().stream().anyMatch(interfaceDef1 ->
+ interfaceDef1.getType().equalsIgnoreCase(interfaceDef.getType())))
+ .flatMap(interfaceDef -> interfaceDef.getOperationsMap().values().stream().map(Operation::getName))
+ .allMatch(operationName -> globalInterfaceTypes.values().stream()
+ .flatMap(interfaceDef -> interfaceDef.getOperationsMap().keySet().stream())
+ .anyMatch(opName -> opName.equalsIgnoreCase(operationName)));
+ if (!isOperationValidOnGlobalInterfaceType) {
+ return Either.right(getResponseFormatManager()
+ .getResponseFormat(ActionStatus.INTERFACE_OPERATION_INVALID_FOR_GLOBAL_TYPE,
+ interfaceDefinition.getType()));
}
return Either.left(Boolean.TRUE);
}
@@ -212,33 +260,47 @@ public class InterfaceOperationValidation {
.collect(Collectors.toSet());
}
String mappedOutputPrefix = interfaceDefinition.getType() + "." + interfaceOperation.getName();
+ //Get the deleted outputs (name changed also equivalent to deleted)
Set<String> deletedOutputs = Sets.difference(existingOperationOutputNames, currentOperationOutputNames);
- Set<String> deletedMappedOutputs = deletedOutputs.stream()
- .filter(deletedOutputName -> isMappedOutputDeleted(mappedOutputPrefix, deletedOutputName,
- component.getInterfaces()))
- .map(this::getOperationOutputName)
- .collect(Collectors.toSet());
+ Set<String> deletedMappedOutputs = getModifiedMappedOutputs(deletedOutputs, mappedOutputPrefix,
+ component.getInterfaces());
if (CollectionUtils.isNotEmpty(deletedMappedOutputs)) {
- return getMappedOutputErrorResponse(responseFormatManager, deletedMappedOutputs);
+ return getMappedOutputErrorResponse(responseFormatManager, deletedMappedOutputs,
+ "Cannot update or delete interface operation output(s) '{}' mapped to an operation input",
+ ActionStatus.INTERFACE_OPERATION_MAPPED_OUTPUT_MODIFIED);
}
if (currentOutputs != null && !currentOutputs.isEmpty()) {
+ //Get the unchanged outputs based on name to see if other attributes (type/mandatory) have not been changed
Set<String> unchangedOutputNames = Sets.intersection(existingOperationOutputNames,
currentOperationOutputNames);
- Set<String> modifiedMappedOutputNames =
- getModifiedMappedOutputNames(currentOutputs.getListToscaDataDefinition(),
+ Set<String> modifiedOutputNames =
+ getModifiedOutputNames(currentOutputs.getListToscaDataDefinition(),
existingOperationOutputs, unchangedOutputNames);
+ Set<String> modifiedMappedOutputNames = getModifiedMappedOutputs(modifiedOutputNames, mappedOutputPrefix,
+ component.getInterfaces());
if (CollectionUtils.isNotEmpty(modifiedMappedOutputNames)) {
- return getMappedOutputErrorResponse(responseFormatManager, modifiedMappedOutputNames);
+ return getMappedOutputErrorResponse(responseFormatManager, modifiedMappedOutputNames,
+ "Cannot update or delete interface operation output(s) '{}' mapped to an operation input",
+ ActionStatus.INTERFACE_OPERATION_MAPPED_OUTPUT_MODIFIED);
}
}
return Either.left(Boolean.TRUE);
}
- private boolean isMappedOutputDeleted(String mappedOutputPrefix, String outputName,
- Map<String, InterfaceDefinition> componentInterfaces) {
+ private Set<String> getModifiedMappedOutputs(Set<String> modifiedOutputNames, String mappedOutputPrefix,
+ Map<String, InterfaceDefinition> componentInterfaces) {
+ return modifiedOutputNames.stream()
+ .filter(modifiedOutputName -> isMappedOutputModified(mappedOutputPrefix, modifiedOutputName,
+ componentInterfaces))
+ .map(InterfaceOperationUtils::getOperationOutputName)
+ .collect(Collectors.toSet());
+ }
+
+ private boolean isMappedOutputModified(String mappedOutputPrefix, String outputName,
+ Map<String, InterfaceDefinition> componentInterfaces) {
List<OperationInputDefinition> interfaceOperationInputs =
getOtherOperationInputsOfComponent(mappedOutputPrefix, componentInterfaces);
return interfaceOperationInputs.stream()
@@ -246,16 +308,16 @@ public class InterfaceOperationValidation {
.equals(mappedOutputPrefix + "." + outputName));
}
- private static Set<String> getModifiedMappedOutputNames(List<OperationOutputDefinition> currentOperationOutputs,
- List<OperationOutputDefinition> existingOperationOutputs,
- Set<String> unchangedOutputNames) {
+ private static Set<String> getModifiedOutputNames(List<OperationOutputDefinition> currentOperationOutputs,
+ List<OperationOutputDefinition> existingOperationOutputs,
+ Set<String> unchangedOutputNames) {
Set<String> modifiedOutputDefinitionNames = new HashSet<>();
- Map<String, OperationOutputDefinition> newOutputMap =
- currentOperationOutputs.stream().collect(Collectors.toMap(OperationOutputDefinition::getName,
+ Map<String, OperationOutputDefinition> newOutputMap = currentOperationOutputs.stream()
+ .collect(Collectors.toMap(OperationOutputDefinition::getName,
(OperationOutputDefinition operationOutputDefinition) -> operationOutputDefinition));
- Map<String, OperationOutputDefinition> existingOutputMap =
- existingOperationOutputs.stream().collect(Collectors.toMap(OperationOutputDefinition::getName,
+ Map<String, OperationOutputDefinition> existingOutputMap = existingOperationOutputs.stream()
+ .collect(Collectors.toMap(OperationOutputDefinition::getName,
(OperationOutputDefinition operationOutputDefinition) -> operationOutputDefinition));
for (String outputName : unchangedOutputNames) {
@@ -270,12 +332,12 @@ public class InterfaceOperationValidation {
}
private Either<Boolean, ResponseFormat> getMappedOutputErrorResponse(ResponseFormatManager responseFormatManager,
- Set<String> modifiedMappedOutputs) {
+ Set<String> modifiedMappedOutputs,
+ String message,
+ ActionStatus errorStatus) {
String modifiedOutputNameList = String.join(",", modifiedMappedOutputs);
- LOGGER.error("Cannot update or delete interface operation output(s) '{}' mapped to an operation input",
- modifiedOutputNameList);
- ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
- .INTERFACE_OPERATION_MAPPED_OUTPUT_MODIFIED, modifiedOutputNameList);
+ LOGGER.error(message, modifiedOutputNameList);
+ ResponseFormat errorResponse = responseFormatManager.getResponseFormat(errorStatus, modifiedOutputNameList);
return Either.right(errorResponse);
}
@@ -461,11 +523,11 @@ public class InterfaceOperationValidation {
List<OperationInputDefinition> inputListToscaDataDefinition =
operation.getInputs().getListToscaDataDefinition();
for (OperationInputDefinition inputDefinition : inputListToscaDataDefinition) {
- if (isOperationInputMappedToComponentProperty(inputDefinition, component.getInputs())) {
+ if (isOperationInputMappedToComponentInput(inputDefinition, component.getInputs())) {
isOperationInputToInputPropertyMappingValid = true;
} else {
mappingName = inputDefinition.getInputId().contains(".")
- ? inputDefinition.getInputId().substring(inputDefinition.getInputId().lastIndexOf(".") + 1)
+ ? inputDefinition.getInputId().substring(inputDefinition.getInputId().lastIndexOf('.') + 1)
: inputDefinition.getInputId();
break;
}
@@ -476,8 +538,9 @@ public class InterfaceOperationValidation {
//Mapped property not found in the component properties.. Check in other operation output parameters of
// component (other operation => not having the same full name)
+ String actualOperationIdentifier = inputInterfaceDefinition.getType() + "." + operation.getName();
ListDataDefinition<OperationOutputDefinition> outputListDataDefinition =
- getOtherOperationOutputsOfComponent(inputInterfaceDefinition.getType(), operation.getName(), component);
+ getOtherOperationOutputsOfComponent(actualOperationIdentifier, component.getInterfaces());
List<OperationOutputDefinition> componentOutputsFromOtherOperations =
outputListDataDefinition.getListToscaDataDefinition();
@@ -506,38 +569,6 @@ public class InterfaceOperationValidation {
}
/**
- * Get the list of outputs of other operations of all the interfaces in the component.
- * @param currentInterfaceName Fully qualified interface name e.g. org.test.interfaces.node.lifecycle.Abc
- * @param currentOperationName Name entered on the operation screen e.g. create
- * @param component VF or service
- */
-
- private ListDataDefinition<OperationOutputDefinition> getOtherOperationOutputsOfComponent(
- String currentInterfaceName, String currentOperationName, org.openecomp.sdc.be.model.Component component) {
- ListDataDefinition<OperationOutputDefinition> componentOutputs = new ListDataDefinition<>();
- Map<String, InterfaceDefinition> componentInterfaces = component.getInterfaces();
- if (MapUtils.isEmpty(componentInterfaces)) {
- return componentOutputs;
- }
- for (Map.Entry<String, InterfaceDefinition> interfaceDefinitionEntry : componentInterfaces.entrySet()) {
- String interfaceName = interfaceDefinitionEntry.getKey();
- final Map<String, OperationDataDefinition> operations = interfaceDefinitionEntry.getValue().getOperations();
- if (MapUtils.isEmpty(operations)) {
- continue;
- }
- String actualOperationIdentifier = currentInterfaceName + "." + currentOperationName;
- for (Map.Entry<String, OperationDataDefinition> operationEntry : operations.entrySet()) {
- ListDataDefinition<OperationOutputDefinition> outputs = operationEntry.getValue().getOutputs();
- String expectedOperationIdentifier = interfaceName + "." + operationEntry.getKey();
- if (!actualOperationIdentifier.equals(expectedOperationIdentifier) && !outputs.isEmpty()) {
- outputs.getListToscaDataDefinition().forEach(componentOutputs::add);
- }
- }
- }
- return componentOutputs;
- }
-
- /**
* Get the input definitions of other operations of the component from current as well as other interfaces.
* @param currentOperationIdentifier Identifier for the request operation (interface_name.operation_name)
* @param componentInterfaces Interfaces of the component
@@ -566,12 +597,6 @@ public class InterfaceOperationValidation {
return otherOperationInputs;
}
- private String getOperationOutputName(String outputName) {
- return outputName.contains(".")
- ? outputName.substring(outputName.lastIndexOf(".") + 1)
- : outputName;
- }
-
/**
* Get the output of an operation in an interface.
* @param inputOperationId Unique identifier for the request operation
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java
index b76664f968..0dddfe5c13 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java
@@ -20,6 +20,16 @@
package org.openecomp.sdc.be.datamodel.utils;
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.toList;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
import org.openecomp.sdc.be.components.impl.GroupTypeBusinessLogic;
import org.openecomp.sdc.be.components.impl.PolicyTypeBusinessLogic;
import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
@@ -27,16 +37,21 @@ import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
-import org.openecomp.sdc.be.model.*;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.GroupDefinition;
+import org.openecomp.sdc.be.model.PolicyDefinition;
+import org.openecomp.sdc.be.model.Resource;
+import org.openecomp.sdc.be.model.Service;
import org.openecomp.sdc.be.tosca.utils.NodeFilterConverter;
-import org.openecomp.sdc.be.ui.model.*;
+import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
+import org.openecomp.sdc.be.ui.model.UiComponentMetadata;
+import org.openecomp.sdc.be.ui.model.UiResourceDataTransfer;
+import org.openecomp.sdc.be.ui.model.UiResourceMetadata;
+import org.openecomp.sdc.be.ui.model.UiServiceDataTransfer;
+import org.openecomp.sdc.be.ui.model.UiServiceMetadata;
import org.openecomp.sdc.common.log.wrappers.Logger;
-import java.util.*;
-
-import static java.util.stream.Collectors.groupingBy;
-import static java.util.stream.Collectors.toList;
-
@org.springframework.stereotype.Component("uiComponentDataConverter")
public class UiComponentDataConverter {
@@ -109,6 +124,16 @@ public class UiComponentDataConverter {
NodeFilterConverter nodeFilterConverter = new NodeFilterConverter();
dataTransfer.setNodeFilterData(nodeFilterConverter.convertDataMapToUI(component.getNodeFilterComponents()));
}
+ break;
+ case COMPONENT_INSTANCES_INTERFACES:
+ setComponentInstanceInterfaces(dataTransfer, component);
+ break;
+ case PROPERTIES:
+ setProperties(dataTransfer, component);
+ break;
+ case INTERFACES:
+ setInterfaces(dataTransfer, component);
+ break;
default:
break;
}
@@ -137,7 +162,6 @@ public class UiComponentDataConverter {
dataTransfer.setComponentInstancesInputs(component.getComponentInstancesInputs());
}
}
-
private void setComponentInstanceAttributes(UiComponentDataTransfer dataTransfer, Component component) {
if (component.getComponentInstancesAttributes() == null) {
dataTransfer.setComponentInstancesAttributes(new HashMap<>());
@@ -145,7 +169,6 @@ public class UiComponentDataConverter {
dataTransfer.setComponentInstancesAttributes(component.getComponentInstancesAttributes());
}
}
-
private void setArtifacts(UiComponentDataTransfer dataTransfer, Component component) {
if (component.getArtifacts() == null) {
dataTransfer.setArtifacts(new HashMap<>());
@@ -153,7 +176,6 @@ public class UiComponentDataConverter {
dataTransfer.setArtifacts(component.getArtifacts());
}
}
-
private void setToscaArtifacts(UiComponentDataTransfer dataTransfer, Component component) {
if (component.getToscaArtifacts() == null) {
dataTransfer.setToscaArtifacts(new HashMap<>());
@@ -221,6 +243,30 @@ public class UiComponentDataConverter {
}
}
+ private void setProperties(UiComponentDataTransfer dataTransfer, Component component) {
+ if (component.getProperties() == null) {
+ dataTransfer.setProperties(new ArrayList<>());
+ } else {
+ dataTransfer.setProperties(component.getProperties());
+ }
+ }
+
+ private void setInterfaces(UiComponentDataTransfer dataTransfer, Component component) {
+ if (component.getInterfaces() == null) {
+ dataTransfer.setInterfaces(new HashMap<>());
+ } else {
+ dataTransfer.setInterfaces(component.getInterfaces());
+ }
+ }
+
+ private void setComponentInstanceInterfaces(UiComponentDataTransfer dataTransfer, Component component) {
+ if (component.getComponentInstancesInterfaces() == null) {
+ dataTransfer.setComponentInstancesInterfaces(new HashMap<>());
+ } else {
+ dataTransfer.setComponentInstancesInterfaces(component.getComponentInstancesInterfaces());
+ }
+ }
+
private void setNonExcludedGroups(UiComponentDataTransfer dataTransfer, Component component) {
List<GroupDefinition> groups = component.getGroups();
if (groups == null) {
@@ -254,15 +300,6 @@ public class UiComponentDataConverter {
continue;
}
switch (field) {
-
- case PROPERTIES:
- setProperties(resource, dataTransfer);
- break;
-
- case INTERFACES:
- setInterfaces(resource, dataTransfer);
- break;
-
case DERIVED_FROM:
setDerivedFrom(resource, dataTransfer);
break;
@@ -287,22 +324,6 @@ public class UiComponentDataConverter {
return dataTransfer;
}
- private void setProperties(Resource resource, UiResourceDataTransfer dataTransfer) {
- if (resource.getProperties() == null) {
- dataTransfer.setProperties(new ArrayList<>());
- } else {
- dataTransfer.setProperties(resource.getProperties());
- }
- }
-
- private void setInterfaces(Resource resource, UiResourceDataTransfer dataTransfer) {
- if (resource.getInterfaces() == null) {
- dataTransfer.setInterfaces(new HashMap<>());
- } else {
- dataTransfer.setInterfaces(resource.getInterfaces());
- }
- }
-
private void setDerivedFrom(Resource resource, UiResourceDataTransfer dataTransfer) {
if (resource.getDerivedFrom() == null) {
dataTransfer.setDerivedFrom(new ArrayList<>());
@@ -338,7 +359,6 @@ public class UiComponentDataConverter {
switch (field) {
case SERVICE_API_ARTIFACTS:
setServiceApiArtifacts(service, dataTransfer);
-
break;
case FORWARDING_PATHS:
setForwardingPaths(service, dataTransfer);
@@ -347,9 +367,6 @@ public class UiComponentDataConverter {
UiServiceMetadata metadata = new UiServiceMetadata(service.getCategories(), (ServiceMetadataDataDefinition) service.getComponentMetadataDefinition().getMetadataDataDefinition());
dataTransfer.setMetadata(metadata);
break;
- case INTERFACES:
- setInterfaces(service, dataTransfer);
- break;
default:
setUiTranferDataByFieldName(dataTransfer, service, fieldName);
}
@@ -373,14 +390,6 @@ public class UiComponentDataConverter {
}
}
- private void setInterfaces(Service service, UiServiceDataTransfer dataTransfer) {
- if (service.getInterfaces() == null) {
- dataTransfer.setInterfaces(new HashMap<>());
- } else {
- dataTransfer.setInterfaces(service.getInterfaces());
- }
- }
-
public static UiComponentMetadata convertToUiComponentMetadata(Component component) {
UiComponentMetadata uiComponentMetadata = null;
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java
index 0930daad04..9f6fb9fe89 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java
@@ -756,6 +756,9 @@ public class ComponentsUtils {
case COMPONENT_IS_ARCHIVED:
responseEnum = ActionStatus.COMPONENT_IS_ARCHIVED;
break;
+ case DECLARED_INPUT_USED_BY_OPERATION:
+ responseEnum = ActionStatus.DECLARED_INPUT_USED_BY_OPERATION;
+ break;
default:
responseEnum = ActionStatus.GENERAL_ERROR;
break;
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceConsumptionServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceConsumptionServlet.java
new file mode 100644
index 0000000000..4ed2f95676
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceConsumptionServlet.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.servlets;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonParseException;
+import com.jcabi.aspects.Loggable;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import fj.data.Either;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.apache.commons.lang3.StringUtils;
+import org.json.simple.JSONArray;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic;
+import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
+import org.openecomp.sdc.be.config.BeEcompErrorManager;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.model.Operation;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.model.tosca.ToscaFunctions;
+import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
+import org.openecomp.sdc.be.types.ServiceConsumptionData;
+import org.openecomp.sdc.be.types.ServiceConsumptionSource;
+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.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+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;
+
+@Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
+@Path("/v1/catalog")
+@Api(value = "Service Consumption Servlet", description = "Service Consumption Servlet")
+@Singleton
+public class ServiceConsumptionServlet extends BeGenericServlet {
+
+ private static final Logger log = LoggerFactory.getLogger(ServiceConsumptionServlet.class);
+
+ @POST
+ @Path("/services/{serviceId}/consumption/{serviceInstanceId}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Service consumption on operation", httpMethod = "POST",
+ notes = "Returns consumption data", 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 addInputToServiceOperation(@PathParam("serviceId")final String serviceId,
+ @PathParam("serviceInstanceId")final String serviceInstanceId,
+ @ApiParam(value = "Service Consumption Data", 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);
+ User modifier = new User();
+ modifier.setUserId(userId);
+
+ try {
+
+ Either<Map<String, List<ServiceConsumptionData>>, ResponseFormat> dataFromJson =
+ getServiceConsumptionData(data, modifier);
+ if(dataFromJson.isRight()) {
+ return buildErrorResponse(dataFromJson.right().value());
+ }
+
+ Map<String, List<ServiceConsumptionData>> serviceConsumptionDataMap = dataFromJson.left().value();
+ ServiceBusinessLogic serviceBL = getServiceBL(context);
+
+ for(Entry<String, List<ServiceConsumptionData>> consumptionEntry : serviceConsumptionDataMap.entrySet()) {
+ List<ServiceConsumptionData> consumptionList = consumptionEntry.getValue();
+ Either<List<Operation>, ResponseFormat> operationEither =
+ serviceBL.addServiceConsumptionData(serviceId, serviceInstanceId,
+ consumptionEntry.getKey(), consumptionList, userId);
+ if (operationEither.isRight()) {
+ return buildErrorResponse(operationEither.right().value());
+ }
+ }
+
+ return buildOkResponse(serviceConsumptionDataMap);
+
+ }
+ catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Operation Inputs");
+ log.debug("Create Operation Inputs failed with exception", e);
+ ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
+ return buildErrorResponse(responseFormat);
+ }
+
+ }
+
+ @GET
+ @Path("/services/{serviceId}/consumption/{serviceInstanceId}/interfaces/{interfaceId}/operations/{operationId}/inputs")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response getInputsListOfOperation(@PathParam("serviceId")final String serviceId,
+ @PathParam("serviceInstanceId")final String serviceInstanceId,
+ @PathParam("interfaceId")final String interfaceId,
+ @PathParam("operationId")final String operationId,
+ @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);
+ User user = new User();
+ user.setUserId(userId);
+
+ try {
+ InterfaceOperationBusinessLogic interfaceOperationBL = getInterfaceOperationBL(context);
+ Either<List<OperationInputDefinition>, ResponseFormat> inputsEither =
+ interfaceOperationBL.getInputsListForOperation(serviceId, serviceInstanceId, interfaceId, operationId, user);
+
+ if(inputsEither.isRight()) {
+ return buildErrorResponse(inputsEither.right().value());
+ }
+
+ List<OperationInputDefinition> inputs = inputsEither.left().value();
+ updateOperationInputListForUi(inputs);
+ return buildOkResponse(inputs);
+ }
+ catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Operation Inputs");
+ log.debug("Get Operation Inputs failed with exception", e);
+ ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
+ return buildErrorResponse(responseFormat);
+ }
+ }
+
+ private void updateOperationInputListForUi(List<OperationInputDefinition> inputsList) {
+ for(OperationInputDefinition input : inputsList) {
+
+ String value = input.getValue();
+ // No Additional UI mapping needed for STATIC source
+ if(StringUtils.isEmpty(value)
+ || ServiceConsumptionSource.STATIC.getSource().equals(input.getSource())) {
+ continue;
+ }
+
+
+ // Additional UI mapping needed for other sources
+ try {
+ Map<String, Object> valueAsMap = (new Gson()).fromJson(value, Map.class);
+ String toscaFunction = valueAsMap.keySet().iterator().next();
+ Object consumptionValueName = valueAsMap.values().iterator().next();
+ if(consumptionValueName instanceof List) {
+ List<Object> toscaFunctionList = (List<Object>) consumptionValueName;
+ String consumptionInputValue = null;
+ if (ToscaFunctions.GET_PROPERTY.getFunctionName().equals(toscaFunction)) {
+ consumptionInputValue = String.valueOf(toscaFunctionList.get(1));
+ } else if (ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName().equals(toscaFunction)) {
+ //Return full output name
+ consumptionInputValue =
+ toscaFunctionList.get(1) + "." + toscaFunctionList.get(2) + "." +toscaFunctionList.get(3);
+ }
+ input.setValue(consumptionInputValue);
+ } else {
+ input.setValue(String.valueOf(consumptionValueName));
+ }
+ }
+ catch(JsonParseException ex){
+ log.info("This means it is static value for which no changes are needed");
+ }
+ }
+ }
+
+
+ private Either<Map<String, List<ServiceConsumptionData>>, ResponseFormat> getServiceConsumptionData(String data,
+ User user) {
+ JSONParser parser = new JSONParser();
+ Map<String, List<ServiceConsumptionData>> serviceConsumptionDataMap = new HashMap<>();
+
+ try {
+ JSONArray operationsArray = (JSONArray) parser.parse(data);
+ Iterator iterator = operationsArray.iterator();
+ while (iterator.hasNext()) {
+ Map next = (Map) iterator.next();
+ Entry consumptionEntry = (Entry) next.entrySet().iterator().next();
+ String operationId = (String) consumptionEntry.getKey();
+ Object value = consumptionEntry.getValue();
+
+ JSONArray inputsArray = (JSONArray) parser.parse(value.toString());
+ serviceConsumptionDataMap.putIfAbsent(operationId, new ArrayList<>());
+ for(Object consumptionObject : inputsArray) {
+ Either<ServiceConsumptionData, ResponseFormat> serviceDataEither =
+ getComponentsUtils()
+ .convertJsonToObjectUsingObjectMapper(consumptionObject.toString(), user, ServiceConsumptionData
+ .class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
+ if(serviceDataEither.isRight()) {
+ return Either.right(serviceDataEither.right().value());
+ }
+
+ serviceConsumptionDataMap.get(operationId).add(serviceDataEither.left().value());
+ }
+ }
+ }
+ catch (ParseException e) {
+ log.info("Conetnt is invalid - {}", data);
+ return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
+ }
+ return Either.left(serviceConsumptionDataMap);
+ }
+}
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 da0ec1c0ea..d3d4c2d073 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
@@ -45,6 +45,7 @@ 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.StorageOperationStatus;
import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
+import org.openecomp.sdc.be.model.tosca.ToscaFunctions;
import org.openecomp.sdc.be.model.tosca.converters.ToscaValueBaseConverter;
import org.openecomp.sdc.be.tosca.model.*;
import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil;
@@ -509,27 +510,8 @@ public class ToscaExportHandler {
}
private Either<ToscaTemplate, ToscaError> convertNodeType(Map<String, Component> componentsCache, Component component, ToscaTemplate toscaNode,
- Map<String, ToscaNodeType> nodeTypes) {
- log.debug("start convert node type for {}", component.getUniqueId());
- ToscaNodeType toscaNodeType = createNodeType(component);
-
- Either<Map<String, DataTypeDefinition>, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll();
- if (dataTypesEither.isRight()) {
- log.debug("Failed to fetch all data types :", dataTypesEither.right().value());
- return Either.right(ToscaError.GENERAL_ERROR);
- }
-
- Map<String, DataTypeDefinition> dataTypes = dataTypesEither.left().value();
- Either<ToscaNodeType, ToscaError> properties = propertyConvertor.convertProperties(component, toscaNodeType,
- dataTypes);
- if (properties.isRight()) {
- return Either.right(properties.right().value());
- }
- toscaNodeType = properties.left().value();
- log.debug("Properties converted for {}", component.getUniqueId());
-
- // Extracted to method for code reuse
- return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
+ Map<String, ToscaNodeType> nodeTypes) {
+ return convertInterfaceNodeType(componentsCache, component, toscaNode, nodeTypes, false);
}
private Either<ToscaTemplate, ToscaError> convertInterfaceNodeType(Map<String, Component> componentsCache,
@@ -546,10 +528,10 @@ public class ToscaExportHandler {
return Either.right(ToscaError.GENERAL_ERROR);
}
List<String> allGlobalInterfaceTypes = lifecycleTypeEither.left().value()
- .values()
- .stream()
- .map(interfaceDef -> interfaceDef.getType())
- .collect(Collectors.toList());
+ .values()
+ .stream()
+ .map(InterfaceDataDefinition::getType)
+ .collect(Collectors.toList());
toscaNode.setInterface_types(addInterfaceTypeElement(component, allGlobalInterfaceTypes));
Either<Map<String, DataTypeDefinition>, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll();
@@ -570,16 +552,40 @@ public class ToscaExportHandler {
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)));
+ PropertyDataDefinition::getName,
+ property -> propertyConvertor.convertProperty(dataTypes, property,
+ PropertyConvertor.PropertyType.PROPERTY)));
}
- if (!mergedProperties.isEmpty()) {
+ if (MapUtils.isNotEmpty(mergedProperties) && Objects.nonNull(inputDef)) {
+ resolveDefaultPropertyValue(inputDef, mergedProperties, dataTypes);
toscaNodeType.setProperties(mergedProperties);
}
// Extracted to method for code reuse
return convertReqCapAndTypeName(componentsCache, component, toscaNode, nodeTypes, toscaNodeType, dataTypes);
}
+ private void resolveDefaultPropertyValue(List<InputDefinition> inputDef,
+ Map<String, ToscaProperty> mergedProperties,
+ Map<String, DataTypeDefinition> dataTypes) {
+ for (Map.Entry<String, ToscaProperty> mergedPropertyEntry : mergedProperties.entrySet()) {
+ ToscaProperty value = mergedPropertyEntry.getValue();
+ if (Objects.nonNull(value) && value.getDefaultp() instanceof Map) {
+ Map<String, String> valueAsMap = (Map<String, String>) value.getDefaultp();
+ String inputName = valueAsMap.get(ToscaFunctions.GET_INPUT.getFunctionName());
+ Optional<InputDefinition> matchedInputDefinition = inputDef.stream()
+ .filter(componentInput -> componentInput.getName().equals(inputName))
+ .findFirst();
+ if (matchedInputDefinition.isPresent()) {
+ InputDefinition matchedInput = matchedInputDefinition.get();
+ Object resolvedDefaultValue = new PropertyConvertor().convertToToscaObject(matchedInput.getType(),
+ matchedInput.getDefaultValue(), matchedInput.getSchemaType(), dataTypes, false);
+ value.setDefaultp(resolvedDefaultValue);
+ mergedProperties.put(mergedPropertyEntry.getKey(), value);
+ }
+ }
+ }
+ }
+
private void addInputsToProperties(Map<String, DataTypeDefinition> dataTypes,
List<InputDefinition> inputDef,
Map<String, ToscaProperty> mergedProperties) {
@@ -692,12 +698,14 @@ public class ToscaExportHandler {
addPropertiesOfParentComponent(dataTypes, originalComponent, props);
}
- if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)) {
+ if (null != componentInstancesProperties && componentInstancesProperties.containsKey(instanceUniqueId)
+ && !isComponentOfTypeServiceProxy(componentInstance)) {
addPropertiesOfComponentInstance(componentInstancesProperties, dataTypes,
instanceUniqueId, props);
}
- if (componentInstancesInputs != null && componentInstancesInputs.containsKey(instanceUniqueId)) {
+ if (componentInstancesInputs != null && componentInstancesInputs.containsKey(instanceUniqueId)
+ && !isComponentOfTypeServiceProxy(componentInstance)) {
addComponentInstanceInputs(dataTypes, componentInstancesInputs, instanceUniqueId,
props);
}
@@ -821,8 +829,8 @@ public class ToscaExportHandler {
if (instanceInputsList != null) {
instanceInputsList.forEach(input -> {
- Supplier<String> supplier = () -> input.getValue() != null && !input.getValue().isEmpty()
- ? input.getValue() : input.getDefaultValue();
+ Supplier<String> supplier = () -> input.getValue() != null && !Objects.isNull(input.getValue())
+ ? input.getValue() : input.getDefaultValue();
propertyConvertor.convertAndAddValue(dataTypes, props, input, supplier);
});
}
@@ -844,13 +852,13 @@ public class ToscaExportHandler {
private void addPropertiesOfParentComponent(Map<String, DataTypeDefinition> dataTypes,
Component componentOfInstance, Map<String, Object> props) {
- List<PropertyDefinition> componentProperties = ((Resource) componentOfInstance).getProperties();
+ List<PropertyDefinition> componentProperties = componentOfInstance.getProperties();
if (isNotEmpty(componentProperties)) {
componentProperties.stream()
- // Filters out properties with empty default values
- .filter(prop -> isNotEmpty(prop.getDefaultValue()))
- // Converts and adds each value to property map
- .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop,
+ // Filters out properties with empty default values
+ .filter(prop -> StringUtils.isNotEmpty(prop.getDefaultValue()))
+ // Converts and adds each value to property map
+ .forEach(prop -> propertyConvertor.convertAndAddValue(dataTypes, props, prop,
prop::getDefaultValue));
}
}
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 a72f57d61c..d69e4f67b3 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
@@ -16,16 +16,15 @@
package org.openecomp.sdc.be.tosca.utils;
-import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToComponentProperty;
-
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
-import java.util.ArrayList;
-import java.util.Arrays;
+import com.google.gson.Gson;
+
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+
import org.apache.commons.collections.MapUtils;
import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
@@ -33,6 +32,8 @@ 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.model.tosca.ToscaFunctions;
+import org.openecomp.sdc.be.tosca.PropertyConvertor;
import org.openecomp.sdc.be.tosca.model.ToscaInterfaceDefinition;
import org.openecomp.sdc.be.tosca.model.ToscaInterfaceNodeType;
import org.openecomp.sdc.be.tosca.model.ToscaLifecycleOperationDefinition;
@@ -50,9 +51,7 @@ public class InterfacesOperationsToscaUtil {
private static final String DOT = ".";
private static final String DEFAULTP = "defaultp";
- static final String SELF = "SELF";
- static final String GET_PROPERTY = "get_property";
- static final String GET_OPERATION_OUTPUT = "get_operation_output";
+ public static final String SELF = "SELF";
private InterfacesOperationsToscaUtil() {
}
@@ -153,7 +152,7 @@ public class InterfacesOperationsToscaUtil {
toscaOperation.setImplementation(operationArtifactPath);
}
toscaOperation.setDescription(operationEntry.getValue().getDescription());
- fillToscaOperationInputs(operationEntry.getValue(), toscaOperation, component);
+ fillToscaOperationInputs(operationEntry.getValue(), dataTypes, toscaOperation, isServiceProxyInterface);
toscaOperations.put(operationEntry.getValue().getName(), toscaOperation);
}
@@ -162,6 +161,7 @@ public class InterfacesOperationsToscaUtil {
Map<String, Object> interfaceDefAsMap = getObjectAsMap(toscaInterfaceDefinition);
Map<String, Object> operationsMap = (Map<String, Object>) interfaceDefAsMap.remove(OPERATIONS_KEY);
if (isServiceProxyInterface) {
+ //Remove input type and copy default value directly into the proxy node template from the node type
handleServiceProxyOperationInputValue(operationsMap, interfaceType);
} else {
handleDefaults(operationsMap);
@@ -235,8 +235,9 @@ public class InterfacesOperationsToscaUtil {
}
private static void fillToscaOperationInputs(OperationDataDefinition operation,
+ Map<String, DataTypeDefinition> dataTypes,
ToscaLifecycleOperationDefinition toscaOperation,
- Component component) {
+ boolean isServiceProxyInterface) {
if (Objects.isNull(operation.getInputs()) || operation.getInputs().isEmpty()) {
toscaOperation.setInputs(null);
return;
@@ -246,61 +247,37 @@ public class InterfacesOperationsToscaUtil {
for (OperationInputDefinition input : operation.getInputs().getListToscaDataDefinition()) {
ToscaProperty toscaInput = new ToscaProperty();
toscaInput.setDescription(input.getDescription());
- String mappedPropertyName;
- if (Objects.nonNull(input.getInputId())) {
- if (isOperationInputMappedToComponentProperty(input, component.getInputs())) {
- mappedPropertyName = input.getInputId().substring(input.getInputId().indexOf(DOT) + 1);
- toscaInput.setDefaultp(createMappedInputPropertyDefaultValue(mappedPropertyName));
- } else {
- mappedPropertyName = input.getInputId();
- toscaInput.setDefaultp(createMappedOutputDefaultValue(mappedPropertyName));
- }
- }
toscaInput.setType(input.getType());
toscaInput.setRequired(input.isRequired());
+ if (isServiceProxyInterface) {
+ String inputValue = Objects.nonNull(input.getValue()) ? getInputValue(input.getValue()) :
+ getInputValue(input.getToscaDefaultValue());
+ toscaInput.setDefaultp(new PropertyConvertor().convertToToscaObject(input.getType(),
+ inputValue, input.getSchemaType(), dataTypes, false));
+ } else {
+ toscaInput.setDefaultp(new PropertyConvertor().convertToToscaObject(input.getType(),
+ getInputValue(input.getToscaDefaultValue()), input.getSchemaType(), dataTypes, false));
+ }
toscaInputs.put(input.getName(), toscaInput);
}
-
toscaOperation.setInputs(toscaInputs);
}
- private static Map<String, List<String>> createMappedInputPropertyDefaultValue(String propertyName) {
- Map<String, List<String>> getPropertyMap = new HashMap<>();
- List<String> values = new ArrayList<>();
- values.add(SELF);
- if (Objects.nonNull(propertyName) && !propertyName.isEmpty()) {
- values.addAll(Arrays.asList(propertyName.split("\\.")));
- }
-
- getPropertyMap.put(GET_PROPERTY, values);
-
- return getPropertyMap;
- }
-
- /**
- * Create the value for operation input mapped to an operation output.
- * @param propertyName the mapped other operation output full name
- * @return input map for tosca
- */
- private static Map<String, List<String>> createMappedOutputDefaultValue(String propertyName) {
- Map<String, List<String>> getOperationOutputMap = new HashMap<>();
- //For operation input mapped to other operation output parameter, the mapped property value
- // should be of the format <interface name>.<operation name>.<output parameter name>
- // Operation name and output param name should not contain "."
- List<String> defaultMappedOperationOutputValue = new ArrayList<>();
- String[] tokens = propertyName.split("\\.");
- if (tokens.length > 2) {
- defaultMappedOperationOutputValue.add(SELF);
- String outputPropertyName = tokens[tokens.length - 1];
- String operationName = tokens[tokens.length - 2];
- String mappedPropertyInterfaceType =
- propertyName.substring(0, propertyName.indexOf(operationName + '.' + outputPropertyName) - 1);
- String interfaceName =
- mappedPropertyInterfaceType.substring(mappedPropertyInterfaceType.lastIndexOf('.') + 1);
- defaultMappedOperationOutputValue.addAll(Arrays.asList(interfaceName, operationName, outputPropertyName));
- getOperationOutputMap.put(GET_OPERATION_OUTPUT, defaultMappedOperationOutputValue);
+ private static String getInputValue(String inputValue) {
+ String toscaInputValue = inputValue;
+ if (Objects.nonNull(inputValue) && inputValue.contains(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName())) {
+ Gson gson = new Gson();
+ Map<String, List<String>> consumptionValue = gson.fromJson(inputValue, Map.class);
+ List<String> mappedOutputValue =
+ consumptionValue.get(ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName());
+ //Extract the interface name from the interface type
+ String interfaceType = mappedOutputValue.get(1);
+ String interfaceName = interfaceType.substring(interfaceType.lastIndexOf('.') + 1);
+ mappedOutputValue.remove(1);
+ mappedOutputValue.add(1, interfaceName);
+ toscaInputValue = gson.toJson(consumptionValue);
}
- return getOperationOutputMap;
+ return toscaInputValue;
}
private static Map<String, Object> getObjectAsMap(Object obj) {
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/types/ServiceConsumptionData.java b/catalog-be/src/main/java/org/openecomp/sdc/be/types/ServiceConsumptionData.java
new file mode 100644
index 0000000000..5e97ac67f4
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/types/ServiceConsumptionData.java
@@ -0,0 +1,56 @@
+/*
+ * 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.types;
+
+public class ServiceConsumptionData {
+ private String inputId;
+ private String source;
+ private String value;
+ private String type;
+
+ public String getInputId() {
+ return inputId;
+ }
+
+ public void setInputId(String inputId) {
+ this.inputId = inputId;
+ }
+
+ public String getSource() {
+ return source;
+ }
+
+ public void setSource(String source) {
+ this.source = source;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/types/ServiceConsumptionSource.java b/catalog-be/src/main/java/org/openecomp/sdc/be/types/ServiceConsumptionSource.java
new file mode 100644
index 0000000000..9e297b7c45
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/types/ServiceConsumptionSource.java
@@ -0,0 +1,49 @@
+/*
+ * 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.types;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum ServiceConsumptionSource {
+ SERVICE_INPUT("ServiceInput"),
+ STATIC("Static");
+
+
+ private static Map<String, ServiceConsumptionSource> sourceToValue;
+
+ static {
+ sourceToValue = new HashMap<>();
+ for(ServiceConsumptionSource sourceName : ServiceConsumptionSource.values()) {
+ sourceToValue.put(sourceName.source, sourceName);
+ }
+ }
+
+ private String source;
+
+ ServiceConsumptionSource(String source) {
+ this.source = source;
+ }
+
+ public static ServiceConsumptionSource getSourceValue(String source) {
+ return sourceToValue.get(source);
+ }
+
+ public String getSource() {
+ return source;
+ }
+}
diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml
index 0908afc628..d9f8ffc7e4 100644
--- a/catalog-be/src/main/resources/config/error-configuration.yaml
+++ b/catalog-be/src/main/resources/config/error-configuration.yaml
@@ -2250,10 +2250,16 @@ errors:
message: "Error: Cannot update or delete interface operation output(s) '%1' mapped to an operation input",
messageId: "SVC4723"
}
-#---------SVC4723-----------------------------
+#---------SVC4724-----------------------------
# %1 - Interface Operation output name
- INTERFACE_OPERATION_MAPPED_OUTPUT_MODIFIED: {
+ INTERFACE_OPERATION_DELETE_WITH_MAPPED_OUTPUT: {
code: 400,
- message: "Error: Cannot update or delete interface operation output(s) '%1' mapped to an operation input",
- messageId: "SVC4723"
+ message: "Error: Cannot delete interface operation with output(s) '%1' mapped to another operation input",
+ messageId: "SVC4724"
+ }
+#---------SVC4725-----------------------------
+ INVALID_CONSUMPTION_TYPE: {
+ code: 400,
+ message: "Error: Given value is different than input type. Needs to be %1",
+ messageId: "SVC4725"
} \ No newline at end of file