Add dependent child service to service 42/78042/4
authorshrek2000 <orenkle@amdocs.com>
Thu, 7 Feb 2019 10:57:08 +0000 (12:57 +0200)
committershrek2000 <orenkle@amdocs.com>
Thu, 7 Feb 2019 14:21:31 +0000 (16:21 +0200)
Add dependent child service to service
Issue-ID: SDC-1987

Change-Id: I5a650f57a27587c4ce6f33059719060ffa1f13de
Signed-off-by: shrek2000 <orenkle@amdocs.com>
44 files changed:
catalog-be/pom.xml
catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/NodeFilterUploadCreator.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/DirectivesUtils.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/MapUtils.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/ProxyServicePropertiesUtils.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java
catalog-be/src/main/java/org/openecomp/sdc/be/impl/ServiceFilterUtils.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplate.java
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/NodeFilterConverter.java
catalog-be/src/main/resources/config/error-configuration.yaml
catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/BaseServiceFilterUtilsTest.java [new file with mode: 0644]
catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterRenameCiTest.java [new file with mode: 0644]
catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsCIChangeTest.java [new file with mode: 0644]
catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsPropertyRemovedTest.java [new file with mode: 0644]
catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsServiceInputTest.java [new file with mode: 0644]
catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfo.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/TopologyTemplate.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperation.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java
catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UiComponentDataTransfer.java
common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ComponentInstanceDataDefinition.java
common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/JsonPresentationFields.java
common-be/src/main/java/org/openecomp/sdc/be/utils/TypeUtils.java
pom.xml
test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/api/Urls.java
test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ComponentInstanceReqDetails.java
test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/PropertyReqDetails.java
test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceFilterDetails.java [new file with mode: 0644]
test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/servicefilter/ServiceFilterTests.java [new file with mode: 0644]
test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/general/ElementFactory.java
test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/PropertyRestUtils.java
test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ServiceFilterUtils.java [new file with mode: 0644]
test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ServiceRestUtils.java
test-apis-ci/src/main/resources/ci/testSuites/onapApiSanity.xml

index 4ebbf82..8ab854c 100644 (file)
             <version>${project.version}</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.onap.sdc.common</groupId>
+            <artifactId>onap-tosca-datatype</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+        </dependency>
 
         <!-- Swagger Dependencies Start -->
         <dependency>
index 9bc2d01..48152ea 100644 (file)
@@ -10,6 +10,7 @@ import org.apache.commons.lang.StringUtils;
 import org.openecomp.sdc.be.components.impl.AnnotationBusinessLogic;
 import org.openecomp.sdc.be.components.impl.GroupTypeBusinessLogic;
 import org.openecomp.sdc.be.components.impl.ImportUtils;
+import org.openecomp.sdc.be.components.impl.NodeFilterUploadCreator;
 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
@@ -19,6 +20,7 @@ import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
+import org.openecomp.sdc.be.utils.TypeUtils;
 import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.stereotype.Component;
 import org.yaml.snakeyaml.parser.ParserException;
@@ -449,6 +451,8 @@ public class YamlTemplateParsingHandler {
                 setRequirements(nodeTemplateInfo, nodeTemplateJsonMap);
                 setCapabilities(nodeTemplateInfo, nodeTemplateJsonMap);
                 updateProperties(nodeTemplateInfo, nodeTemplateJsonMap);
+                setDirectives(nodeTemplateInfo, nodeTemplateJsonMap);
+                setNodeFilter(nodeTemplateInfo, nodeTemplateJsonMap);
                 setSubstitutions(substitutionMappings, nodeTemplateInfo);
             } else {
                 rollbackWithException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE);
@@ -514,6 +518,22 @@ public class YamlTemplateParsingHandler {
         }
     }
 
+    private void setDirectives(UploadComponentInstanceInfo nodeTemplateInfo,
+            Map<String, Object> nodeTemplateJsonMap) {
+        List<String> directives =
+                (List<String>) nodeTemplateJsonMap.get(TypeUtils.ToscaTagNamesEnum.DIRECTIVES.getElementName());
+        nodeTemplateInfo.setDirectives(directives);
+    }
+
+    private void setNodeFilter(UploadComponentInstanceInfo nodeTemplateInfo,
+            Map<String, Object> nodeTemplateJsonMap) {
+        if (nodeTemplateJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.NODE_FILTER.getElementName())) {
+            nodeTemplateInfo.setUploadNodeFilterInfo(
+                    new NodeFilterUploadCreator().createNodeFilterData(nodeTemplateJsonMap.get(
+                            TypeUtils.ToscaTagNamesEnum.NODE_FILTER.getElementName())));
+        }
+    }
+
     @SuppressWarnings("unchecked")
     private Map<String, List<UploadReqInfo>> createReqModuleFromYaml(Map<String, Object> nodeTemplateJsonMap) {
         Map<String, List<UploadReqInfo>> moduleRequirements = new HashMap<>();
index 8c7c473..dd8cec3 100644 (file)
@@ -27,8 +27,10 @@ import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.openecomp.sdc.be.components.impl.instance.ComponentInstanceChangeOperationOrchestrator;
+import org.openecomp.sdc.be.components.impl.utils.DirectivesUtils;
 import org.openecomp.sdc.be.components.merge.instance.ComponentInstanceMergeDataBusinessLogic;
 import org.openecomp.sdc.be.components.merge.instance.DataForMergeHolder;
+import org.openecomp.sdc.be.components.utils.ProxyServicePropertiesUtils;
 import org.openecomp.sdc.be.components.validation.ComponentValidations;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
@@ -36,6 +38,7 @@ import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
@@ -47,10 +50,12 @@ import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
+import org.openecomp.sdc.be.impl.ServiceFilterUtils;
 import org.openecomp.sdc.be.info.CreateAndAssotiateInfo;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.ComponentParametersView;
 import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.RequirementDefinition;
 import org.openecomp.sdc.be.model.Resource;
 import org.openecomp.sdc.be.model.Service;
@@ -69,6 +74,7 @@ import org.openecomp.sdc.be.model.ComponentInstanceInput;
 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
 import org.openecomp.sdc.be.model.PropertyDefinition.PropertyNames;
 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.jsontitan.utils.ModelConverter;
 import org.openecomp.sdc.be.model.operations.api.IComponentInstanceOperation;
@@ -136,6 +142,9 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
     @Autowired
     private ForwardingPathOperation forwardingPathOperation;
 
+    @Autowired
+    private NodeFilterOperation serviceFilterOperation;
+
     public ComponentInstanceBusinessLogic() {
     }
 
@@ -301,7 +310,11 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         filter.setIgnoreCapabiltyProperties(false);
         filter.setIgnoreComponentInstances(false);
         filter.setIgnoreRequirements(false);
-        Either<Component, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(resourceInstance.getComponentUid(), filter);
+        filter.setIgnoreInterfaces(false);
+        filter.setIgnoreProperties(false);
+        filter.setIgnoreInputs(false);
+        Either<Component, StorageOperationStatus> serviceRes =
+                toscaOperationFacade.getToscaElement(resourceInstance.getComponentUid(), filter);
         if (serviceRes.isRight()) {
             return serviceRes.right().value();
         }
@@ -311,6 +324,14 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         Map<String, List<RequirementDefinition>> req = service.getRequirements();
         resourceInstance.setRequirements(req);
 
+        Map<String, InterfaceDefinition> serviceInterfaces = service.getInterfaces();
+        if(MapUtils.isNotEmpty(serviceInterfaces)) {
+            serviceInterfaces.forEach(resourceInstance::addInterface);
+        }
+
+
+        resourceInstance.setProperties(ProxyServicePropertiesUtils.getProperties(service));
+
         String name = service.getNormalizedName() + ToscaOperationFacade.PROXY_SUFFIX;
         String toscaResourceName = ((Resource) proxyTemplate).getToscaResourceName();
         int lastIndexOf = toscaResourceName.lastIndexOf('.');
@@ -718,7 +739,6 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
                             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, containerComponentType.getValue(), origInst.getName()));
                             return resultOp;
                         }
-
                         listForUpdate.add(updatedCi);
                     } else
                         listForUpdate.add(origInst);
@@ -789,8 +809,22 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the name of the component instance {} to {}. A component instance with the same name already exists. ", oldComponentInstance.getName(), newInstanceName);
                 resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, containerComponentType.getValue(), componentInstance.getName()));
             }
+            if(!DirectivesUtils.isValid(componentInstance.getDirectives())) {
+                final String directivesStr =
+                        componentInstance.getDirectives().stream().collect(Collectors.joining(" , ", " [ ", " ] "));
+                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
+                        "Failed to update the directives of the component instance {} to {}. Directives data {} is invalid. ",
+                        oldComponentInstance.getName(), newInstanceName ,
+                        directivesStr);
+                resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.DIRECTIVES_INVALID_VALUE,
+                        directivesStr));
+            }
         }
+        String newInstanceName = componentInstance.getName();
+        String oldInstanceName = null;
         if (resultOp == null) {
+            oldComponentInstance = componentInstanceOptional.get();
+            newInstanceName = componentInstance.getName();
             updateRes = toscaOperationFacade.updateComponentInstanceMetadataOfTopologyTemplate(containerComponent, origComponent, updateComponentInstanceMetadata(oldComponentInstance, componentInstance));
             if (updateRes.isRight()) {
                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update metadata of component instance {} belonging to container component {}. Status is {}. ", componentInstance.getName(), containerComponent.getName(),
@@ -802,6 +836,14 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
                     Either result = toscaOperationFacade.cleanAndAddGroupInstancesToComponentInstance(containerComponent, oldComponentInstance, componentInstanceId);
                     if (result.isRight())
                         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to rename group instances for container {}. error {} ", componentInstanceId, result.right().value());
+                    if (containerComponent instanceof Service) {
+                        Either<ComponentInstance, ResponseFormat> renameEither =
+                                renameServiceFilter((Service) containerComponent, newInstanceName,
+                                        oldInstanceName);
+                        if (renameEither.isRight()) {
+                            return renameEither;
+                        }
+                    }
                 }
                 // endregion
             }
@@ -824,6 +866,27 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         return resultOp;
     }
 
