aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-be/src/main
diff options
context:
space:
mode:
authorshrek2000 <orenkle@amdocs.com>2019-01-29 13:04:42 +0200
committerAvi Gaffa <avi.gaffa@amdocs.com>2019-01-30 12:18:32 +0000
commitade7fd243fe41b5056ba63d3584ea616ee8bf808 (patch)
tree4be93c8ddfd4577b29fe8553f92d2bd17dbe89b4 /catalog-be/src/main
parent614136b09c5d11bec99fe3c1e23e8c9e022eaa58 (diff)
Add dependent child service to service
Add dependent child service to service Issue-ID: SDC-1987 Change-Id: Ic542fe1bc13f2b77df9944f05421a42b4b21c437 Signed-off-by: shrek2000 <orenkle@amdocs.com>
Diffstat (limited to 'catalog-be/src/main')
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java308
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java87
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/NodeFilterConstraintAction.java20
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java226
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ConstraintConvertor.java138
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceFilterServlet.java258
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/CapabilityFilter.java54
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/NodeFilter.java50
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/NodeFilterConverter.java139
-rw-r--r--catalog-be/src/main/resources/config/error-configuration.yaml62
10 files changed, 1342 insertions, 0 deletions
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 8d4f896d47..9bf442990b 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
@@ -33,8 +33,10 @@ import org.openecomp.sdc.be.components.distribution.engine.INotificationData;
import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload;
import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic;
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.validation.NodeFilterValidator;
import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
import org.openecomp.sdc.be.config.BeEcompErrorManager;
import org.openecomp.sdc.be.config.ConfigurationManager;
@@ -43,7 +45,9 @@ import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
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.RequirementNodeFilterPropertyDataDefinition;
import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
import org.openecomp.sdc.be.datatypes.enums.InstantiationTypes;
import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
@@ -54,6 +58,7 @@ import org.openecomp.sdc.be.impl.WebAppContextWrapper;
import org.openecomp.sdc.be.model.*;
import org.openecomp.sdc.be.model.category.CategoryDefinition;
import org.openecomp.sdc.be.model.jsontitan.operations.ForwardingPathOperation;
+import org.openecomp.sdc.be.model.jsontitan.operations.NodeFilterOperation;
import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation;
import org.openecomp.sdc.be.model.operations.api.IElementOperation;
@@ -120,6 +125,10 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
private ForwardingPathValidator forwardingPathValidator;
@Autowired
private UiComponentDataConverter uiComponentDataConverter;
+ @Autowired
+ private NodeFilterOperation serviceFilterOperation;
+ @Autowired
+ private NodeFilterValidator serviceFilterValidator;
public Either<Service, ResponseFormat> changeServiceDistributionState(String serviceId, String state, LifecycleChangeInfoWithAction commentObj, User user) {
@@ -2107,4 +2116,303 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
return Either.left(dataTransfer);
}
+
+ public Either<String, ResponseFormat> deleteIfNotAlreadyDeletedServiceFilter(String serviceId, String resourceId, String userId, boolean lock) {
+ Service serviceToDelete = initServiceToDeleteServiceFilter(serviceId);
+ User user = validateUserExists(userId, "Create service Filter", false);
+
+ user =
+ validateUser(user, "deleteIfNotAlreadyDeletedServiceFilter", serviceToDelete, null, false);
+
+ Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
+ if (storageStatus.isRight()) {
+ return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
+ }
+ Service service = storageStatus.left().value();
+
+ Either<Boolean, ResponseFormat> response = serviceFilterValidator.validateComponentInstanceExist(service, resourceId);
+ if (storageStatus.isRight()) {
+ return Either.right(response.right().value());
+ }
+ final Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(resourceId);
+ if (!optionalComponentInstance.isPresent() ){
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+ }
+ CINodeFilterDataDefinition nodeFilter = optionalComponentInstance.get().getNodeFilter();
+ if (nodeFilter == null){
+ return Either.left(resourceId);
+ }
+
+ Either<String, StorageOperationStatus> result;
+ if (lock) {
+ Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Service Filter from service");
+ if (lockResult.isRight()) {
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(componentsUtils
+ .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
+ }
+ }
+ try{
+ result = serviceFilterOperation.deleteNodeFilter(service , resourceId);
+ if (result.isRight()) {
+ log.debug("Failed to delete node filter in service {}. Response is {}. ", service.getName(), result.right().value());
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
+ }
+ titanDao.commit();
+ log.debug("Node filter successfully changed in service {} . ", service.getSystemName());
+
+ } catch (Exception e){
+ log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+ } finally {
+ graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
+ }
+ return Either.left(result.left().value());
+ }
+
+
+ private Service initServiceToDeleteServiceFilter(String serviceId) {
+ Service serviceToDelete = new Service();
+ serviceToDelete.setUniqueId(serviceId);
+ return serviceToDelete;
+ }
+
+
+ public Either<CINodeFilterDataDefinition, ResponseFormat> createIfNotAlreadyExistServiceFilter(String serviceId, String componentInstanceId, String userId, boolean lock) {
+ String errorContext = "createIfNotAlreadyExistServiceFilter";
+ User user = validateUserExists(userId, "Create service Filter", false);
+
+ Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
+ if (serviceEither.isRight()) {
+ return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceEither.right().value(), ComponentTypeEnum.SERVICE), ""));
+ }
+ final Service service = serviceEither.left().value();
+ validateUserAndRole(service, user, errorContext);
+
+ Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(componentInstanceId);
+ if (!optionalComponentInstance.isPresent()){
+ return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
+ }
+ ComponentInstance componentInstance = optionalComponentInstance.get();
+ CINodeFilterDataDefinition serviceFilter = componentInstance.getNodeFilter();
+ if (serviceFilter != null){
+ return Either.left(serviceFilter);
+ }
+
+ Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
+
+ Either<Boolean, ResponseFormat> lockResult = null;
+ if (lock) {
+ lockResult =
+ lockComponent(service.getUniqueId(), service, "Create Service Filter");
+ if (lockResult.isRight()) {
+ log.debug("Failed to lock service {}. Response is {}. ", service.getName(),
+ lockResult.right().value().getFormattedMessage());
+ return Either.right(lockResult.right().value());
+ } else {
+ log.debug("The service with system name {} locked. ", service.getSystemName());
+ }
+ }
+ CINodeFilterDataDefinition serviceFilterResult;
+ try {
+ result = serviceFilterOperation.createNodeFilter(serviceId, componentInstanceId);
+ if (result.isRight()) {
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(
+ componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
+ ""));
+ } else {
+ serviceFilterResult = result.left().value();
+ }
+ titanDao.commit();
+
+ } catch (Exception e) {
+ titanDao.rollback();
+ log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
+ e);
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+
+ } finally {
+ if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
+ graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
+ }
+ }
+ return Either.left(serviceFilterResult);
+ }
+
+
+ public Either<CINodeFilterDataDefinition, ResponseFormat> updateServiceFilter(String serviceId, String componentInstanceId,
+ List<String> constraints, User inUser, boolean lock) {
+ String errorContext = "createIfNotAlreadyExistServiceFilter";
+ Either<?, ResponseFormat> eitherCreator1 = null;
+ User user = validateUserExists(inUser, errorContext, true);
+ validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
+ if (eitherCreator1 != null && eitherCreator1.isRight()) {
+ return Either.right(eitherCreator1.right().value());
+ }
+
+ Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
+
+ if(serviceStorageOperationStatusEither.isRight()){
+ StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
+ log.debug("Failed to fetch service information by service id, error {}", errorStatus);
+ return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
+ }
+ Service storedService = serviceStorageOperationStatusEither.left().value();
+
+ Either<Boolean, ResponseFormat> booleanResponseFormatEither =
+ serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId, constraints,
+ NodeFilterConstraintAction.UPDATE);
+ if(booleanResponseFormatEither.isRight()){
+ return Either.right(booleanResponseFormatEither.right().value());
+ }
+
+
+ Either<Boolean, ResponseFormat> lockResult = null;
+ if (lock) {
+ lockResult =
+ lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
+ if (lockResult.isRight()) {
+ log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
+ lockResult.right().value().getFormattedMessage());
+ return Either.right(lockResult.right().value());
+ } else {
+ log.debug("The service with system name {} locked. ", storedService.getSystemName());
+ }
+ }
+ Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
+ if (!componentInstanceOptional.isPresent()){
+ return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
+ }
+ CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
+ if(serviceFilter == null){
+ return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
+ }
+ CINodeFilterDataDefinition serviceFilterResult;
+ try {
+ List<RequirementNodeFilterPropertyDataDefinition> properties = (List<RequirementNodeFilterPropertyDataDefinition>) constraints.
+ stream().map(this::getRequirementNodeFilterPropertyDataDefinition).collect(Collectors.toList());
+ Either<CINodeFilterDataDefinition, StorageOperationStatus> result = serviceFilterOperation.updateProperties(serviceId, componentInstanceId, serviceFilter ,properties);
+
+ if (result.isRight()) {
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(
+ componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
+ ""));
+ } else {
+ serviceFilterResult = result.left().value();
+ }
+ titanDao.commit();
+
+ } catch (Exception e) {
+ titanDao.rollback();
+ log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
+ e);
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+
+ } finally {
+ if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
+ graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
+ }
+ }
+ return Either.left(serviceFilterResult);
+ }
+
+ private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition(String constraint){
+ RequirementNodeFilterPropertyDataDefinition pdd = new RequirementNodeFilterPropertyDataDefinition();
+ pdd.setConstraints(Arrays.asList(constraint));
+ return pdd;
+ }
+
+ public Either<CINodeFilterDataDefinition, ResponseFormat> addOrDeleteServiceFilter(String serviceId, String componentInstanceId,
+ NodeFilterConstraintAction action, String constraint, int position, User inUser, boolean lock) {
+ String errorContext = "createIfNotAlreadyExistServiceFilter";
+ Either<?, ResponseFormat> eitherCreator1 = null;
+ User user = validateUserExists(inUser, errorContext, true);
+ validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
+ if (eitherCreator1 != null && eitherCreator1.isRight()) {
+ return Either.right(eitherCreator1.right().value());
+ }
+
+ Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
+
+ if(serviceStorageOperationStatusEither.isRight()){
+ StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
+ log.debug("Failed to fetch service information by service id, error {}", errorStatus);
+ return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
+ }
+ Service storedService = serviceStorageOperationStatusEither.left().value();
+
+ Either<Boolean, ResponseFormat> booleanResponseFormatEither =
+ serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId,
+ Collections.singletonList(constraint), action);
+ if(booleanResponseFormatEither.isRight()){
+ return Either.right(booleanResponseFormatEither.right().value());
+ }
+
+ Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
+
+ Either<Boolean, ResponseFormat> lockResult = null;
+ if (lock) {
+ lockResult =
+ lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
+ if (lockResult.isRight()) {
+ log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
+ lockResult.right().value().getFormattedMessage());
+ return Either.right(lockResult.right().value());
+ } else {
+ log.debug("The service with system name {} locked. ", storedService.getSystemName());
+ }
+ }
+
+ Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
+ if (!componentInstanceOptional.isPresent()){
+ return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
+ }
+ CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
+ if(serviceFilter == null){
+ return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
+ }
+ CINodeFilterDataDefinition serviceFilterResult;
+ try {
+ switch (action) {
+ case ADD:
+ RequirementNodeFilterPropertyDataDefinition newProperty = new RequirementNodeFilterPropertyDataDefinition();
+ newProperty.setConstraints(Collections.singletonList(constraint));
+ result = serviceFilterOperation.addNewProperty(serviceId, componentInstanceId,serviceFilter,newProperty);
+ break;
+ case DELETE:
+ result = serviceFilterOperation.deleteConstraint(serviceId, componentInstanceId, serviceFilter, position);
+ break;
+ default:
+ log.error("Unsupported operation "+action);
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+
+ }
+
+ if (result.isRight()) {
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(
+ componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
+ ""));
+ } else {
+ serviceFilterResult = result.left().value();
+ }
+ titanDao.commit();
+
+ } catch (Exception e) {
+ titanDao.rollback();
+ log.error("Exception occurred during add or update node filter property values: {}", e.getMessage(),
+ e);
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+
+ } finally {
+ if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
+ graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
+ }
+ }
+ return Either.left(serviceFilterResult);
+ }
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java
new file mode 100644
index 0000000000..73ec3352b3
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.components.impl.utils;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
+import org.openecomp.sdc.be.model.UploadNodeFilterCapabilitiesInfo;
+import org.openecomp.sdc.be.model.UploadNodeFilterInfo;
+import org.openecomp.sdc.be.model.UploadNodeFilterPropertyInfo;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+
+public class CINodeFilterUtils {
+
+ Logger log = Logger.getLogger(CINodeFilterUtils.class);
+
+
+ public CINodeFilterDataDefinition getNodeFilterDataDefinition(
+ UploadNodeFilterInfo uploadNodeFilterInfo, String uniqueId) {
+ CINodeFilterDataDefinition nodeFilterDataDefinition =
+ new CINodeFilterDataDefinition();
+ nodeFilterDataDefinition.setName(uploadNodeFilterInfo.getName());
+ List<RequirementNodeFilterPropertyDataDefinition> collect =
+ uploadNodeFilterInfo.getProperties().stream().map(this::buildProperty).collect(Collectors.toList());
+ ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> listDataDefinition = new ListDataDefinition<>();
+ listDataDefinition.getListToscaDataDefinition().addAll(collect);
+ nodeFilterDataDefinition.setProperties(listDataDefinition);
+ nodeFilterDataDefinition.setCapabilities(converCapabilties(uploadNodeFilterInfo.getCapabilities()));
+ nodeFilterDataDefinition.setID(uniqueId);
+ nodeFilterDataDefinition.setTosca_id(uploadNodeFilterInfo.getTosca_id());
+ return nodeFilterDataDefinition;
+ }
+
+ private ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> converCapabilties(
+ Map<String, UploadNodeFilterCapabilitiesInfo> capabilities) {
+ ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> listDataDefinition =
+ new ListDataDefinition<>();
+ for (UploadNodeFilterCapabilitiesInfo capability : capabilities.values()) {
+ RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition =
+ convertCapability(capability);
+ listDataDefinition.add(requirementNodeFilterCapabilityDataDefinition);
+ }
+ return listDataDefinition;
+ }
+
+ private RequirementNodeFilterCapabilityDataDefinition convertCapability(
+ UploadNodeFilterCapabilitiesInfo capability) {
+ RequirementNodeFilterCapabilityDataDefinition retVal = new RequirementNodeFilterCapabilityDataDefinition();
+ retVal.setName(capability.getName());
+ List<RequirementNodeFilterPropertyDataDefinition> props =
+ capability.getProperties().stream().map(this::buildProperty).collect(Collectors.toList());
+ ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> propsList = new ListDataDefinition<>();
+ propsList.getListToscaDataDefinition().addAll(props);
+ retVal.setProperties(propsList);
+ return retVal;
+ }
+
+
+ private RequirementNodeFilterPropertyDataDefinition buildProperty(
+ UploadNodeFilterPropertyInfo uploadNodeFilterPropertyInfo) {
+ RequirementNodeFilterPropertyDataDefinition retVal = new RequirementNodeFilterPropertyDataDefinition();
+ retVal.setName(uploadNodeFilterPropertyInfo.getName());
+ List<String> propertyConstraints = uploadNodeFilterPropertyInfo.getValues();
+ retVal.setConstraints(propertyConstraints);
+ return retVal;
+ }
+
+
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/NodeFilterConstraintAction.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/NodeFilterConstraintAction.java
new file mode 100644
index 0000000000..32f49b3849
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/NodeFilterConstraintAction.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.openecomp.sdc.be.components.impl.utils;
+
+public enum NodeFilterConstraintAction {
+ ADD, DELETE, UPDATE
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java
new file mode 100644
index 0000000000..8d2808851b
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java
@@ -0,0 +1,226 @@
+package org.openecomp.sdc.be.components.validation;
+
+import com.google.common.collect.ImmutableSet;
+import fj.data.Either;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
+import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
+import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor;
+import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
+import org.openecomp.sdc.be.impl.ComponentsUtils;
+import org.openecomp.sdc.be.model.ComponentInstance;
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.Service;
+import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
+import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
+import org.openecomp.sdc.be.ui.model.UIConstraint;
+import org.openecomp.sdc.exception.ResponseFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+@Component("NodeFilterValidator")
+public class NodeFilterValidator {
+
+ private static final String SOURCE = "Source";
+ public static final Set<String> comparableTypes = ImmutableSet.of(ToscaPropertyType.STRING.getType(),
+ ToscaPropertyType.INTEGER.getType(), ToscaPropertyType.FLOAT.getType());
+ public static final Set<String> schemableTypes =
+ ImmutableSet.of(ToscaPropertyType.MAP.getType(), ToscaPropertyType.LIST.getType());
+ public static final Set<String> comparableConstraintsOperators =
+ ImmutableSet.of(ConstraintConvertor.GREATER_THAN_OPERATOR, ConstraintConvertor.LESS_THAN_OPERATOR);
+
+ @Autowired
+ protected ToscaOperationFacade toscaOperationFacade;
+
+ @Autowired
+ protected ComponentsUtils componentsUtils;
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(NodeFilterValidator.class);
+
+ public Either<Boolean, ResponseFormat> validateComponentInstanceExist(Service service, String componentInstanceId) {
+ if (service == null || StringUtils.isEmpty(componentInstanceId)) {
+ LOGGER.debug("Input data cannot be empty");
+ return getErrorResponse(ActionStatus.NODE_FILTER_NOT_FOUND);
+ }
+ if (CollectionUtils.isEmpty(service.getComponentInstances())) {
+ LOGGER.debug("Component Instance list is empty");
+ return getErrorResponse(ActionStatus.NODE_FILTER_NOT_FOUND);
+ }
+ boolean found =
+ service.getComponentInstances().stream().anyMatch(ci -> ci.getUniqueId().equals(componentInstanceId));
+ if (!found) {
+ LOGGER.debug("Component Instance list is empty");
+ return getErrorResponse(ActionStatus.NODE_FILTER_NOT_FOUND);
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ private Either<Boolean, ResponseFormat> getErrorResponse(ActionStatus actionStatus, String... variables) {
+ ResponseFormat errorResponse = ResponseFormatManager.getInstance().getResponseFormat(actionStatus, variables);
+ return Either.right(errorResponse);
+ }
+
+ public Either<Boolean, ResponseFormat> validateNodeFilter(CINodeFilterDataDefinition nodeFilter, String serviceId,
+ String complonentInstanceId) {
+ return Either.left(Boolean.TRUE);
+ }
+
+
+ public Either<Boolean, ResponseFormat> validateNodeFilter(Service parentComponent, String componentInstanceId,
+ List<String> uiConstraints, NodeFilterConstraintAction action) {
+ try {
+ for (String uiConstraint : uiConstraints) {
+ if (NodeFilterConstraintAction.ADD != action && NodeFilterConstraintAction.UPDATE != action) {
+ break;
+ }
+ UIConstraint constraint = new ConstraintConvertor().convert(uiConstraint);
+ if (ConstraintConvertor.PROPERTY_CONSTRAINT.equals(constraint.getSourceType())) {
+ final Either<Boolean, ResponseFormat> booleanResponseFormatEither =
+ validatePropertyConstraint(parentComponent, componentInstanceId, constraint);
+ if (booleanResponseFormatEither.isRight()) {
+ return booleanResponseFormatEither;
+ }
+ } else if (ConstraintConvertor.STATIC_CONSTRAINT.equals(constraint.getSourceType())) {
+ final Either<Boolean, ResponseFormat> booleanResponseFormatEither =
+ validateStaticValueAndOperator(parentComponent, componentInstanceId, constraint);
+ if (booleanResponseFormatEither.isRight()) {
+ return booleanResponseFormatEither;
+ }
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.debug("Provided constraint" + uiConstraints, e);
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.CONSTRAINT_FORMAT_INCORRECT));
+ }
+
+ return Either.left(true);
+ }
+
+ private Either<Boolean, ResponseFormat> validatePropertyConstraint(Service parentComponent,
+ String componentInstanceId, UIConstraint uiConstraint) {
+ String source = SOURCE;
+ Optional<ComponentInstance> brotherComponentInstance;
+
+ List<? extends PropertyDefinition> sourcePropertyDefinition =
+ parentComponent.getName().equals(uiConstraint.getSourceName()) ? parentComponent.getProperties() :
+ Collections.emptyList();
+
+
+ if (sourcePropertyDefinition.isEmpty() && !parentComponent.getName().equals(uiConstraint.getSourceName())) {
+ brotherComponentInstance = parentComponent.getComponentInstances().stream()
+ .filter(componentInstance -> uiConstraint.getSourceName()
+ .equals(componentInstance
+ .getName()))
+ .findFirst();
+
+ if (brotherComponentInstance.isPresent()) {
+ final List<ComponentInstanceProperty> componentInstanceProperties =
+ parentComponent.getComponentInstancesProperties()
+ .get(brotherComponentInstance.get().getUniqueId());
+ sourcePropertyDefinition =
+ componentInstanceProperties == null ? new ArrayList<>() : componentInstanceProperties;
+ }
+ }
+
+ if (!CollectionUtils.isEmpty(sourcePropertyDefinition)) {
+ Optional<? extends PropertyDefinition> sourceSelectedProperty = sourcePropertyDefinition.stream()
+ .filter(property -> uiConstraint
+ .getValue()
+ .equals(property.getName()))
+ .findFirst();
+
+ Optional<? extends PropertyDefinition> targetComponentInstanceProperty =
+ parentComponent.getComponentInstancesProperties().get(componentInstanceId).stream()
+ .filter(property -> uiConstraint.getServicePropertyName().equals(property.getName()))
+ .findFirst();
+
+ source = !targetComponentInstanceProperty.isPresent() ? "Target" : SOURCE;
+ if (sourceSelectedProperty.isPresent() && targetComponentInstanceProperty.isPresent()) {
+ return validatePropertyData(uiConstraint, sourceSelectedProperty, targetComponentInstanceProperty);
+ }
+ }
+
+ String missingProperty =
+ source.equals(SOURCE) ? uiConstraint.getValue().toString() : uiConstraint.getServicePropertyName();
+
+ return Either.right(
+ componentsUtils.getResponseFormat(ActionStatus.MAPPED_PROPERTY_NOT_FOUND, source, missingProperty));
+ }
+
+ private Either<Boolean, ResponseFormat> validatePropertyData(UIConstraint uiConstraint,
+ Optional<? extends PropertyDefinition> sourceSelectedProperty,
+ Optional<? extends PropertyDefinition> targetComponentInstanceProperty) {
+ final PropertyDefinition sourcePropDefinition = sourceSelectedProperty.get();
+ final String sourceType = sourcePropDefinition.getType();
+ final PropertyDefinition targetPropDefinition = targetComponentInstanceProperty.get();
+ final String targetType = targetPropDefinition.getType();
+ if (sourceType.equals(targetType)) {
+ if (schemableTypes.contains(sourceType)) {
+ final SchemaDefinition sourceSchemaDefinition = sourcePropDefinition.getSchema();
+ final SchemaDefinition targetSchemaDefinition = targetPropDefinition.getSchema();
+ if (!sourceSchemaDefinition.equals(targetSchemaDefinition)) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_SCHEMA_MISMATCH,
+ uiConstraint.getServicePropertyName(), uiConstraint.getValue().toString()));
+ }
+ }
+ return Either.left(Boolean.TRUE);
+ } else {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_PROPERTY_TYPE_MISMATCH,
+ uiConstraint.getServicePropertyName(), uiConstraint.getValue().toString()));
+ }
+ }
+
+ private Either<Boolean, ResponseFormat> validateStaticValueAndOperator(Service parentComponent,
+ String componentInstanceId, UIConstraint uiConstraint) {
+ if (!(Objects.nonNull(uiConstraint) && uiConstraint.getValue() instanceof String)) {
+ return Either.left(false);
+ }
+ Optional<ComponentInstanceProperty> componentInstanceProperty =
+ parentComponent.getComponentInstancesProperties().get(componentInstanceId).stream()
+ .filter(property -> uiConstraint.getServicePropertyName().equals(property.getName()))
+ .findFirst();
+
+ if (!componentInstanceProperty.isPresent()) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.SELECTED_PROPERTY_NOT_PRESENT,
+ uiConstraint.getServicePropertyName()));
+ }
+ if (comparableConstraintsOperators.contains(uiConstraint.getConstraintOperator()) && !comparableTypes.contains(
+ componentInstanceProperty.get().getType())) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_OPERATOR_PROVIDED,
+ uiConstraint.getServicePropertyName(), uiConstraint.getConstraintOperator()));
+ }
+
+ return isValidValueCheck(componentInstanceProperty.get().getType(), String.valueOf(uiConstraint.getValue()),
+ uiConstraint.getServicePropertyName());
+ }
+
+ private Either<Boolean, ResponseFormat> isValidValueCheck(String type, String value, String propertyName) {
+
+ ToscaPropertyType toscaPropertyType = ToscaPropertyType.isValidType(type);
+ if (Objects.isNull(toscaPropertyType)) {
+ return Either.right(
+ componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_PROPERTY_TYPE, type, propertyName));
+ }
+ if (toscaPropertyType.getValidator().isValid(value, null)) {
+ return Either.left(Boolean.TRUE);
+ }
+ return Either.right(
+ componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_VALUE_PROVIDED, type, propertyName, value));
+ }
+
+
+}
+
+
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ConstraintConvertor.java b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ConstraintConvertor.java
new file mode 100644
index 0000000000..e05ef92431
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ConstraintConvertor.java
@@ -0,0 +1,138 @@
+package org.openecomp.sdc.be.datamodel.utils;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType;
+import org.openecomp.sdc.be.ui.model.UIConstraint;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.yaml.snakeyaml.Yaml;
+
+public class ConstraintConvertor {
+
+ private static final Logger logger = LoggerFactory.getLogger(ConstraintConvertor.class);
+
+ public static final String EQUAL_OPERATOR = ConstraintType.EQUAL.getTypes().get(1);
+ public static final String GREATER_THAN_OPERATOR = ConstraintType.GREATER_THAN.getTypes().get(1);
+ public static final String LESS_THAN_OPERATOR = ConstraintType.LESS_THAN.getTypes().get(1);
+ public static final String STATIC_CONSTRAINT = "static";
+ public static final String PROPERTY_CONSTRAINT = "property";
+ public static final String SERVICE_INPUT_CONSTRAINT = "service_input";
+ public static final String SELF = "SELF";
+ private static final Set<String> SUPPORTED_CONSTRAINT_LIST =
+ ImmutableSet.of(EQUAL_OPERATOR, GREATER_THAN_OPERATOR, LESS_THAN_OPERATOR);
+ private static final String GET_INPUT = "get_input";
+ private static final String GET_PROPERTY = "get_property";
+ private static final Set<String> SUPPORTED_FUNCTIONS = ImmutableSet.of(GET_INPUT, GET_PROPERTY);
+
+
+ public UIConstraint convert(String inConstraint) {
+ Yaml yamlSource = new Yaml();
+ UIConstraint uiConstraint = new UIConstraint();
+ Object content1 = yamlSource.load(inConstraint);
+ if (content1 instanceof Map) {
+ Map map1 = (Map) content1;
+ Object key = map1.keySet().iterator().next();
+ uiConstraint.setServicePropertyName(key.toString());
+ Object content2 = map1.get(key);
+ if (content2 instanceof Map && handleServiceConstraint(uiConstraint, (Map) content2)) {
+ return uiConstraint;
+ }
+ }
+ return null;
+ }
+
+ private boolean handleServiceConstraint(UIConstraint uiConstraint, Map content2) {
+ Map map2 = content2;
+ Object key2 = map2.keySet().iterator().next();
+ final String operator = key2.toString();
+ if (SUPPORTED_CONSTRAINT_LIST.contains(operator)) {
+ uiConstraint.setConstraintOperator(operator);
+ }
+ Object content3 = map2.get(key2);
+ if (content3 instanceof String || content3 instanceof Number || content3 instanceof Boolean) {
+ uiConstraint.setValue(content3);
+ uiConstraint.setSourceType(STATIC_CONSTRAINT);
+ return true;
+ } else if (content3 instanceof List) {
+ List list1 = (List) content3;
+ uiConstraint.setSourceType(STATIC_CONSTRAINT);
+ uiConstraint.setValue(list1);
+ return true;
+ } else if (content3 instanceof Map) {
+ Map map3 = (Map) content3;
+ Map.Entry entry = (Map.Entry) map3.entrySet().iterator().next();
+ final String firstKey = entry.getKey().toString().trim();
+ if (handleSupportedFunctions(uiConstraint, entry, firstKey)) {
+ return true;
+ }
+ uiConstraint.setValue(content3);
+ return true;
+ }
+ return false;
+ }
+
+ private boolean handleSupportedFunctions(UIConstraint uiConstraint, Map.Entry entry, String firstKey) {
+ if (SUPPORTED_FUNCTIONS.contains(firstKey)) {
+ if (GET_INPUT.equals(firstKey)) {
+ uiConstraint.setSourceType(SERVICE_INPUT_CONSTRAINT);
+ uiConstraint.setValue(entry.getValue());
+ return true;
+ } else if (GET_PROPERTY.equals(firstKey)) {
+ uiConstraint.setSourceType(PROPERTY_CONSTRAINT);
+ final List<String> value = (List<String>) entry.getValue();
+ uiConstraint.setSourceName(value.get(0));
+ uiConstraint.setValue(value.get(1));
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public List<String> convertToList(List<UIConstraint> uiConstraints) {
+ List<String> retVal = new ArrayList<>();
+ for (UIConstraint uiConstraint : uiConstraints) {
+ String constraint = convert(uiConstraint);
+ if (constraint != null) {
+ retVal.add(constraint);
+ }
+ }
+ return retVal;
+ }
+
+ public String convert(UIConstraint uiConstraint) {
+ try {
+ Map map1 = new HashMap();
+ Map map2 = new HashMap();
+
+ map1.put(uiConstraint.getServicePropertyName(), map2);
+ if (uiConstraint.getSourceType().equals(STATIC_CONSTRAINT)) {
+ Object value = uiConstraint.getValue();
+ if (value instanceof String) {
+ value = new Yaml().load(value.toString());
+ }
+ map2.put(uiConstraint.getConstraintOperator(), value);
+ } else if (uiConstraint.getSourceType().equals(PROPERTY_CONSTRAINT)) {
+ List list1 = Arrays.asList(uiConstraint.getSourceName(), uiConstraint.getValue());
+ Map map3 = ImmutableMap.of(GET_PROPERTY, list1);
+ map2.put(uiConstraint.getConstraintOperator(), map3);
+ } else if (uiConstraint.getSourceType().equals(SERVICE_INPUT_CONSTRAINT)) {
+ Map map3 = ImmutableMap.of(GET_INPUT, uiConstraint.getValue());
+ map2.put(uiConstraint.getConstraintOperator(), map3);
+ }
+
+
+ Yaml yamlSource = new Yaml();
+ return yamlSource.dump(map1);
+ } catch (NullPointerException ex) {
+ logger.error(ex.getMessage(), ex);
+ }
+ return null;
+ }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceFilterServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceFilterServlet.java
new file mode 100644
index 0000000000..3daca3f28c
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceFilterServlet.java
@@ -0,0 +1,258 @@
+package org.openecomp.sdc.be.servlets;
+
+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 java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import javax.inject.Singleton;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
+import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
+import org.openecomp.sdc.be.config.BeEcompErrorManager;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor;
+import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
+import org.openecomp.sdc.be.tosca.utils.NodeFilterConverter;
+import org.openecomp.sdc.be.ui.model.UIConstraint;
+import org.openecomp.sdc.be.ui.model.UINodeFilter;
+import org.openecomp.sdc.common.api.Constants;
+import org.openecomp.sdc.exception.ResponseFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Path("/v1/catalog/services/{serviceId}/resourceInstances/{resourceInstanceId}/nodeFilter")
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Api(value = "Service Filter", description = "Service Filter Servlet")
+@Singleton
+public class ServiceFilterServlet extends AbstractValidationsServlet {
+
+ private static final Logger log = LoggerFactory.getLogger(ServiceFilterServlet.class);
+ private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
+ private static final String MODIFIER_ID_IS = "modifier id is {}";
+ private static final String FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER = "failed to update or create node filter";
+ private static final String FAILED_TO_PARSE_SERVICE = "failed to parse service";
+ private static final String NODE_FILTER_CREATION_OR_UPDATE = "Node Filter Creation or update";
+ private static final String CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR =
+ "create or update node filter with an error";
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/")
+ @ApiOperation(value = "Add Service Filter Constraint", httpMethod = "POST", notes = "Add Service Filter Constraint",
+ response = Response.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Service Filter"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+ public Response addServiceFilterConstraint(@ApiParam(value = "Service data", required = true) String data,
+ @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
+ @ApiParam(value = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId,
+ @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+ String url = request.getMethod() + " " + request.getRequestURI();
+ log.debug(START_HANDLE_REQUEST_OF, url);
+ final HttpSession session = request.getSession();
+ ServletContext context = session.getServletContext();
+ User modifier = new User();
+ modifier.setUserId(userId);
+ log.debug(MODIFIER_ID_IS, userId);
+
+ Response response;
+
+ try {
+ String serviceIdLower = serviceId.toLowerCase();
+ ServiceBusinessLogic businessLogic = getServiceBL(context);
+
+ Either<UIConstraint, ResponseFormat> convertResponse = parseToConstraint(data, modifier);
+ if (convertResponse.isRight()) {
+ log.debug(FAILED_TO_PARSE_SERVICE);
+ response = buildErrorResponse(convertResponse.right().value());
+ return response;
+ }
+ UIConstraint uiConstraint = convertResponse.left().value();
+ if (uiConstraint == null) {
+ log.debug(FAILED_TO_PARSE_SERVICE);
+ response = buildErrorResponse(convertResponse.right().value());
+ return response;
+ }
+ Either<CINodeFilterDataDefinition, ResponseFormat> actionResponse;
+ String constraint = new ConstraintConvertor().convert(uiConstraint);
+ actionResponse = businessLogic
+ .addOrDeleteServiceFilter(serviceIdLower, ciId, NodeFilterConstraintAction.ADD,
+ constraint, -1, modifier, true);
+
+ if (actionResponse.isRight()) {
+ log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER);
+ response = buildErrorResponse(actionResponse.right().value());
+ return response;
+ }
+
+ CINodeFilterDataDefinition value = actionResponse.left().value();
+ UINodeFilter nodeFilter = new NodeFilterConverter().convertToUi(value);
+ return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), nodeFilter);
+
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE);
+ log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e);
+ response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+ return response;
+
+ }
+ }
+
+ @PUT
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/")
+ @ApiOperation(value = "Update Service Filter Constraint", httpMethod = "PUT",
+ notes = "Update Service Filter Constraint", response = Response.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Service Filter"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+ public Response updateServiceFilterConstraint(@ApiParam(value = "Service data", required = true) String data,
+ @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
+ @ApiParam(value = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId,
+ @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+ ServletContext context = request.getSession().getServletContext();
+ String url = request.getMethod() + " " + request.getRequestURI();
+ log.debug(START_HANDLE_REQUEST_OF, url);
+
+ User modifier = new User();
+ modifier.setUserId(userId);
+ log.debug(MODIFIER_ID_IS, userId);
+
+ Response response;
+
+ try {
+ String serviceIdLower = serviceId.toLowerCase();
+ ServiceBusinessLogic businessLogic = getServiceBL(context);
+
+ Either<List, ResponseFormat> convertResponse = parseToConstraints(data, modifier);
+ if (convertResponse.isRight()) {
+ log.debug(FAILED_TO_PARSE_SERVICE);
+ response = buildErrorResponse(convertResponse.right().value());
+ return response;
+ }
+ List<Map<String,String>> uiConstraintsMaps = (List<Map<String,String>>) convertResponse.left().value();
+ if (uiConstraintsMaps == null) {
+ log.debug("failed to parse data");
+ response = buildErrorResponse(convertResponse.right().value());
+ return response;
+ }
+ final ObjectMapper objectMapper = new ObjectMapper();
+ List<UIConstraint> uiConstraints = uiConstraintsMaps.stream().map(dataMap -> objectMapper.convertValue(dataMap, UIConstraint.class)).collect(
+ Collectors.toList());
+ if (uiConstraints == null) {
+ log.debug("failed to parse data");
+ response = buildErrorResponse(convertResponse.right().value());
+ return response;
+ }
+ Either<CINodeFilterDataDefinition, ResponseFormat> actionResponse;
+ List<String> constraints = new ConstraintConvertor().convertToList(uiConstraints);
+ actionResponse = businessLogic.updateServiceFilter(serviceIdLower, ciId, constraints, modifier, true);
+
+ if (actionResponse.isRight()) {
+ log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER);
+ response = buildErrorResponse(actionResponse.right().value());
+ return response;
+ }
+
+ CINodeFilterDataDefinition value = actionResponse.left().value();
+ return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
+ new NodeFilterConverter().convertToUi(value));
+
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE);
+ log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e);
+ response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+ return response;
+
+ }
+ }
+
+ @DELETE
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/{constraintIndex}")
+ @ApiOperation(value = "Delete Service Filter Constraint", httpMethod = "Delete",
+ notes = "Delete Service Filter Constraint", response = Response.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete Service Filter Constraint"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+ public Response deleteServiceFilterConstraint(
+ @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
+ @ApiParam(value = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId,
+ @ApiParam(value = "Constraint Index") @PathParam("constraintIndex") int index,
+ @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+ ServletContext context = request.getSession().getServletContext();
+ String url = request.getMethod() + " " + request.getRequestURI();
+ log.debug(START_HANDLE_REQUEST_OF, url);
+
+ User modifier = new User();
+ modifier.setUserId(userId);
+ log.debug(MODIFIER_ID_IS, userId);
+
+ Response response;
+
+ try {
+ String serviceIdLower = serviceId.toLowerCase();
+ ServiceBusinessLogic businessLogic = getServiceBL(context);
+
+ Either<CINodeFilterDataDefinition, ResponseFormat> actionResponse;
+ actionResponse = businessLogic
+ .addOrDeleteServiceFilter(serviceIdLower, ciId, NodeFilterConstraintAction.DELETE,
+ null, index, modifier, true);
+
+ if (actionResponse.isRight()) {
+
+ log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER);
+ response = buildErrorResponse(actionResponse.right().value());
+ return response;
+ }
+
+ final CINodeFilterDataDefinition value = actionResponse.left().value();
+ return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
+ new NodeFilterConverter().convertToUi(value));
+
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE);
+ log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e);
+ response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+ return response;
+
+ }
+ }
+
+ private Either<UIConstraint, ResponseFormat> parseToConstraint(String serviceJson, User user) {
+ return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, UIConstraint.class,
+ AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
+ }
+
+ private Either<List, ResponseFormat> parseToConstraints(String serviceJson, User user) {
+ return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, List.class,
+ AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
+ }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/CapabilityFilter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/CapabilityFilter.java
new file mode 100644
index 0000000000..58a9a759bf
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/CapabilityFilter.java
@@ -0,0 +1,54 @@
+/*
+ * 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.tosca.model;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.collections.CollectionUtils;
+
+
+
+public class CapabilityFilter {
+
+ List<Map<String, List<Object>>> properties;
+
+ public List<Map<String, List<Object>>> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(List<Map<String, List<Object>>> properties) {
+ this.properties = properties;
+ }
+
+ public void addProperty(Map<String, List<Object>> property) {
+ if(CollectionUtils.isEmpty(properties)) {
+ this.properties = new ArrayList<>();
+ }
+
+ this.properties.add(property);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("CapabilityFilter{");
+ sb.append("properties=").append(properties);
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/NodeFilter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/NodeFilter.java
new file mode 100644
index 0000000000..79e9f57209
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/NodeFilter.java
@@ -0,0 +1,50 @@
+/*
+ * 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.tosca.model;
+
+import java.util.List;
+import java.util.Map;
+
+public class NodeFilter {
+
+ Object tosca_id;
+ List<Map<String, List<Object>>> properties;
+ List<Map<String, CapabilityFilter>> capabilities;
+
+ public Object getTosca_id() {
+ return tosca_id;
+ }
+
+ public void setTosca_id(Object tosca_id) {
+ this.tosca_id = tosca_id;
+ }
+
+ public List<Map<String, CapabilityFilter>> getCapabilities() {
+ return capabilities;
+ }
+
+ public void setCapabilities(List<Map<String, CapabilityFilter>> capabilities) {
+ this.capabilities = capabilities;
+ }
+
+ public List<Map<String, List<Object>>> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(List<Map<String, List<Object>>> properties) {
+ this.properties = properties;
+ }
+} \ No newline at end of file
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/NodeFilterConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/NodeFilterConverter.java
new file mode 100644
index 0000000000..af0837fdcf
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/NodeFilterConverter.java
@@ -0,0 +1,139 @@
+/*
+ * 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.tosca.utils;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.apache.commons.collections.CollectionUtils;
+import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor;
+import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
+import org.openecomp.sdc.be.tosca.model.CapabilityFilter;
+import org.openecomp.sdc.be.tosca.model.NodeFilter;
+import org.openecomp.sdc.be.ui.model.UIConstraint;
+import org.openecomp.sdc.be.ui.model.UINodeFilter;
+
+public class NodeFilterConverter {
+
+
+ public NodeFilter convertNodeFilter(CINodeFilterDataDefinition nodeFilterData) {
+ NodeFilter retVal = new NodeFilter();
+ if (nodeFilterData.getCapabilities() != null) {
+ retVal.setCapabilities(convertCapabilities(nodeFilterData.getCapabilities().getListToscaDataDefinition()));
+ }
+ if (nodeFilterData.getProperties() != null) {
+ retVal.setProperties(convertProperties(nodeFilterData.getProperties().getListToscaDataDefinition()));
+ }
+ return retVal;
+ }
+
+ private List<Map<String, CapabilityFilter>> convertCapabilities(
+ List<RequirementNodeFilterCapabilityDataDefinition> capabilities) {
+ if (CollectionUtils.isEmpty(capabilities)) {
+ return Collections.emptyList();
+ }
+ return capabilities.stream().map(this::transformCapability).collect(Collectors.toList());
+ }
+
+ private Map<String, CapabilityFilter> transformCapability(
+ RequirementNodeFilterCapabilityDataDefinition capability) {
+ Map<String, CapabilityFilter> retVal = new HashMap<>();
+ if (capability.getProperties() == null) {
+ return retVal;
+ }
+ List<RequirementNodeFilterPropertyDataDefinition> propertyDataDefinitionList =
+ capability.getProperties().getListToscaDataDefinition();
+ for (RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : propertyDataDefinitionList) {
+ retVal.put(capability.getName(), convertCapabilityProperty(propertyDataDefinition));
+ }
+ return retVal;
+ }
+
+ private List<Map<String, List<Object>>> convertProperties(
+ List<RequirementNodeFilterPropertyDataDefinition> properties) {
+ if (CollectionUtils.isEmpty(properties)) {
+ return Collections.emptyList();
+ }
+ return properties.stream().map(this::transformProperty).collect(Collectors.toList());
+ }
+
+ private CapabilityFilter convertCapabilityProperty(RequirementNodeFilterPropertyDataDefinition property) {
+ TransformCapabilityData transformCapabilityData = new TransformCapabilityData(property).invoke();
+ Map<String, List<Object>> tranformedMap = transformCapabilityData.getRetVal();
+ List<Object> constraints = transformCapabilityData.getConstraints();
+ tranformedMap.put(property.getName(), constraints);
+ CapabilityFilter capabilityFilter = new CapabilityFilter();
+ capabilityFilter.setProperties(Collections.singletonList(tranformedMap));
+ return capabilityFilter;
+ }
+
+
+ private Map<String, List<Object>> transformProperty(RequirementNodeFilterPropertyDataDefinition property) {
+ TransformCapabilityData transformCapabilityData = new TransformCapabilityData(property).invoke();
+ Map<String, List<Object>> retVal = transformCapabilityData.getRetVal();
+ List<Object> constraints = transformCapabilityData.getConstraints();
+ retVal.put(property.getName(), constraints);
+
+ return retVal;
+ }
+
+ private class TransformCapabilityData {
+
+ private RequirementNodeFilterPropertyDataDefinition property;
+ private Map<String, List<Object>> retVal;
+ private List<Object> constraints;
+
+ public TransformCapabilityData(RequirementNodeFilterPropertyDataDefinition property) {
+ this.property = property;
+ }
+
+ public Map<String, List<Object>> getRetVal() {
+ return retVal;
+ }
+
+ public List<Object> getConstraints() {
+ return constraints;
+ }
+
+ public TransformCapabilityData invoke() {
+ final List<String> propertyConstraints = property.getConstraints();
+ if (CollectionUtils.isEmpty(propertyConstraints)) {
+ return this;
+ }
+ this.constraints = propertyConstraints.stream().map(c -> (Object) c).collect(Collectors.toList());
+ return this;
+ }
+ }
+
+ public UINodeFilter convertToUi(CINodeFilterDataDefinition inNodeFilter) {
+ UINodeFilter retVal = new UINodeFilter();
+ final ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+ if (inNodeFilter.getProperties() == null || inNodeFilter.getProperties().isEmpty()) {
+ return retVal;
+ }
+ List<UIConstraint> constraints = inNodeFilter.getProperties().getListToscaDataDefinition().stream()
+ .map(property -> property.getConstraints().iterator().next())
+ .map(str -> constraintConvertor.convert(str))
+ .collect(Collectors.toList());
+ retVal.setProperties(constraints);
+ return retVal;
+ }
+}
diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml
index 315027b43e..69f67e63ed 100644
--- a/catalog-be/src/main/resources/config/error-configuration.yaml
+++ b/catalog-be/src/main/resources/config/error-configuration.yaml
@@ -2173,6 +2173,68 @@ errors:
message: "Error: Invalid input, only pre-defined operation names are allowed in global interface type '%1'",
messageId: "SVC4713"
}
+
+ #---------SVC4714-----------------------------
+ NODE_FILTER_NOT_FOUND: {
+ code: 400,
+ message: "Error: Node Filter was not found",
+ messageId: "SVC4714"
+ }
+ #---------SVC4715----------------------------
+ UNSUPPORTED_VALUE_PROVIDED: {
+ code: 400,
+ message: "Error: Supported value type is %1 for %2 property. Provided Value: %3",
+ messageId: "SVC4715"
+ }
+ #---------SVC4716----------------------------
+ # %1 - Property Name
+ SELECTED_PROPERTY_NOT_PRESENT: {
+ code: 400,
+ message: "Error: %1 property does not exists in Service anymore.",
+ messageId: "SVC4716"
+ }
+
+ #---------SVC4717----------------------------
+ # %1 - Property Name
+ MAPPED_PROPERTY_NOT_FOUND: {
+ code: 400,
+ message: "Error: %1 property does not exist.",
+ messageId: "SVC4717"
+ }
+
+ #---------SVC4718----------------------------
+ # %1 - Property Name
+ # %2 - Operator Name
+ UNSUPPORTED_OPERATOR_PROVIDED: {
+ code: 400,
+ message: "Error: %1 property does not support %2 operator.",
+ messageId: "SVC4718"
+ }
+
+ #---------SVC4719----------------------------
+ CONSTRAINT_FORMAT_INCORRECT: {
+ code: 400,
+ message: "Error: Constraint provided does not contains expected values.",
+ messageId: "SVC4719"
+ }
+
+ #---------SVC4720----------------------------
+ # %1 - Property Name
+ # %2 - Operator Type
+ SOURCE_TARGET_PROPERTY_TYPE_MISMATCH: {
+ code: 400,
+ message: "Error: %1 property and %2 property type is not same.",
+ messageId: "SVC4720"
+ }
+
+ #---------SVC4721----------------------------
+ # %1 - Property Type
+ # %2 - Operator Type
+ UNSUPPORTED_PROPERTY_TYPE: {
+ code: 400,
+ message: "Error: Property type %1 provided against %2 is not supported for static value.",
+ messageId: "SVC4721"
+ }
#---------SVC4714-----------------------------
# %1 - Interface Operation output name
INTERFACE_OPERATION_MAPPED_OUTPUT_DELETED: {