+
+    public Either<ComponentInstance, ResponseFormat> renameServiceFilter(Service containerComponent,
+            String newInstanceName, String oldInstanceName) {
+
+        Map<String, CINodeFilterDataDefinition> renamedNodesFilter =
+                ServiceFilterUtils.getRenamedNodesFilter((Service) containerComponent,
+                        oldInstanceName, newInstanceName);
+        for( Entry<String, CINodeFilterDataDefinition> entry :  renamedNodesFilter.entrySet()){
+            Either<CINodeFilterDataDefinition, StorageOperationStatus>
+                    renameEither = serviceFilterOperation.updateNodeFilter(
+                    containerComponent.getUniqueId(),entry.getKey(),entry.getValue());
+            if (renameEither.isRight()){
+                return  Either.right(componentsUtils.getResponseFormatForResourceInstance(
+                        componentsUtils.convertFromStorageResponse(renameEither.right().value(), ComponentTypeEnum.SERVICE),
+                        containerComponent.getName(), null));
+            }
+
+        }
+        return Either.left(null);
+    }
+
     /**
      * @param oldPrefix-
      *            The normalized old vf name
@@ -847,6 +910,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         oldComponentInstance.setName(newComponentInstance.getName());
         oldComponentInstance.setModificationTime(System.currentTimeMillis());
         oldComponentInstance.setCustomizationUUID(UUID.randomUUID().toString());
+        oldComponentInstance.setDirectives(newComponentInstance.getDirectives());
         if (oldComponentInstance.getGroupInstances() != null)
             oldComponentInstance.getGroupInstances().forEach(group -> group.setName(getNewGroupName(oldComponentInstance.getNormalizedName(), ValidationUtils.normalizeComponentInstanceName(newComponentInstance.getName()), group.getName())));
         return oldComponentInstance;
@@ -879,6 +943,23 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
 
         Either<ComponentInstance, ResponseFormat> resultOp = null;
         try {
+            if (containerComponent instanceof Service) {
+                ComponentInstance componentInstance = containerComponent.getComponentInstanceById(componentInstanceId).get();
+                Either<String, StorageOperationStatus> deleteServiceFilterEither =
+                        serviceFilterOperation.deleteNodeFilter((Service) containerComponent, componentInstanceId);
+                if (deleteServiceFilterEither.isRight()) {
+                    ActionStatus status = componentsUtils.convertFromStorageResponse(deleteServiceFilterEither.right().value(),
+                            containerComponentType);
+                    titanDao.rollback();
+                    return Either.right(componentsUtils.getResponseFormat(status, componentInstanceId));
+                }
+                resultOp = deleteServiceFiltersRelatedTobeDeletedComponentInstance((Service) containerComponent,
+                        componentInstance, ComponentTypeEnum.SERVICE, userId);
+                if (resultOp.isRight()) {
+                    titanDao.rollback();
+                    return resultOp;
+                }
+            }
             resultOp = deleteComponentInstance(containerComponent, componentInstanceId, containerComponentType);
             if (resultOp.isRight()){
                 return resultOp;
@@ -895,6 +976,60 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         }
     }
 
+    public Either<ComponentInstance, ResponseFormat> deleteServiceFiltersRelatedTobeDeletedComponentInstance(
+            Service service, ComponentInstance componentInstance, ComponentTypeEnum containerComponentType, String userId) {
+        if (containerComponentType.equals(ComponentTypeEnum.SERVICE)) {
+            Set<String> serviceFiltersIDsToBeDeleted =
+                    getServiceFiltersRelatedToComponentInstance(service.getUniqueId(), componentInstance);
+            if (!serviceFiltersIDsToBeDeleted.isEmpty()) {
+                Set<String> ids = service.getComponentInstances().stream()
+                                         .filter(ci -> serviceFiltersIDsToBeDeleted
+                                                               .contains(ci.getName()))
+                                         .map(ComponentInstance::getUniqueId)
+                                         .collect(Collectors.toSet());
+                Either<Set<String>, StorageOperationStatus> deleteServiceFiltersEither =
+                        serviceFilterOperation.deleteNodeFilters(service, ids);
+                if (deleteServiceFiltersEither.isRight()) {
+                    ActionStatus status = componentsUtils.convertFromStorageResponse(deleteServiceFiltersEither.right().value(),
+                            containerComponentType);
+                    return Either.right(componentsUtils.getResponseFormat(status, componentInstance.getName()));
+                }
+                for (String id : ids) {
+                    final Optional<ComponentInstance> componentInstanceById = service.getComponentInstanceById(id);
+                    if (!componentInstanceById.isPresent()){
+                        return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+                    }
+                    ComponentInstance ci = componentInstanceById.get();
+                    List<String> directives = ci.getDirectives();
+                    directives.remove(DirectivesUtils.SELECTABLE);
+                    ci.setDirectives(directives);
+                    final Either<ComponentInstance, ResponseFormat> componentInstanceResponseFormatEither =
+                            updateComponentInstanceMetadata(ComponentTypeEnum.SERVICE_PARAM_NAME, service.getUniqueId(),
+                                    ci.getUniqueId(), userId, ci, true, false, false);
+                    if (componentInstanceResponseFormatEither.isRight()) {
+                        return componentInstanceResponseFormatEither;
+                    }
+                }
+            }
+        }
+        return Either.left(componentInstance);
+    }
+
+
+
+    private Set<String> getServiceFiltersRelatedToComponentInstance(String containerComponentId,
+            ComponentInstance componentInstance) {
+        ComponentParametersView filter = new ComponentParametersView(true);
+        filter.setIgnoreComponentInstances(false);
+        Either<Service, StorageOperationStatus> serviceFilterOrigin =
+                toscaOperationFacade.getToscaElement(containerComponentId, filter);
+        final Service service = serviceFilterOrigin.left().value();
+        final Set<String> nodesFiltersToBeDeleted = ServiceFilterUtils.getNodesFiltersToBeDeleted(service,
+                componentInstance);
+        return nodesFiltersToBeDeleted;
+    }
+
+
     public Either<ComponentInstance, ResponseFormat> deleteForwardingPathsRelatedTobeDeletedComponentInstance(String containerComponentId, ComponentTypeEnum containerComponentType,
                                                                                                               Either<ComponentInstance, ResponseFormat> resultOp) {
         if(containerComponentType.equals(ComponentTypeEnum.SERVICE) && resultOp.isLeft() ){
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/NodeFilterUploadCreator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/NodeFilterUploadCreator.java
new file mode 100644 (file)
index 0000000..444ac0b
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.onap.sdc.tosca.services.YamlUtil;
+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.be.utils.TypeUtils;
+
+public class NodeFilterUploadCreator {
+
+
+    public UploadNodeFilterInfo createNodeFilterData(Object obj) {
+        if (!(obj instanceof Map)) {
+            return null;
+        }
+        Map<String, Object> nodeFilterMap = (Map<String, Object>) obj;
+
+        UploadNodeFilterInfo uploadNodeFilterInfo = new UploadNodeFilterInfo();
+        final String propertiesElementName = TypeUtils.ToscaTagNamesEnum.PROPERTIES.getElementName();
+        if (nodeFilterMap.containsKey(propertiesElementName)) {
+            uploadNodeFilterInfo.setProperties(createNodeFilterProperties(nodeFilterMap.get(propertiesElementName)));
+        }
+        final String capabilitiesElementName = TypeUtils.ToscaTagNamesEnum.CAPABILITIES.getElementName();
+        if (nodeFilterMap.containsKey(capabilitiesElementName)) {
+            uploadNodeFilterInfo
+                    .setCapabilities(createNodeFilterCapabilities(nodeFilterMap.get(capabilitiesElementName)));
+        }
+        final String toscaId = TypeUtils.ToscaTagNamesEnum.TOSCA_ID.getElementName();
+        if (nodeFilterMap.containsKey(toscaId)) {
+            uploadNodeFilterInfo.setTosca_id(nodeFilterMap.get(toscaId));
+        }
+        return uploadNodeFilterInfo;
+    }
+
+    private List<UploadNodeFilterPropertyInfo> createNodeFilterProperties(Object o) {
+        if (!(o instanceof List)) {
+            return null;
+        }
+        List<UploadNodeFilterPropertyInfo> retVal = new ArrayList<>();
+        List<Map<String, Object>> propertiesList = (List<Map<String, Object>>) o;
+        for (Map<String, Object> map : propertiesList) {
+            final Map.Entry<String, Object> entry = map.entrySet().iterator().next();
+            final Object value = entry.getValue();
+            if (value instanceof Map) {
+                List<String> valueList = new ArrayList<>();
+                valueList.add(valueToProperty(entry.getValue()));
+                retVal.add(new UploadNodeFilterPropertyInfo(entry.getKey(), valueList));
+            } else if (value instanceof List) {
+                List<String> propertiesVals =
+                        (List<String>) ((List) value).stream().map(this::valueToProperty).collect(Collectors.toList());
+                retVal.add(new UploadNodeFilterPropertyInfo(entry.getKey(), propertiesVals));
+            }
+        }
+        return retVal;
+    }
+
+    private String valueToProperty(Object o) {
+
+        if (o instanceof Map) {
+            return new YamlUtil().objectToYaml(o);
+        }
+        return null;
+    }
+
+    private Map<String, UploadNodeFilterCapabilitiesInfo> createNodeFilterCapabilities(Object o) {
+        if (!(o instanceof List)) {
+            return null;
+        }
+        Map<String, UploadNodeFilterCapabilitiesInfo> retVal = new HashMap<>();
+        List<Map<String, Object>> capabilitiesMap = (List<Map<String, Object>>) o;
+        for (Map<String, Object> map : capabilitiesMap) {
+            final Map.Entry<String, Object> entry = map.entrySet().iterator().next();
+            UploadNodeFilterCapabilitiesInfo uploadNodeFilterCapabilitiesInfo = new UploadNodeFilterCapabilitiesInfo();
+            uploadNodeFilterCapabilitiesInfo.setName(entry.getKey());
+            uploadNodeFilterCapabilitiesInfo.setProperties(createCapabilitiesProperties(entry.getValue()));
+            retVal.put(entry.getKey(), uploadNodeFilterCapabilitiesInfo);
+        }
+        return retVal;
+
+    }
+
+    private List<UploadNodeFilterPropertyInfo> createCapabilitiesProperties(Object o) {
+        if (!(o instanceof Map)) {
+            return null;
+        }
+        Map<String, Object> capabilitiesPropertiesMap = (Map<String, Object>) o;
+        final String capabilitiesPropertiesElementName = TypeUtils.ToscaTagNamesEnum.PROPERTIES.getElementName();
+        if (capabilitiesPropertiesMap.containsKey(capabilitiesPropertiesElementName)) {
+            final Object propertiesObject = capabilitiesPropertiesMap.get(capabilitiesPropertiesElementName);
+            return createNodeFilterProperties(propertiesObject);
+        }
+        return null;
+    }
+
+
+}
index 4e84292..d23fcfa 100644 (file)
@@ -34,6 +34,7 @@ import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOpera
 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationInfo;
 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
+import org.openecomp.sdc.be.components.impl.utils.CINodeFilterUtils;
 import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum;
@@ -3026,6 +3027,17 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
 
         ComponentInstance componentInstance = new ComponentInstance();
         componentInstance.setComponentUid(refResource.getUniqueId());
+
+        Collection<String> directives = uploadComponentInstanceInfo.getDirectives();
+        if(directives != null && !directives.isEmpty()) {
+            componentInstance.setDirectives(new ArrayList<>(directives));
+        }
+        UploadNodeFilterInfo uploadNodeFilterInfo = uploadComponentInstanceInfo.getUploadNodeFilterInfo();
+        if (uploadNodeFilterInfo != null){
+            componentInstance.setNodeFilter(new CINodeFilterUtils().getNodeFilterDataDefinition(uploadNodeFilterInfo,
+                    componentInstance.getUniqueId()));
+        }
+
         ComponentTypeEnum containerComponentType = resource.getComponentType();
         NodeTypeEnum containerNodeType = containerComponentType.getNodeType();
         if (containerNodeType.equals(NodeTypeEnum.Resource)
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/DirectivesUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/DirectivesUtils.java
new file mode 100644 (file)
index 0000000..b19f059
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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 com.google.common.collect.Sets;
+import java.util.List;
+import java.util.Optional;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+
+public class DirectivesUtils {
+
+    public static final String SUBSTITUTABLE = "substitutable";
+    public static final String SELECTABLE = "selectable";
+    public enum DIRECTIVE {
+
+        SUBSTITUTABLE(DirectivesUtils.SUBSTITUTABLE), SELECTABLE(DirectivesUtils.SELECTABLE);
+
+        private final String value;
+
+        DIRECTIVE(String value) {
+            this.value = value;
+        }
+
+        @Override
+        public String toString() {
+            return value;
+        }
+
+    }
+
+    public static Optional<DIRECTIVE> getDirective(String inDirective) {
+        if (StringUtils.isEmpty(inDirective)) {
+            return Optional.empty();
+        }
+
+        return Sets.newHashSet(DIRECTIVE.values()).stream()
+                   .filter(directive -> directive.toString().equals(inDirective)).findAny();
+    }
+
+    public static boolean isValid(List<String> inDirectives){
+        if (CollectionUtils.isEmpty(inDirectives)){
+            return true;
+        }
+        return inDirectives.stream().allMatch(directive -> getDirective(directive).isPresent());
+    }
+
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/MapUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/MapUtils.java
new file mode 100644 (file)
index 0000000..30b9057
--- /dev/null
@@ -0,0 +1,84 @@
+package org.openecomp.sdc.be.components.utils;
+
+import java.util.List;
+import java.util.Map;
+
+public class MapUtils {
+  public static boolean compareMaps(Map<String, Object> source, Map<String, Object> target) {
+    if (source == null && target == null) {
+      return true;
+    }
+    if ((source == null && target != null) || source != null && target == null
+        || source.keySet().size() != target.keySet().size()) {
+      return false;
+    }
+
+    for (Map.Entry<String, Object> entry : source.entrySet()) {
+      Object sourceObj = entry.getValue();
+      Object targetObj = target.get(entry.getKey());
+      if ((sourceObj == null && targetObj != null) || (sourceObj != null && targetObj == null)) {
+        return false;
+      }
+      if (!handleSourceAndTargetObjects(sourceObj, targetObj)) {
+        return false;
+      }
+    }
+    return true;
+
+  }
+
+  public static boolean compareLists(List<Object> source, List<Object> target) {
+    if (source == null && target == null) {
+      return true;
+    }
+    if ((source == null && target != null) || source != null && target == null ||
+        source.size() != target.size()) {
+      return false;
+    }
+    for (int i = 0; i < source.size(); i++) {
+      Object sourceObj = source.get(i);
+      Object targetObj = target.get(i);
+      if ((sourceObj == null && targetObj != null) || sourceObj != null && targetObj == null) {
+        return false;
+      }
+      if (!handleSourceAndTargetObjects(sourceObj, targetObj)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public static boolean handleSourceAndTargetObjects(Object sourceObj, Object targetObj) {
+
+    if (sourceObj == null && targetObj == null) {
+      return true;
+    }
+
+    if (sourceObj == null && targetObj != null) {
+      return false;
+    }
+    if (sourceObj.getClass().equals(targetObj.getClass())) {
+      if (sourceObj instanceof Map) {
+        if (!compareMaps((Map<String, Object>) sourceObj, (Map<String, Object>) targetObj)) {
+          return false;
+        }
+      } else if (sourceObj instanceof List) {
+        if (!compareLists((List<Object>) sourceObj, (List<Object>) targetObj)) {
+          return false;
+        }
+      } else  {
+
+        if(sourceObj.getClass() != targetObj.getClass()){
+          return false;
+        }
+
+        if (!sourceObj.equals(targetObj)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/ProxyServicePropertiesUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/ProxyServicePropertiesUtils.java
new file mode 100644 (file)
index 0000000..b9b7ab6
--- /dev/null
@@ -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.components.utils;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+
+public class ProxyServicePropertiesUtils {
+
+    private ProxyServicePropertiesUtils() {
+    }
+
+    public static List<PropertyDefinition> getProperties(Component service) {
+        List<PropertyDefinition> properties = service.getProperties();
+        if (properties == null) {
+            properties = new ArrayList<>();
+        }
+        Set<PropertyDefinition> serviceProperties = new HashSet<>(properties);
+        if (service.getInputs() != null) {
+            Set<PropertyDefinition> inputs = service.getInputs().stream().map(input -> new PropertyDefinition(input))
+                                                    .collect(Collectors.toSet());
+            serviceProperties.addAll(inputs);
+        }
+        serviceProperties =
+                serviceProperties.stream().filter(distinctByKey(PropertyDefinition::getName)).collect(Collectors.toSet());
+        return new ArrayList<>(serviceProperties);
+    }
+
+    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
+        Set<Object> seen = new HashSet<>();
+        return t -> seen.add(keyExtractor.apply(t));
+    }
+}
index 899a7b1..b76664f 100644 (file)
@@ -28,6 +28,7 @@ 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.tosca.utils.NodeFilterConverter;
 import org.openecomp.sdc.be.ui.model.*;
 import org.openecomp.sdc.common.log.wrappers.Logger;
 
@@ -101,6 +102,13 @@ public class UiComponentDataConverter {
             case COMPONENT_INSTANCE_INPUTS:
                 setComponentInstanceInputs(dataTransfer, component);
                 break;
+            case NODE_FILTER:
+                if(component.getNodeFilterComponents() == null) {
+                    dataTransfer.setNodeFilterData(null);
+                } else {
+                    NodeFilterConverter nodeFilterConverter = new NodeFilterConverter();
+                    dataTransfer.setNodeFilterData(nodeFilterConverter.convertDataMapToUI(component.getNodeFilterComponents()));
+                }
             default:
                 break;
         }
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ServiceFilterUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ServiceFilterUtils.java
new file mode 100644 (file)
index 0000000..7faf89c
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * 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.impl;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import org.javatuples.Pair;
+import org.openecomp.sdc.be.components.impl.utils.DirectivesUtils;
+import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor;
+import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
+import org.openecomp.sdc.be.model.ComponentInstance;
+import org.openecomp.sdc.be.model.InputDefinition;
+import org.openecomp.sdc.be.model.Service;
+import org.openecomp.sdc.be.ui.model.UIConstraint;
+
+public class ServiceFilterUtils {
+
+
+    private ServiceFilterUtils() {
+    }
+
+
+     public static boolean isNodeFilterAffectedByPropertyRemoval(Service service, String ciName, String propertyName) {
+        return service.getComponentInstances().stream().filter(ci -> ci.getNodeFilter() != null)
+                      .anyMatch(ci -> propertyIsUsedInCI(ci, ciName, propertyName));
+    }
+
+
+    private static boolean propertyIsUsedInCI(ComponentInstance ci, String ciName, String propertyName) {
+        final List<String> directives = ci.getDirectives();
+        if (!directives.contains(DirectivesUtils.SELECTABLE)) {
+            return false;
+        }
+        if (ci.getNodeFilter() == null || ci.getNodeFilter().getProperties() == null
+                    || ci.getNodeFilter().getProperties().getListToscaDataDefinition() == null) {
+            return false;
+        }
+        return ci.getNodeFilter().getProperties().getListToscaDataDefinition().stream()
+                 .flatMap(prop -> prop.getConstraints().stream()).map(String::new)
+                 .filter(constraint -> new ConstraintConvertor().convert(constraint).getSourceType()
+                                                                .equals(ConstraintConvertor.PROPERTY_CONSTRAINT))
+                 .anyMatch(constraintStr -> {
+                     UIConstraint uiConstraint = new ConstraintConvertor().convert(constraintStr);
+                     return uiConstraint.getSourceName().equals(ciName) && uiConstraint.getValue().equals(propertyName);
+                 });
+
+    }
+
+    public static Map<String, CINodeFilterDataDefinition> getRenamedNodesFilter(Service service, String oldName,
+            String newName) {
+        return service.getComponentInstances().stream().filter(ci -> isNodeFilterUsingChangedCi(ci, oldName))
+                      .map(ci -> renameOldCiNames(ci, oldName, newName))
+                      .collect(Collectors.toMap(Pair::getValue0, Pair::getValue1));
+    }
+
+    private static Pair<String, CINodeFilterDataDefinition> renameOldCiNames(ComponentInstance ci, String oldName,
+            String newName) {
+        ci.getNodeFilter().getProperties().getListToscaDataDefinition().stream()
+          .filter(property -> isPropertyConstraintChangedByCi(property, oldName))
+          .forEach(property -> renamePropertyCiNames(property, oldName, newName));
+
+        return new Pair<>(ci.getUniqueId(), ci.getNodeFilter());
+    }
+
+    private static void renamePropertyCiNames(RequirementNodeFilterPropertyDataDefinition property, String oldName,
+            String newName) {
+        final List<String> constraints = property.getConstraints().stream().map(getConstraintString(oldName, newName))
+                                                 .collect(Collectors.toList());
+        property.setConstraints(constraints);
+    }
+
+    private static Function<String, String> getConstraintString(String oldName, String newName) {
+        return constraint -> {
+            final ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+            UIConstraint uiConstraint = constraintConvertor.convert(constraint);
+            if (uiConstraint.getSourceName().equals(oldName)) {
+                uiConstraint.setSourceName(newName);
+            }
+            return constraintConvertor.convert(uiConstraint);
+        };
+    }
+
+
+    public static Set<String> getNodesFiltersToBeDeleted(Service service, String ciName) {
+        return service.getComponentInstances().stream().filter(ci -> isNodeFilterUsingChangedCi(ci, ciName))
+                      .map(ComponentInstance::getName).collect(Collectors.toSet());
+    }
+
+
+
+    public static Set<String> getNodesFiltersToBeDeleted(Service service, ComponentInstance inCi) {
+        return getNodesFiltersToBeDeleted(service, inCi.getName());
+    }
+
+
+
+    private static boolean isNodeFilterUsingChangedCi(ComponentInstance ci, String name) {
+        final List<String> directives = ci.getDirectives();
+        if (!directives.contains(DirectivesUtils.SELECTABLE)) {
+            return false;
+        }
+        if (ci.getNodeFilter() == null || ci.getNodeFilter().getProperties() == null
+                    || ci.getNodeFilter().getProperties().getListToscaDataDefinition() == null) {
+            return false;
+        }
+        return ci.getNodeFilter().getProperties().getListToscaDataDefinition().stream()
+                 .anyMatch(property -> isPropertyConstraintChangedByCi(property, name));
+    }
+
+    private static boolean isPropertyConstraintChangedByCi(
+            RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition, String name) {
+        List<String> constraints = requirementNodeFilterPropertyDataDefinition.getConstraints();
+        if (constraints == null) {
+            return false;
+        }
+        return constraints.stream().anyMatch(constraint -> isConstraintChangedByCi(constraint, name));
+    }
+
+    private static boolean isConstraintChangedByCi(String constraint, String name) {
+        UIConstraint uiConstraint = new ConstraintConvertor().convert(constraint);
+        if (uiConstraint == null || uiConstraint.getSourceType() == null) {
+            return false;
+        }
+        if (!uiConstraint.getSourceType().equals(ConstraintConvertor.PROPERTY_CONSTRAINT)) {
+            return false;
+        }
+        return uiConstraint.getSourceName().equals(name);
+    }
+
+    public static Set<String> getNodesFiltersToBeDeleted(Service service, InputDefinition changedInput) {
+        return service.getComponentInstances().stream().filter(ci -> isNodeFilterUsingChangedInput(ci, changedInput))
+                      .map(ComponentInstance::getName).collect(Collectors.toSet());
+    }
+
+    private static boolean isNodeFilterUsingChangedInput(ComponentInstance ci, InputDefinition changedInput) {
+        final List<String> directives = ci.getDirectives();
+        if (!directives.contains(DirectivesUtils.SELECTABLE)) {
+            return false;
+        }
+        return ci.getNodeFilter().getProperties().getListToscaDataDefinition().stream()
+                 .anyMatch(property -> isPropertyConstraintChangedByInput(property, changedInput));
+    }
+
+    private static boolean isPropertyConstraintChangedByInput(
+            RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition,
+            InputDefinition changedInput) {
+        List<String> constraints = requirementNodeFilterPropertyDataDefinition.getConstraints();
+        return constraints.stream().anyMatch(constraint -> isConstraintChangedByInput(constraint, changedInput));
+    }
+
+    private static boolean isConstraintChangedByInput(String constraint, InputDefinition changedInput) {
+        UIConstraint uiConstraint = new ConstraintConvertor().convert(constraint);
+        if (!uiConstraint.getSourceType().equals(ConstraintConvertor.SERVICE_INPUT_CONSTRAINT)) {
+            return false;
+        }
+        return uiConstraint.getValue().equals(changedInput.getName());
+    }
+
+}
index b5e2814..45d1c5f 100644 (file)
@@ -31,9 +31,12 @@ import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
 import org.openecomp.sdc.be.components.impl.GroupBusinessLogic;
+import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
+import org.openecomp.sdc.be.components.impl.utils.DirectivesUtils;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.datamodel.ForwardingPaths;
+import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
 import org.openecomp.sdc.be.info.CreateAndAssotiateInfo;
@@ -171,6 +174,34 @@ public class ComponentInstanceServlet extends AbstractValidationsServlet {
             if (actionResponse.isRight()) {
                 return buildErrorResponse(actionResponse.right().value());
             }
+            ComponentInstance resultValue = actionResponse.left().value();
+            if (componentTypeEnum.equals(ComponentTypeEnum.SERVICE)){
+                boolean shouldCreateServiceFilter = resourceInstance.getDirectives() != null && resourceInstance.getDirectives().contains(
+                        DirectivesUtils.SELECTABLE);
+                ServiceBusinessLogic
+                        serviceBusinessLogic = (ServiceBusinessLogic) getComponentBL(componentTypeEnum, context);
+
+                if(shouldCreateServiceFilter) {
+                    Either<CINodeFilterDataDefinition, ResponseFormat> either =
+                            serviceBusinessLogic.createIfNotAlreadyExistServiceFilter(componentId, componentInstanceId, userId,
+                                    true);
+                    if (either.isRight()){
+                        BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - updateResourceInstance Failed to create service filter.");
+                        log.debug("Failed to create service filter.");
+                        return buildErrorResponse(convertResponse.right().value());
+                    }
+                    resultValue.setNodeFilter(either.left().value());
+                } else {
+                    Either<String, ResponseFormat> either = serviceBusinessLogic.deleteIfNotAlreadyDeletedServiceFilter(componentId, componentInstanceId,  userId,true);
+                    if (either.isRight()){
+                        BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - updateResourceInstance Failed to delete service filter.");
+                        log.debug("Failed to delete service filter.");
+                        return buildErrorResponse(convertResponse.right().value());
+                    }
+                    resultValue.setNodeFilter(null);
+                }
+            }
+
             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value());
 
         } catch (Exception e) {
index 06cf2af..da0ec1c 100644 (file)
@@ -29,11 +29,12 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.ImmutableTriple;
 import org.apache.commons.lang3.tuple.Triple;
+import org.onap.sdc.tosca.services.YamlUtil;
 import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException;
 import org.openecomp.sdc.be.config.ConfigurationManager;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
-import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.*;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
@@ -116,6 +117,7 @@ public class ToscaExportHandler {
     private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}";
     private static final List<Map<String, Map<String, String>>> DEFAULT_IMPORTS = ConfigurationManager
                                                                                           .getConfigurationManager().getConfiguration().getDefaultImports();
+    private static YamlUtil yamlUtil = new YamlUtil();
 
     public ToscaExportHandler(){}
 
@@ -587,7 +589,6 @@ public class ToscaExportHandler {
     }
   }
 
-
     private Either<ToscaTemplate, ToscaError> convertReqCapAndTypeName(Map<String, Component> componentsCache, Component component, ToscaTemplate toscaNode,
             Map<String, ToscaNodeType> nodeTypes, ToscaNodeType toscaNodeType,
             Map<String, DataTypeDefinition> dataTypes) {
@@ -645,6 +646,8 @@ public class ToscaExportHandler {
         for (ComponentInstance componentInstance : componentInstances) {
             ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate();
             nodeTemplate.setType(componentInstance.getToscaComponentName());
+            nodeTemplate.setDirectives(componentInstance.getDirectives());
+            nodeTemplate.setNode_filter(convertToNodeTemplateNodeFilterComponent(componentInstance.getNodeFilter()));
 
             Either<Component, Boolean> originComponentRes = capabilityRequirementConverter
                                                                     .getOriginComponent(componentCache, componentInstance);
@@ -809,7 +812,6 @@ public class ToscaExportHandler {
 
         return interfaces;
     }
-    //M3[00001] - NODE TEMPLATE INTERFACES  - END
 
     private void addComponentInstanceInputs(Map<String, DataTypeDefinition> dataTypes,
             Map<String, List<ComponentInstanceInput>> componentInstancesInputs,
@@ -1164,6 +1166,102 @@ public class ToscaExportHandler {
         return Either.left(nodeType);
     }
 
+
+    protected NodeFilter convertToNodeTemplateNodeFilterComponent(CINodeFilterDataDefinition inNodeFilter) {
+        if (inNodeFilter == null){
+            return null;
+        }
+        NodeFilter nodeFilter = new NodeFilter();
+
+        ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities =
+                inNodeFilter.getCapabilities();
+
+        ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties = inNodeFilter.getProperties();
+
+        List<Map<String, CapabilityFilter>> capabilitiesCopy = new ArrayList<>();
+        List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
+
+        copyNodeFilterCapabilitiesTemplate(origCapabilities, capabilitiesCopy);
+        copyNodeFilterProperties(origProperties, propertiesCopy);
+
+        if(CollectionUtils.isNotEmpty(capabilitiesCopy)) {
+            nodeFilter.setCapabilities(capabilitiesCopy);
+        }
+
+        if(CollectionUtils.isNotEmpty(propertiesCopy)) {
+            nodeFilter.setProperties(propertiesCopy);
+        }
+
+        nodeFilter.setTosca_id(cloneToscaId(inNodeFilter.getTosca_id()));
+
+
+        nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class);
+
+        return nodeFilter;
+    }
+
+    private Object cloneToscaId(Object toscaId) {
+        return Objects.isNull(toscaId) ? null
+                       : cloneObjectFromYml(toscaId, toscaId.getClass());
+    }
+
+
+    private Object cloneObjectFromYml(Object objToClone, Class classOfObj) {
+        String objectAsYml = yamlUtil.objectToYaml(objToClone);
+        return yamlUtil.yamlToObject(objectAsYml, classOfObj);
+    }
+    private void copyNodeFilterCapabilitiesTemplate(
+            ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> origCapabilities,
+            List<Map<String, CapabilityFilter>> capabilitiesCopy) {
+        if(origCapabilities == null || origCapabilities.getListToscaDataDefinition() == null ||
+                   origCapabilities.getListToscaDataDefinition().isEmpty() ) {
+            return;
+        }
+        for(RequirementNodeFilterCapabilityDataDefinition capability : origCapabilities.getListToscaDataDefinition()) {
+            Map<String, CapabilityFilter> capabilityFilterCopyMap = new HashMap<>();
+            CapabilityFilter capabilityFilter = new CapabilityFilter();
+            List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>();
+            copyNodeFilterProperties(capability.getProperties(), propertiesCopy);
+            capabilityFilter.setProperties(propertiesCopy);
+            capabilityFilterCopyMap.put(capability.getName(), capabilityFilter);
+            capabilitiesCopy.add(capabilityFilterCopyMap);
+        }
+    }
+
+    private List<Object> copyNodeFilterProperty(List<Object> propertyList) {
+        String listAsString = yamlUtil.objectToYaml(propertyList);
+        return yamlUtil.yamlToObject(listAsString, List.class);
+    }
+
+
+    private void copyNodeFilterProperties(
+            ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> origProperties,
+            List<Map<String, List<Object>>> propertiesCopy) {
+        if(origProperties == null || origProperties.getListToscaDataDefinition() == null ||
+                   origProperties.isEmpty()) {
+            return;
+        }
+        for(RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : origProperties.getListToscaDataDefinition()) {
+            Map<String, List<Object>> propertyMapCopy = new HashMap<>();
+            for(String propertyInfoEntry : propertyDataDefinition.getConstraints()) {
+                Map propertyValObj =  new YamlUtil().yamlToObject(propertyInfoEntry, Map.class);
+                if (propertyMapCopy.containsKey(propertyDataDefinition.getName())){
+                    propertyMapCopy.get(propertyDataDefinition.getName()).add(propertyValObj);
+                } else {
+                    if (propertyDataDefinition.getName() != null) {
+                        List propsList =new ArrayList();
+                        propsList.add(propertyValObj);
+                        propertyMapCopy.put(propertyDataDefinition.getName(), propsList);
+                    } else {
+                        propertyMapCopy.putAll(propertyValObj);
+                    }
+                }
+            }
+            propertiesCopy.add(propertyMapCopy);
+        }
+
+    }
+
     private static class CustomRepresenter extends Representer {
         public CustomRepresenter() {
             super();
index b67a2cf..b17dc3a 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -25,14 +25,18 @@ import org.apache.commons.collections.MapUtils;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import org.apache.commons.collections.CollectionUtils;
 
 public class ToscaNodeTemplate {
+
     private String type;
+    private List<String> directives;
     private ToscaMetadata metadata;
     private String description;
     private Map<String, Object> properties;
     private List<Map<String, ToscaTemplateRequirement>> requirements;
     private Map<String, ToscaTemplateCapability> capabilities;
+    private NodeFilter node_filter;
     private Map<String, Object> interfaces;
 
     public String getType() {
@@ -75,13 +79,33 @@ public class ToscaNodeTemplate {
         this.metadata = metadata;
     }
 
-  public String getDescription() {
-    return description;
-  }
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public List<String> getDirectives() {
+        return directives;
+    }
+
+    public void setDirectives(List<String> directives) {
+        if (CollectionUtils.isEmpty(directives)) {
+            this.directives = null;
+            return;
+        }
+        this.directives = directives;
+    }
+
+    public NodeFilter getNode_filter() {
+        return node_filter;
+    }
 
-  public void setDescription(String description) {
-    this.description = description;
-  }
+    public void setNode_filter(NodeFilter node_filter) {
+        this.node_filter = node_filter;
+    }
 
     public void setInterfaces(
             Map<String, Object> interfaces) {
index af0837f..8470bd2 100644 (file)
@@ -123,6 +123,10 @@ public class NodeFilterConverter {
         }
     }
 
+    public Map<String, UINodeFilter> convertDataMapToUI(Map<String, CINodeFilterDataDefinition> inMap) {
+        return inMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, o -> convertToUi(o.getValue())));
+    }
+
     public UINodeFilter convertToUi(CINodeFilterDataDefinition inNodeFilter) {
         UINodeFilter retVal = new UINodeFilter();
         final ConstraintConvertor constraintConvertor = new ConstraintConvertor();
@@ -131,7 +135,7 @@ public class NodeFilterConverter {
         }
         List<UIConstraint> constraints = inNodeFilter.getProperties().getListToscaDataDefinition().stream()
                                                      .map(property -> property.getConstraints().iterator().next())
-                                                     .map(str -> constraintConvertor.convert(str))
+                                                     .map(constraintConvertor::convert)
                                                      .collect(Collectors.toList());
         retVal.setProperties(constraints);
         return retVal;
index c92b0fd..371f77d 100644 (file)
@@ -2235,6 +2235,21 @@ errors:
         message: "Error: Property type %1 provided against %2 is not supported for static value.",
         messageId: "SVC4721"
     }
+
+  #---------SVC4722------------------------------
+  # %1 Directive value set
+    DIRECTIVES_INVALID_VALUE: {
+      code: 404,
+      message: "Error: Invalid directive value : '%1' .",
+      messageId: "SVC4722"
+    }
+#---------SVC4723-----------------------------
+# %1 - Interface Operation output name
+    INTERFACE_OPERATION_MAPPED_OUTPUT_MODIFIED: {
+        code: 400,
+        message: "Error: Cannot update or delete interface operation output(s) '%1' mapped to an operation input",
+        messageId: "SVC4723"
+    }
 #---------SVC4723-----------------------------
 # %1 - Interface Operation output name
     INTERFACE_OPERATION_MAPPED_OUTPUT_MODIFIED: {
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/BaseServiceFilterUtilsTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/BaseServiceFilterUtilsTest.java
new file mode 100644 (file)
index 0000000..7cd7f3f
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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.nodeFilter;
+
+import java.util.Arrays;
+import org.junit.Assert;
+import org.junit.Before;
+import org.openecomp.sdc.be.components.impl.utils.DirectivesUtils;
+import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
+import org.openecomp.sdc.be.model.ComponentInstance;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.Service;
+
+public class BaseServiceFilterUtilsTest {
+
+    protected Service service;
+    protected RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition;
+    protected RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition2;
+    protected static final String CI_NAME = "AAAAAA";
+    protected static final String A_PROP_NAME = "A_PROP";
+    protected static final String SIZE_PROP = "size";
+    protected static final String ORIG_COMP_INSTANCE_ID = "54355645457457";
+
+    @Before
+    public void initService() {
+        try {
+            service = new Service();
+            ComponentInstance componentInstance = new ComponentInstance();
+            componentInstance.setUniqueId(CI_NAME);
+            componentInstance.setName(CI_NAME);
+            service.setComponentInstances(Arrays.asList(componentInstance));
+            componentInstance.setDirectives(Arrays.asList(DirectivesUtils.SELECTABLE));
+            CINodeFilterDataDefinition serviceFilter = new CINodeFilterDataDefinition();
+            componentInstance.setNodeFilter(serviceFilter);
+            requirementNodeFilterPropertyDataDefinition = new RequirementNodeFilterPropertyDataDefinition();
+            requirementNodeFilterPropertyDataDefinition.setName("Name1");
+            requirementNodeFilterPropertyDataDefinition
+                    .setConstraints(Arrays.asList("mem_size:\n" + "  equal: { get_property : [" + CI_NAME + ", size]}\n"));
+            requirementNodeFilterPropertyDataDefinition2 = new RequirementNodeFilterPropertyDataDefinition();
+            requirementNodeFilterPropertyDataDefinition2.setName("Name2");
+            requirementNodeFilterPropertyDataDefinition2
+                    .setConstraints(Arrays.asList("mem_size:\n {equal:  { get_property : [SELF, "+A_PROP_NAME+"]}}\n"));
+
+            ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> listDataDefinition =
+                    new ListDataDefinition<>(Arrays.asList(
+                            requirementNodeFilterPropertyDataDefinition,
+                            requirementNodeFilterPropertyDataDefinition2));
+            serviceFilter.setProperties(listDataDefinition);
+            PropertyDefinition property = new PropertyDefinition();
+            property.setName(A_PROP_NAME);
+            service.setProperties(Arrays.asList(property));
+        } catch (Exception e) {
+            Assert.fail(e.getMessage());
+        }
+    }
+
+}
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterRenameCiTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterRenameCiTest.java
new file mode 100644 (file)
index 0000000..a6a41c5
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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.nodeFilter;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import java.util.Map;
+import org.junit.Test;
+import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
+import org.openecomp.sdc.be.impl.ServiceFilterUtils;
+
+public class ServiceFilterRenameCiTest extends BaseServiceFilterUtilsTest {
+
+    protected static final String CI_NEW_NAME = "BBBBB";
+
+    @Test
+    public void renameCI() {
+        Map<String, CINodeFilterDataDefinition> renamedNodeFilters = getRenamedNodeFilters(CI_NAME, CI_NEW_NAME);
+        assertNotNull(renamedNodeFilters);
+        final List<String> constraints =
+                renamedNodeFilters.get(CI_NAME).getProperties().getListToscaDataDefinition().iterator().next()
+                                  .getConstraints();
+        assertEquals(1,constraints.size());
+        final String constraint = constraints.iterator().next();
+        assertTrue(constraint.contains(CI_NEW_NAME));
+    }
+
+    private Map<String, CINodeFilterDataDefinition> getRenamedNodeFilters(String oldName, String newName) {
+        return ServiceFilterUtils.getRenamedNodesFilter(service, oldName, newName);
+    }
+}
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsCIChangeTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsCIChangeTest.java
new file mode 100644 (file)
index 0000000..b6bf0ad
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright Â© 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.nodeFilter;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import fj.data.Either;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Set;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.openecomp.sdc.be.auditing.impl.AuditingManager;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.impl.ComponentsUtils;
+import org.openecomp.sdc.be.impl.ServiceFilterUtils;
+import org.openecomp.sdc.be.model.ComponentInstance;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
+import org.openecomp.sdc.be.ui.model.UIConstraint;
+import org.openecomp.sdc.exception.ResponseFormat;
+
+public class ServiceFilterUtilsCIChangeTest extends BaseServiceFilterUtilsTest {
+
+
+    @Test
+    public void checkComponentInstanceIsFound() {
+        Set<String> nodesFiltersToBeDeleted = getNodeFiltersToBeDeleted(CI_NAME);
+        assertNotNull(nodesFiltersToBeDeleted);
+        assertTrue(nodesFiltersToBeDeleted.contains(CI_NAME));
+    }
+
+    private Set<String> getNodeFiltersToBeDeleted(String inCiName) {
+        requirementNodeFilterPropertyDataDefinition
+                .setConstraints(Arrays.asList("mem_size:\n" + "  equal:\n" + "    get_property: ["+CI_NAME+", some static]\n"));
+        ComponentInstance ci = new ComponentInstance();
+        ci.setName(inCiName);
+        return ServiceFilterUtils.getNodesFiltersToBeDeleted(service, ci);
+    }
+
+    @Test
+    public void checkComponentInstanceIsNotFound() {
+        Set<String> nodesFiltersToBeDeleted = getNodeFiltersToBeDeleted(CI_NAME + " aaa bbb");
+        assertNotNull(nodesFiltersToBeDeleted);
+        assertTrue(nodesFiltersToBeDeleted.isEmpty());
+        assertFalse(nodesFiltersToBeDeleted.contains(CI_NAME));
+    }
+
+    @Test
+    public void testServiceConstraintPairSerialization() throws IOException {
+        UIConstraint uiConstraint =new UIConstraint();
+        ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+        mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
+        assertTrue(mapper.canSerialize(uiConstraint.getClass()));
+        String data;
+        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()  ) {
+            mapper.writeValue(outputStream, uiConstraint);
+            data = outputStream.toString();
+
+        }
+        assertNotNull(data);
+        final AuditingManager mock = Mockito.mock(AuditingManager.class);
+        final Either<UIConstraint, ResponseFormat> serviceConstraintPairResponseFormatEither =
+                new ComponentsUtils(mock)
+                        .convertJsonToObjectUsingObjectMapper(data, new User(), UIConstraint.class,
+                                AuditingActionEnum.ADD_GROUPING, ComponentTypeEnum.SERVICE);
+        assertTrue(serviceConstraintPairResponseFormatEither.isLeft());
+
+    }
+}
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsPropertyRemovedTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsPropertyRemovedTest.java
new file mode 100644 (file)
index 0000000..739ba3a
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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.nodeFilter;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.openecomp.sdc.be.impl.ServiceFilterUtils;
+
+public class ServiceFilterUtilsPropertyRemovedTest extends BaseServiceFilterUtilsTest {
+
+
+    @Test
+    public void checkPropertyIsFound() {
+        assertTrue(ServiceFilterUtils.isNodeFilterAffectedByPropertyRemoval(service, CI_NAME, SIZE_PROP));
+    }
+
+    @Test
+    public void checkPropertyIsNotFound() {
+        assertFalse(ServiceFilterUtils.isNodeFilterAffectedByPropertyRemoval(service, CI_NAME, A_PROP_NAME + "XXXX"));
+    }
+
+}
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsServiceInputTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/nodeFilter/ServiceFilterUtilsServiceInputTest.java
new file mode 100644 (file)
index 0000000..8f12fd1
--- /dev/null
@@ -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.nodeFilter;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Set;
+import org.junit.Test;
+import org.openecomp.sdc.be.impl.ServiceFilterUtils;
+import org.openecomp.sdc.be.model.InputDefinition;
+
+public class ServiceFilterUtilsServiceInputTest extends BaseServiceFilterUtilsTest {
+
+    private static final String CONSTRAINT_NAME = "InputName";
+
+
+    @Test
+    public void checkInputStreamIsFound() {
+        Set<String> nodesFiltersToBeDeleted = getNodeFiltersToBeDeleted(CONSTRAINT_NAME);
+        assertNotNull(nodesFiltersToBeDeleted);
+        assertTrue(nodesFiltersToBeDeleted.contains(CI_NAME));
+    }
+
+    private Set<String> getNodeFiltersToBeDeleted(String constraintName) {
+        requirementNodeFilterPropertyDataDefinition
+                .setConstraints(Arrays.asList("mem_size:\n  equal: {get_input: " + CONSTRAINT_NAME + "}\n"));
+        InputDefinition inputDefinition = new InputDefinition();
+        inputDefinition.setName(constraintName);
+        return ServiceFilterUtils.getNodesFiltersToBeDeleted(service, inputDefinition);
+    }
+
+    @Test
+    public void checkInputStreamIsNOtFound() {
+        Set<String> nodesFiltersToBeDeleted = getNodeFiltersToBeDeleted(CONSTRAINT_NAME + " aaa bbb");
+        assertNotNull(nodesFiltersToBeDeleted);
+        assertTrue(nodesFiltersToBeDeleted.isEmpty());
+        assertFalse(nodesFiltersToBeDeleted.contains(CI_NAME));
+    }
+}
index 6acdb32..06540e6 100644 (file)
@@ -37,6 +37,8 @@ public enum ActionStatus {
     COMPONENT_INVALID_DESCRIPTION, COMPONENT_MISSING_DESCRIPTION, COMPONENT_DESCRIPTION_EXCEEDS_LIMIT,
     // Component icon related
     COMPONENT_MISSING_ICON, COMPONENT_INVALID_ICON, COMPONENT_ICON_EXCEEDS_LIMIT,
+    // Directives related
+    DIRECTIVES_INVALID_VALUE,
     // Tag related
     COMPONENT_MISSING_TAGS, COMPONENT_TAGS_EXCEED_LIMIT, COMPONENT_SINGLE_TAG_EXCEED_LIMIT, INVALID_FIELD_FORMAT, COMPONENT_INVALID_TAGS_NO_COMP_NAME,
     // contactId related
index 24386bc..e33ded2 100644 (file)
 
 package org.openecomp.sdc.be.model;
 
+import static java.util.Collections.emptyList;
+import static java.util.Collections.emptyMap;
+import static java.util.stream.Collectors.toMap;
+import static org.apache.commons.collections.CollectionUtils.isEmpty;
+import static org.apache.commons.collections.MapUtils.isEmpty;
+
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.google.common.collect.Maps;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
 import org.apache.commons.collections.MapUtils;
 import org.openecomp.sdc.be.config.ConfigurationManager;
 import org.openecomp.sdc.be.dao.utils.MapUtil;
@@ -71,6 +85,7 @@ public abstract class Component implements PropertiesOwner {
        protected List<AdditionalInformationDefinition> additionalInformation;
        protected List<PropertyDefinition> properties;
        private Map<String, InterfaceDefinition> interfaces;
+    private Map<String, CINodeFilterDataDefinition> nodeFilterComponents;
 
        public Map<String, InterfaceDefinition> getInterfaces() {
                return interfaces;
@@ -589,6 +604,14 @@ public abstract class Component implements PropertiesOwner {
                return result;
        }
 
+    public Map<String, CINodeFilterDataDefinition> getNodeFilterComponents() {
+        return nodeFilterComponents;
+    }
+
+    public void setNodeFilterComponents(Map<String, CINodeFilterDataDefinition> nodeFilterComponents) {
+        this.nodeFilterComponents = nodeFilterComponents;
+    }
+
     @Override
     public boolean equals(Object obj) {
         if (this == obj) {
@@ -725,6 +748,9 @@ public abstract class Component implements PropertiesOwner {
         else if (!properties.equals(other.properties)) {
             return false;
         }
+        else if (!nodeFilterComponents.equals(other.nodeFilterComponents)) {
+            return false;
+        }
         return true;
     }
 
index 0cff11e..087816c 100644 (file)
@@ -48,6 +48,7 @@ public class ComponentParametersView {
     private boolean ignoreCapabiltyProperties = true;
     private boolean ignoreServicePath = true;
     private boolean ignorePolicies = false;
+    private boolean ignoreNodeFilter = false;
 
     public ComponentParametersView() {
     }
@@ -90,6 +91,7 @@ public class ComponentParametersView {
                     this.setIgnoreComponentInstances(false);
                     this.setIgnoreCapabilities(false);
                     this.setIgnoreRequirements(false);
+                    this.setIgnoreNodeFilter(false);
                     break;
                 case COMPONENT_INSTANCES_PROPERTIES:
                     this.setIgnoreComponentInstances(false); //we need this in order to get the calculate capabilities requirements
@@ -142,6 +144,9 @@ public class ComponentParametersView {
                 case NON_EXCLUDED_POLICIES:
                     this.setIgnorePolicies(false);
                     break;
+                case NODE_FILTER:
+                    this.setIgnoreNodeFilter(false);
+                    break;
                 default:
                     break;
             }
@@ -216,6 +221,9 @@ public class ComponentParametersView {
         if (ignoreServicePath && componentType == ComponentTypeEnum.SERVICE) {
             ((Service) component).setForwardingPaths(null);
         }
+        if (ignoreNodeFilter){
+            component.setNodeFilterComponents(null);
+        }
         return component;
     }
 
@@ -240,6 +248,7 @@ public class ComponentParametersView {
         ignoreComponentInstancesInputs = true;
         ignoreCapabiltyProperties = true;
         ignoreServicePath = true;
+        ignoreNodeFilter = true;
     }
 
     public boolean isIgnoreGroups() {
@@ -406,6 +415,14 @@ public class ComponentParametersView {
         this.ignorePolicies = ignorePolicies;
     }
 
+    public boolean isIgnoreNodeFilter() {
+        return ignoreNodeFilter;
+    }
+
+    public void setIgnoreNodeFilter(boolean ignoreNodeFilter) {
+        this.ignoreNodeFilter = ignoreNodeFilter;
+    }
+
     public JsonParseFlagEnum detectParseFlag() {
         JsonParseFlagEnum parseFlag;
         if (isIgnoreComponentInstances()) {
index 3454fd7..7b672ac 100644 (file)
@@ -20,6 +20,7 @@
 
 package org.openecomp.sdc.be.model;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -31,6 +32,8 @@ public class UploadComponentInstanceInfo {
     private Map<String, List<UploadPropInfo>> properties;
     private Map<String, String> capabilitiesNamesToUpdate;
     private Map<String, String> requirementsNamesToUpdate;
+    private Collection<String> directives;
+    private UploadNodeFilterInfo uploadNodeFilterInfo;
 
     public Map<String, List<UploadPropInfo>> getProperties() {
         return properties;
@@ -88,4 +91,19 @@ public class UploadComponentInstanceInfo {
         this.requirementsNamesToUpdate = requirementsNamesToUpdate;
     }
 
+    public Collection<String> getDirectives() {
+        return directives;
+    }
+
+    public void setDirectives(Collection<String> directives) {
+        this.directives = directives;
+    }
+
+    public UploadNodeFilterInfo getUploadNodeFilterInfo() {
+        return uploadNodeFilterInfo;
+    }
+
+    public void setUploadNodeFilterInfo(UploadNodeFilterInfo uploadNodeFilterInfo) {
+        this.uploadNodeFilterInfo = uploadNodeFilterInfo;
+    }
 }
index ac9f196..04cc6ea 100644 (file)
@@ -58,7 +58,8 @@ public class TopologyTemplate extends ToscaElement{
     private Map<String, InterfaceDataDefinition> interfaces;
     private Map<String, MapInterfaceInstanceDataDefinition> instInterfaces;
     private Map<String, MapInterfaceDataDefinition> componentInstInterfaces;
-    
+
+    private Map<String, CINodeFilterDataDefinition> nodeFilterComponents;
     //Component Instances External References (instanceId -> ExternalRefsMap)
     //-----------------------------------------------------------------------
     private Map<String, MapComponentInstanceExternalRefs> mapComponentInstancesExternalRefs;
@@ -231,7 +232,15 @@ public class TopologyTemplate extends ToscaElement{
         this.forwardingPaths = forwardingPaths;
     }
 
-    /**
+    public Map<String, CINodeFilterDataDefinition> getNodeFilterComponents() {
+        return nodeFilterComponents;
+    }
+
+    public void setNodeFilterComponents(Map<String, CINodeFilterDataDefinition> nodeFilters) {
+        this.nodeFilterComponents = nodeFilters;
+    }
+
+      /**
      * Adds component instance to composition of topology template
      * Note that component instance will be overrided in case if the topology template already contains a component instance with the same name
      * @param componentInstance
index f6c4207..95f518a 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -136,6 +136,14 @@ public class NodeTemplateOperation extends BaseOperation {
             if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
                 TopologyTemplate updatedContainer = addComponentInstanceRes.left().value();
                 result = addServerCapAndReqToProxyServerInstance(updatedContainer, componentInstance, componentInstanceData);
+                if(result.isRight()) {
+                    return result;
+                }
+
+                result = addServiceInstancePropertiesToProxyServiceInstance(updatedContainer, componentInstance);
+                if(result.isRight()) {
+                  return result;
+                }
 
             }
         }
@@ -272,6 +280,34 @@ public class NodeTemplateOperation extends BaseOperation {
         return result;
     }
 
+    private Either<ImmutablePair<TopologyTemplate, String>, StorageOperationStatus> addServiceInstancePropertiesToProxyServiceInstance(TopologyTemplate updatedContainer, ComponentInstance componentInstance) {
+
+        List<PropertyDefinition> propertiesList = componentInstance.getProperties();
+
+        if (propertiesList != null && !propertiesList.isEmpty()) {
+            Map<String, PropertyDataDefinition> propertiesMap = propertiesList.stream().map(i -> new PropertyDataDefinition(i))
+                                                                              .collect(Collectors.toMap(i -> i.getName(), i -> i));
+            MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(propertiesMap);
+            Map<String, MapPropertiesDataDefinition> instPropertiesMap = new HashMap<>();
+            instPropertiesMap.put(componentInstance.getUniqueId(), instProperties);
+            updatedContainer.setInstProperties(instPropertiesMap);
+            Either<GraphVertex, TitanOperationStatus> getToscaElementRes = titanDao.getVertexById(updatedContainer.getUniqueId(), JsonParseFlagEnum.NoParse);
+           if(getToscaElementRes.isLeft()){
+               deleteToscaDataDeepElementsBlockToToscaElement(getToscaElementRes.left().value(),  EdgeLabelEnum.INST_PROPERTIES,
+                       VertexTypeEnum.INST_PROPERTIES,  componentInstance.getUniqueId());
+           }
+            StorageOperationStatus status = addToscaDataDeepElementsBlockToToscaElement(updatedContainer.getUniqueId(),
+                    EdgeLabelEnum.INST_PROPERTIES, VertexTypeEnum.INST_PROPERTIES, instProperties,
+                    componentInstance.getUniqueId());
+            if (status != StorageOperationStatus.OK) {
+                return Either.right(status);
+            }
+
+
+        }
+        return Either.left(new ImmutablePair<>(updatedContainer, componentInstance.getUniqueId()));
+    }
+
     public Either<TopologyTemplate, StorageOperationStatus> addComponentInstanceToTopologyTemplate(TopologyTemplate container, ToscaElement originToscaElement, ComponentInstanceDataDefinition componentInstance, GraphVertex metadataVertex,
             boolean allowDeleted, User user) {
 
@@ -620,7 +656,7 @@ public class NodeTemplateOperation extends BaseOperation {
 
         return status;
     }
-    
+
     private MapPropertiesDataDefinition turnInputsIntoProperties(MapPropertiesDataDefinition instInput){
         if (instInput.getMapToscaDataDefinition() != null) {
             for (PropertyDataDefinition currProp : instInput.getMapToscaDataDefinition().values()){
@@ -873,7 +909,7 @@ public class NodeTemplateOperation extends BaseOperation {
 
     /**
      * Prepares a map of capabilities lists Produces a deep copy of the received map of capabilities Sets values to the specific fields according to received component instance
-     * 
+     *
      * @param capabilities
      * @param componentInstance
      * @return
@@ -900,7 +936,7 @@ public class NodeTemplateOperation extends BaseOperation {
 
     /**
      * Prepares a map of requirements lists Produces a deep copy of the received map of requirements Sets values to the specific fields according to received component instance
-     * 
+     *
      * @param requirements
      * @param componentInstance
      * @return
@@ -1284,7 +1320,7 @@ public class NodeTemplateOperation extends BaseOperation {
 
     /**
      * Retrieves fulfilled requirement according to relation and received predicate
-     * 
+     *
      * @param componentId
      * @param instanceId
      * @param foundRelation
@@ -1332,7 +1368,7 @@ public class NodeTemplateOperation extends BaseOperation {
 
     /**
      * Retrieves fulfilled capability according to relation and received predicate
-     * 
+     *
      * @param componentId
      * @param instanceId
      * @param foundRelation
@@ -2018,12 +2054,12 @@ public class NodeTemplateOperation extends BaseOperation {
             log.debug("Failed to fetch component metadata vertex for id {} error {}", componentId, vertexById.right().value());
             return DaoStatusConverter.convertTitanStatusToStorageStatus(vertexById.right().value());
         }
-        GraphVertex metadataVertex = vertexById.left().value(); 
+        GraphVertex metadataVertex = vertexById.left().value();
 
         EnumMap<GraphPropertyEnum, Object> props = new EnumMap<>(GraphPropertyEnum.class);
         props.put(GraphPropertyEnum.UUID, serviceUUID);
         props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
-  
+
         EnumMap<GraphPropertyEnum, Object> hasNot = new EnumMap<>(GraphPropertyEnum.class);
         hasNot.put(GraphPropertyEnum.IS_DELETED, true);
 
@@ -2037,7 +2073,7 @@ public class NodeTemplateOperation extends BaseOperation {
         if ( vertecies != null ){
             GraphVertex serviceVertex = vertecies.get(0);
             //remove previous edges
-            
+
             log.debug("Try to create or update edge between resource {} and service {} ", metadataVertex, serviceVertex.getUniqueId());
             // create edge between container and service reference
             result = createOrUpdateInstanceEdge(metadataVertex, EdgeLabelEnum.ALLOTTED_OF, serviceVertex.getUniqueId(), instanceId).either(v -> StorageOperationStatus.OK,
@@ -2045,8 +2081,8 @@ public class NodeTemplateOperation extends BaseOperation {
         }
         return result;
     }
-    
-    
+
+
     public StorageOperationStatus removeInstanceEdge(GraphVertex metadataVertex, ComponentInstanceDataDefinition componentInstance) {
         String instUniqueId = componentInstance.getUniqueId();
 
@@ -2095,7 +2131,7 @@ public class NodeTemplateOperation extends BaseOperation {
         try {
             String jsonArr = JsonParserUtils.toJson(property);
             log.debug("Update INSTANCES edge property with value {} ", jsonArr );
-            
+
             edge.property(EdgePropertyEnum.INSTANCES.getProperty(), jsonArr);
         } catch (IOException e) {
            log.debug("Failed to convert INSTANCES edge property to json for container {}", metadataVertex.getUniqueId(), e );
index 3bdec2a..26fe1e2 100644 (file)
@@ -212,6 +212,13 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
         return associateForwardingPathToComponent(topologyTemplateVertex,forwardingPaths);
     }
 
+    private StorageOperationStatus associateNodeFilterToResource(GraphVertex topologyTemplateVertex,
+            TopologyTemplate topologyTemplate) {
+        Map<String, CINodeFilterDataDefinition> nodeFilters =
+                topologyTemplate.getNodeFilterComponents();
+        return associateNodeFiltersToComponent(topologyTemplateVertex, nodeFilters);
+    }
+
     private StorageOperationStatus associateCapPropertiesToResource(GraphVertex topologyTemplateVertex, TopologyTemplate topologyTemplate) {
         Map<String, MapCapabilityProperty> calculatedCapProperties = topologyTemplate.getCalculatedCapabilitiesProperties();
         if (calculatedCapProperties != null && !calculatedCapProperties.isEmpty()) {
@@ -697,7 +704,15 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
 
             }
         }
-        
+
+        if (!componentParametersView.isIgnoreNodeFilter()) {
+            status = setNodeFilterComponentFromGraph(componentV, toscaElement);
+            if (status != TitanOperationStatus.OK) {
+                return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+
+            }
+        }
+
         if (!componentParametersView.isIgnoreInterfaces()) {
             TitanOperationStatus storageStatus = setInterfcesFromGraph(componentV, toscaElement);
             if (storageStatus != TitanOperationStatus.OK) {
@@ -744,6 +759,19 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
         return TitanOperationStatus.OK;
     }
 
+    public StorageOperationStatus associateNodeFiltersToComponent(GraphVertex nodeTypeVertex,
+            Map<String, CINodeFilterDataDefinition> filterMaps) {
+        if (filterMaps != null && !filterMaps.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData
+                                                                                         (nodeTypeVertex, VertexTypeEnum.NODE_FILTER_TEMPLATE,
+                                                                                                 EdgeLabelEnum.NODE_FILTER_TEMPLATE, filterMaps);
+            if (assosiateElementToData.isRight()) {
+                return assosiateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
+
     private TitanOperationStatus setForwardingGraphPropertiesFromGraph(GraphVertex componentV, TopologyTemplate topologyTemplate) {
         Either<Map<String, ForwardingPathDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.FORWARDING_PATH);
         if (result.isLeft()) {
@@ -817,6 +845,21 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
         return TitanOperationStatus.OK;
     }
 
+    private TitanOperationStatus setNodeFilterComponentFromGraph(GraphVertex componentV,
+            TopologyTemplate topologyTemplate) {
+        Either<Map<String, CINodeFilterDataDefinition>, TitanOperationStatus> result =
+                getDataFromGraph(componentV,
+                        EdgeLabelEnum.NODE_FILTER_TEMPLATE);
+        if (result.isLeft()) {
+            topologyTemplate.setNodeFilterComponents(result.left().value());
+        } else {
+            if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return result.right().value();
+            }
+        }
+        return TitanOperationStatus.OK;
+    }
+
     @Override
     protected <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement) {
         Either<Map<String, MapListRequirementDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CALCULATED_REQUIREMENTS);
index 6a49509..5e40bd5 100644 (file)
@@ -131,6 +131,10 @@ public class ModelConverter {
 
                convertPolicies(topologyTemplate, service);
 
+               convertProperties(topologyTemplate, service);
+
+               convertPolicies(topologyTemplate, service);
+
         convertGroups(topologyTemplate, service);
 
                setCapabilitiesToComponentAndGroups(topologyTemplate, service);
@@ -147,6 +151,7 @@ public class ModelConverter {
 
         convertServiceInterfaces(topologyTemplate, service);
 
+        convertNodeFiltersComponents(topologyTemplate, service);
         return service;
     }
 
@@ -193,6 +198,8 @@ public class ModelConverter {
             convertGroups(topologyTemplate, resource);
                        setCapabilitiesToComponentAndGroups(topologyTemplate, resource);
             convertPolicies(topologyTemplate, resource);
+            convertNodeFiltersComponents(topologyTemplate, resource);
+            convertProperties(topologyTemplate, resource);
         }
         convertArtifacts(toscaElement, resource);
         convertAdditionalInformation(toscaElement, resource);
@@ -678,6 +685,17 @@ public class ModelConverter {
         component.setDeploymentArtifacts(copy);
     }
 
+    private static void convertNodeFiltersComponents(TopologyTemplate topologyTemplate, Component component) {
+        Map<String, CINodeFilterDataDefinition> filters = topologyTemplate.getNodeFilterComponents();
+        Map<String, CINodeFilterDataDefinition> copy;
+        if (filters != null) {
+            copy = filters.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new CINodeFilterDataDefinition(e.getValue())));
+        } else {
+            copy = new HashMap<>();
+        }
+        component.setNodeFilterComponents(copy);
+    }
+
     private static void convertServiceApiArtifacts(TopologyTemplate topologyTemplate, Service service) {
         Map<String, ArtifactDataDefinition> serviceApiArtifacts = topologyTemplate.getServiceApiArtifacts();
         Map<String, ArtifactDefinition> copy;
@@ -1100,6 +1118,8 @@ public class ModelConverter {
 
         List<ComponentInstance> componentInstances = new ArrayList<>();
         ComponentInstance currComponentInstance;
+        Map<String, CINodeFilterDataDefinition> nodeFilterComponents = topologyTemplate.getNodeFilterComponents();
+
         for (Map.Entry<String, ComponentInstanceDataDefinition> entry : topologyTemplate.getComponentInstances().entrySet()) {
             String key = entry.getKey();
             currComponentInstance = new ComponentInstance(topologyTemplate.getComponentInstances().get(key));
@@ -1116,6 +1136,7 @@ public class ModelConverter {
                 currComponentInstance.setInterfaces(interfacesMap);
             }
             componentInstances.add(currComponentInstance);
+
         }
         component.setComponentInstances(componentInstances);
     }
index 43df6da..a8a2409 100644 (file)
@@ -21,6 +21,7 @@
 package org.openecomp.sdc.be.ui.model;
 
 
+import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.model.AdditionalInformationDefinition;
 import org.openecomp.sdc.be.model.ArtifactDefinition;
@@ -80,6 +81,10 @@ public class UiComponentDataTransfer {
 
     private Map<String, InterfaceDefinition> interfaces;
 
+    private Map<String, CINodeFilterDataDefinition> nodeFilter;
+
+    private Map<String, UINodeFilter> nodeFilterforNode;
+
     public Map<String, InterfaceDefinition> getInterfaces() {
         return interfaces;
     }
@@ -289,4 +294,19 @@ public class UiComponentDataTransfer {
         this.policies = policies;
     }
 
+    public Map<String, CINodeFilterDataDefinition> getNodeFilter() {
+        return nodeFilter;
+    }
+
+    public void setNodeFilter(Map<String, CINodeFilterDataDefinition> nodeFilter) {
+        this.nodeFilter = nodeFilter;
+    }
+
+    public Map<String, UINodeFilter> getNodeFilterData() {
+        return nodeFilterforNode;
+    }
+
+    public void setNodeFilterData(Map<String, UINodeFilter> nodeFilterforNode) {
+        this.nodeFilterforNode = nodeFilterforNode;
+    }
 }
index 4a4a7a4..5354d31 100644 (file)
 
 package org.openecomp.sdc.be.datatypes.elements;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.commons.collections.CollectionUtils;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
@@ -57,6 +61,7 @@ public class ComponentInstanceDataDefinition extends ToscaDataDefinition {
                setSourceModelUuid(dataDefinition.getSourceModelUuid());
                setSourceModelUid(dataDefinition.getSourceModelUid());
                setIsProxy(dataDefinition.getIsProxy());
+               setDirectives(dataDefinition.getDirectives());
                setOriginArchived(dataDefinition.isOriginArchived());
        }
 
@@ -273,11 +278,29 @@ public class ComponentInstanceDataDefinition extends ToscaDataDefinition {
                }
        }
 
+       public List<String> getDirectives() {
+               return ( List<String>) getToscaPresentationValue(JsonPresentationFields.CI_DIRECTIVES);
+       }
+
+       public void setDirectives(List<String> directives) {
+               if (directives == null){
+                       directives = new ArrayList<>();
+               }
+               setToscaPresentationValue(JsonPresentationFields.CI_DIRECTIVES, directives);
+       }
+
        public Boolean isOriginArchived() {
                Boolean originArchived = (Boolean) getToscaPresentationValue(JsonPresentationFields.CI_IS_ORIGIN_ARCHIVED);
                return ( originArchived != null ) ? originArchived : false;
        }
 
+       private String getDirectivesString(){
+               if (CollectionUtils.isEmpty(getDirectives())){
+                       return "";
+               }
+               return getDirectives().stream().collect(Collectors.joining(","));
+       }
+
        @Override
        public String toString() {
                return "ComponentInstanceDataDefinition [icon=" + getIcon() + ", uniqueId=" + getUniqueId() + ", name="
@@ -288,7 +311,7 @@ public class ComponentInstanceDataDefinition extends ToscaDataDefinition {
                                + getAttributeValueCounter() + ", inputValueCounter=" + getInputValueCounter() + ", originType="
                                + getOriginType() + ", customizationUUID=" + getCustomizationUUID() + ", componentName="
                                + getComponentName() + ", componentVersion=" + getComponentVersion() + ", toscaComponentName="
-                               + getToscaComponentName() + "]";
+                               + getToscaComponentName() + ", directives =" + getDirectivesString()  +"]";
        }
 
 }
index 4d39ec1..7a4c3d4 100644 (file)
@@ -190,7 +190,7 @@ public enum JsonPresentationFields {
     CI_SOURCE_MODEL_INVARIANT("sourceModelInvariant", null),
     CI_SOURCE_MODEL_NAME("sourceModelName", null),
     CI_IS_PROXY("isProxy", null),
-
+    CI_DIRECTIVES("directives", null),
 
     //path
     FORWARDING_PATH("forwardingPath", null),
index d4524d9..7d21afb 100644 (file)
@@ -27,11 +27,12 @@ public class TypeUtils {
         CAPABILITIES("capabilities"), VALID_SOURCE_TYPES("valid_source_types"),
         // Requirements
         REQUIREMENTS("requirements"), NODE("node"), RELATIONSHIP("relationship"), CAPABILITY("capability"), INTERFACES("interfaces"),
+        NODE_FILTER("node_filter"), TOSCA_ID("tosca_id"),
         // Heat env Validation
         PARAMETERS("parameters"),
         // Import Validations
         TOSCA_VERSION("tosca_definitions_version"), TOPOLOGY_TEMPLATE("topology_template"), NODE_TYPES("node_types"), OCCURRENCES("occurrences"), NODE_TEMPLATES("node_templates"), GROUPS("groups"), INPUTS("inputs"),
-        SUBSTITUTION_MAPPINGS("substitution_mappings"),  NODE_TYPE("node_type"),
+        SUBSTITUTION_MAPPINGS("substitution_mappings"),  NODE_TYPE("node_type"), DIRECTIVES("directives"),
         // Attributes
         ATTRIBUTES("attributes"), LABEL("label"), HIDDEN("hidden"), IMMUTABLE("immutable"), GET_INPUT("get_input"), ANNOTATIONS("annotations");
 
diff --git a/pom.xml b/pom.xml
index 637fb07..74c7e1f 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -473,7 +473,6 @@ Modifications copyright (c) 2018 Nokia
             </modules>
 
             <properties>
-                <ecomp.version>1.2.7</ecomp.version>
                 <sdc-tosca-parser.version>1.1.32</sdc-tosca-parser.version>
             </properties>
         </profile>
index d3b717e..ba35ac3 100644 (file)
@@ -180,6 +180,7 @@ public interface Urls {
        final String CHANGE_COMPONENT_LIFECYCLE_STATE = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/%s/%s/lifecycleState/%s";
 
        final String CREATE_PROPERTY = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/resources/%s/properties";
+    String CREATE_SERVICE_PROPERTY = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/services/%s/properties";
        final String DECLARE_PROPERTIES  = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/%s/%s/create/inputs";
        final String UPDATE_INPUT  = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/resources/%s/update/inputs";
 
@@ -392,6 +393,12 @@ public interface Urls {
        final String GET_VSP_COMPONENT_BY_VERSION = SDC_HTTP_METHOD + "://%s:%s/onboarding-api/v1.0/vendor-software-products/%s/versions/%s";
        final String GET_VLM_COMPONENT_BY_VERSION = SDC_HTTP_METHOD + "://%s:%s/onboarding-api/v1.0/vendor-license-models/%s/versions/%s";
        final String ACTION_ARCHIVE_RESTORE_COMPONENT = SDC_HTTP_METHOD + "://%s:%s/onboarding-api/v1.0/%s/%s/actions";
+       String CREATE_SERVICE_FILTER = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/services/%s/resourceInstances/%s/nodeFilter";
+    String UPDATE_SERVICE_FILTER = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/services/%s"
+            + "/resourceInstances/%s/nodeFilter/";
+       String DELETE_SERVICE_FILTER = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/services/%s"
+                                                                                                 + "/resourceInstances/%s/nodeFilter/%s";
+       String MARK_AS_DEPENDENT = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/%s/%s/resourceInstance/%s";
 
        // Interface Lifecycle Types
        final String GET_All_INTERFACE_LIFECYCLE_TYPES = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/interfaceLifecycleTypes";
index d6699d3..b276850 100644 (file)
@@ -20,6 +20,8 @@
 
 package org.openecomp.sdc.ci.tests.datatypes;
 
+import java.util.List;
+
 import org.openecomp.sdc.be.model.ComponentInstance;
 
 public class ComponentInstanceReqDetails {
@@ -31,6 +33,7 @@ public class ComponentInstanceReqDetails {
        String name;
        String uniqueId;
        String originType;
+    List<String> directives;
 
        public ComponentInstanceReqDetails() {
                super();
@@ -122,10 +125,25 @@ public class ComponentInstanceReqDetails {
                this.originType = originType;
        }
 
-       @Override
-       public String toString() {
-               return "ResourceInstanceReqDetails [resourceUid=" + componentUid + ", description=" + description + ", posX="
-                               + posX + ", posY=" + posY + ", name=" + name + ", uniqueId=" + uniqueId + "]";
-       }
-
+    public List<String> getDirectives() {
+        return directives;
+    }
+
+    public void setDirectives(List<String> directives) {
+        this.directives = directives;
+    }
+
+    @Override
+    public String toString() {
+        return "ComponentInstanceReqDetails{" +
+                "componentUid='" + componentUid + '\'' +
+                ", description='" + description + '\'' +
+                ", posX='" + posX + '\'' +
+                ", posY='" + posY + '\'' +
+                ", name='" + name + '\'' +
+                ", uniqueId='" + uniqueId + '\'' +
+                ", originType='" + originType + '\'' +
+                ", directives=" + directives +
+                '}';
+    }
 }
index 208e4aa..0898206 100644 (file)
@@ -135,7 +135,8 @@ public class PropertyReqDetails {
 
        public String propertyToJsonString() {
                String jsonString;
-               jsonString = "{\"" + this.getName() + "\":{" + "\"type\":\"" + this.getPropertyType() + "\"," + "\"required\":"
+               jsonString =
+                "{\"" + this.getName() + "\":{" + "\"name\":\"" + this.getName() + "\"," + "\"type\":\"" + this.getPropertyType() + "\"," + "\"required\":"
                                + this.getPropertyRequired() + "," + "\"defaultValue\":\"" + this.getPropertyDefaultValue() + "\","
                                + "\"description\":\"" + this.getPropertyDescription() + "\"," + "\"constraints\":[{\"inRange\":[\""
                                + this.getPropertyRangeMin() + "\",\"" + this.getPropertyRangeMax() + "\"]}]," + "\"isPassword\":"
diff --git a/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceFilterDetails.java b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceFilterDetails.java
new file mode 100644 (file)
index 0000000..1d6740a
--- /dev/null
@@ -0,0 +1,60 @@
+package org.openecomp.sdc.ci.tests.datatypes;
+
+public class ServiceFilterDetails {
+    private String servicePropertyName;
+    private String constraintOperator;
+    private String sourceType;
+    private String sourceName;
+    private Object value;
+
+    public ServiceFilterDetails() {}
+
+    public ServiceFilterDetails(String servicePropertyName, String constraintOperator, String sourceType, String sourceName,
+                        Object value) {
+        this.servicePropertyName = servicePropertyName;
+        this.constraintOperator = constraintOperator;
+        this.sourceType = sourceType;
+        this.sourceName = sourceName;
+        this.value = value;
+    }
+
+    public String getServicePropertyName() {
+        return servicePropertyName;
+    }
+
+    public void setServicePropertyName(String servicePropertyName) {
+        this.servicePropertyName = servicePropertyName;
+    }
+
+    public String getConstraintOperator() {
+        return constraintOperator;
+    }
+
+    public void setConstraintOperator(String constraintOperator) {
+        this.constraintOperator = constraintOperator;
+    }
+
+    public String getSourceType() {
+        return sourceType;
+    }
+
+    public void setSourceType(String sourceType) {
+        this.sourceType = sourceType;
+    }
+
+    public Object getValue() {
+        return value;
+    }
+
+    public void setValue(Object value) {
+        this.value = value;
+    }
+
+    public String getSourceName() {
+        return sourceName;
+    }
+
+    public void setSourceName(String sourceName) {
+        this.sourceName = sourceName;
+    }
+}
diff --git a/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/servicefilter/ServiceFilterTests.java b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/servicefilter/ServiceFilterTests.java
new file mode 100644 (file)
index 0000000..8be7132
--- /dev/null
@@ -0,0 +1,123 @@
+package org.openecomp.sdc.ci.tests.servicefilter;
+
+import java.util.Collections;
+
+import org.junit.Rule;
+import org.junit.rules.TestName;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.ci.tests.api.ComponentBaseTest;
+import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails;
+import org.openecomp.sdc.ci.tests.datatypes.PropertyReqDetails;
+import org.openecomp.sdc.ci.tests.datatypes.ServiceFilterDetails;
+import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails;
+import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum;
+import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum;
+import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse;
+import org.openecomp.sdc.ci.tests.utils.general.ElementFactory;
+import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils;
+import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils;
+import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils;
+import org.openecomp.sdc.ci.tests.utils.rest.PropertyRestUtils;
+import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser;
+import org.openecomp.sdc.ci.tests.utils.rest.ServiceFilterUtils;
+import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils;
+import org.testng.Assert;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+public class ServiceFilterTests extends ComponentBaseTest {
+    @Rule
+    public static TestName name = new TestName();
+
+    private static ServiceReqDetails externalService;
+    private static ComponentInstanceReqDetails componentInstanceReqDetails;
+    private static User user = null;
+
+    public ServiceFilterTests() {
+        super(name, ServiceFilterTests.class.getName());
+    }
+
+    @BeforeTest
+    public void init() throws Exception {
+        user = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER);
+
+        ServiceReqDetails internalService;
+        //Create External Service
+        externalService = ElementFactory.getDefaultService();
+        externalService.setName("ExternalService" + Math.random());
+        ServiceRestUtils.createService(externalService, user);
+
+        //Create Internal Service
+        internalService = ElementFactory.getDefaultService();
+        internalService.setName("InternalService" + Math.random());
+        ServiceRestUtils.createService(internalService, user);
+
+        //Add property services
+        //#PropertyOne
+        PropertyReqDetails propertyReqDetails = ElementFactory.getDefaultStringProperty();
+        propertyReqDetails.setName("StringProp1");
+        String body = propertyReqDetails.propertyToJsonString();
+        PropertyRestUtils.createServiceProperty(externalService.getUniqueId(), body, user);
+        PropertyRestUtils.createServiceProperty(internalService.getUniqueId(), body, user);
+        //#PropertyTwo
+        propertyReqDetails.setName("StringProp2");
+        body = propertyReqDetails.propertyToJsonString();
+        RestResponse response = PropertyRestUtils.createServiceProperty(externalService.getUniqueId(), body, user);
+        response = PropertyRestUtils.createServiceProperty(internalService.getUniqueId(), body, user);
+
+        //CheckIn internal Service
+        response = LifecycleRestUtils.changeServiceState(internalService, user, "0.1",
+                LifeCycleStatesEnum.CHECKIN,
+                "{\"userRemarks\":\"CheckIn\"}");
+        BaseRestUtils.checkSuccess(response);
+        if (response.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS) {
+            internalService.setUniqueId(ResponseParser.getUniqueIdFromResponse(response));
+        }
+        //Make internal service as component instance
+        componentInstanceReqDetails =
+                ElementFactory.getDefaultComponentInstance(internalService.getUniqueId(), "ServiceProxy");
+        response = ComponentInstanceRestUtils.createComponentInstance(componentInstanceReqDetails,
+                user, externalService.getUniqueId(), ComponentTypeEnum.SERVICE);
+        BaseRestUtils.checkCreateResponse(response);
+        if (response.getErrorCode() == BaseRestUtils.STATUS_CODE_CREATED) {
+            componentInstanceReqDetails.setUniqueId(ResponseParser.getUniqueIdFromResponse(response));
+            componentInstanceReqDetails.setName(ResponseParser.getNameFromResponse(response));
+        }
+        //Mark as dependent
+        componentInstanceReqDetails.setDirectives(Collections.singletonList("selectable"));
+        response = ComponentInstanceRestUtils.updateComponentInstance(componentInstanceReqDetails,
+                user, externalService.getUniqueId(), ComponentTypeEnum.SERVICE);
+        BaseRestUtils.checkSuccess(response);
+    }
+
+    @Test
+    public void createServiceFilter() throws Exception {
+        //Add Service Filter
+        ServiceFilterDetails serviceFilterDetails = ElementFactory.getDefaultEqualOperatorFilter("StringProp1", "value");
+        RestResponse restResponse = ServiceFilterUtils.createServiceFilter(externalService.getUniqueId(),
+                componentInstanceReqDetails.getUniqueId(), serviceFilterDetails, user);
+        logger.info("CreateServiceFilter Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+
+    @Test(dependsOnMethods = "createServiceFilter")
+    public void updateServiceFilter() throws Exception {
+        //Update Service Filter
+        ServiceFilterDetails serviceFilterDetails =
+                ElementFactory.getDefaultEqualOperatorFilter("StringProp1", "updated");
+        RestResponse restResponse = ServiceFilterUtils.updateServiceFilter(externalService.getUniqueId(),
+                componentInstanceReqDetails.getUniqueId(), Collections.singletonList(serviceFilterDetails),  user);
+        logger.info("UpdateServiceFilter Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+
+    //    @Test(dependsOnMethods = "updateServiceFilter")
+    public void deleteServiceFilter() throws Exception {
+        //Delete Service Filter
+        RestResponse restResponse = ServiceFilterUtils.deleteServiceFilter(externalService.getUniqueId(),
+                componentInstanceReqDetails.getUniqueId(), 0, user);
+        logger.info("DeleteServiceFilter Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+}
\ No newline at end of file
index e303682..82954e6 100644 (file)
@@ -391,6 +391,16 @@ public class ElementFactory {
 
        }
 
+    public static ComponentInstanceReqDetails getDefaultComponentInstance(String serviceUniqueId, String originType) {
+        ComponentInstanceReqDetails componentInstanceReqDetails = new ComponentInstanceReqDetails(serviceUniqueId,
+                RESOURCE_INSTANCE_DESCRIPTION, RESOURCE_INSTANCE_POS_X, RESOURCE_INSTANCE_POS_Y, null, originType);
+
+        componentInstanceReqDetails.setUniqueId(serviceUniqueId + Math.random());
+
+        return componentInstanceReqDetails;
+
+    }
+
        public static ComponentInstanceReqDetails getComponentResourceInstance(ComponentReqDetails compInstOriginDetails) {
                String compInstName = (compInstOriginDetails.getName() != null ? compInstOriginDetails.getName() : "resourceInstanceName");
                String resourceUid = compInstOriginDetails.getUniqueId();
@@ -407,6 +417,16 @@ public class ElementFactory {
 
        }
 
+       //********ServiceFilter**********
+    public static ServiceFilterDetails getDefaultEqualOperatorFilter(String propertyName, String valueString) {
+        return new ServiceFilterDetails(propertyName, "equal", "static", "static", valueString);
+    }
+
+    public static ServiceFilterDetails getDefaultFilter(String propertyName, String valueString,
+                                                                    String operator) {
+        return new ServiceFilterDetails(propertyName, operator, "static", "static", valueString);
+    }
+
        // ******* USER **********************
        public static User getDefaultUser(UserRoleEnum userRole) {
                User sdncModifierDetails = new User();
index d5ae0a4..9d2cdb5 100644 (file)
@@ -50,6 +50,14 @@ public class PropertyRestUtils extends BaseRestUtils {
         return sendPost(url, body, user.getUserId(), acceptHeaderData);
     }
 
+    public static RestResponse createServiceProperty(String resourceId, String body, User user) throws Exception {
+        Config config = Config.instance();
+        String url = String.format(Urls.CREATE_SERVICE_PROPERTY, config.getCatalogBeHost(), config.getCatalogBePort(),
+                resourceId);
+
+        return sendPost(url, body, user.getUserId(), acceptHeaderData);
+    }
+
     public static RestResponse updateProperty(String resourceId, String propertyId, String body, User user)
             throws Exception {
         Config config = Config.instance();
diff --git a/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ServiceFilterUtils.java b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ServiceFilterUtils.java
new file mode 100644 (file)
index 0000000..cc68ef5
--- /dev/null
@@ -0,0 +1,53 @@
+package org.openecomp.sdc.ci.tests.utils.rest;
+
+import com.google.gson.Gson;
+
+import java.util.List;
+
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.ci.tests.api.Urls;
+import org.openecomp.sdc.ci.tests.config.Config;
+import org.openecomp.sdc.ci.tests.datatypes.ServiceFilterDetails;
+import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ServiceFilterUtils extends BaseRestUtils {
+
+    private static Logger logger = LoggerFactory.getLogger(ServiceFilterUtils.class.getName());
+
+    private static Gson gson = new Gson();
+
+    public static RestResponse createServiceFilter(String externalServiceId, String proxyServiceId,
+                                                   ServiceFilterDetails serviceFilterDetails,
+                                                   User user) throws Exception{
+        Config config = Config.instance();
+
+        String url = String.format(Urls.CREATE_SERVICE_FILTER, config.getCatalogBeHost(), config.getCatalogBePort(),
+                externalServiceId, proxyServiceId);
+
+        return sendPost(url, gson.toJson(serviceFilterDetails), user.getUserId(), acceptHeaderData);
+    }
+
+    public static RestResponse updateServiceFilter(String externalServiceId, String proxyServiceId,
+                                                   List<ServiceFilterDetails> serviceFilterDetailsList,
+                                                   User user) throws Exception{
+        Config config = Config.instance();
+
+        String url = String.format(Urls.UPDATE_SERVICE_FILTER, config.getCatalogBeHost(), config.getCatalogBePort(),
+                externalServiceId, proxyServiceId);
+
+        return sendPut(url, gson.toJson(serviceFilterDetailsList), user.getUserId(), acceptHeaderData);
+    }
+
+    public static RestResponse deleteServiceFilter(String externalServiceId, String proxyServiceId,
+                                                   int constraintIndex,
+                                                   User user) throws Exception{
+        Config config = Config.instance();
+
+        String url = String.format(Urls.DELETE_SERVICE_FILTER, config.getCatalogBeHost(), config.getCatalogBePort(),
+                externalServiceId, proxyServiceId, constraintIndex);
+
+        return sendDelete(url, user.getUserId());
+    }
+}
index 88666cc..c82a772 100644 (file)
@@ -99,6 +99,7 @@ public class ServiceRestUtils extends BaseRestUtils {
                RestResponse res = sendPost(url, serviceBodyJson, user.getUserId(), acceptHeaderData);
                if (res.getErrorCode() == STATUS_CODE_CREATED) {
                        service.setUniqueId(ResponseParser.getUniqueIdFromResponse(res));
+            service.setName(ResponseParser.getNameFromResponse(res));
                        service.setVersion(ResponseParser.getVersionFromResponse(res));
                        service.setUUID(ResponseParser.getUuidFromResponse(res));
                        // Creator details never change after component is created - Ella,
index 707500a..391ba33 100644 (file)
@@ -4,8 +4,8 @@
        <parameter name="makeDistribution"  value="false"/>
        <parameter name="makeToscaValidation"  value="true"/>
        <test name="ExternalApis"> 
-               <classes>       
-                       
+               <classes>
+            <class name="org.openecomp.sdc.ci.tests.servicefilter.ServiceFilterTests"/>
                        <class name="org.openecomp.sdc.ci.tests.sanity.Onboard"/>
                </classes>
        </test>