Support Capability Properties 45/87545/1
authorMojahidul Islam <mojahidul.islam@amdocs.com>
Mon, 13 May 2019 11:38:25 +0000 (17:08 +0530)
committerMojahidul Islam <mojahidul.islam@amdocs.com>
Mon, 13 May 2019 11:39:02 +0000 (17:09 +0530)
This change includes following changes
1. Get capability properties from global types- BE
2. Show capability properties in cap/req screen
3. Support Capability Properties in assingment, operation and consumption screens

Change-Id: I7e21691beedfa8831ecf78c01ed501804f81ec78
Issue-ID: SDC-2295
Signed-off-by: Mojahidul Islam <mojahidul.islam@amdocs.com>
60 files changed:
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CapabilitiesBusinessLogic.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/InterfaceOperationBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CertificationChangeTransition.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTransition.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentInstancePropertyDeclarator.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/property/DefaultPropertyDeclarator.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/ConsumptionUtils.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/PropertiesUtils.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/ProxyServicePropertiesUtils.java [deleted file]
catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/CapabilitiesValidation.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java
catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceConsumptionServlet.java
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java
catalog-be/src/main/resources/config/error-configuration.yaml
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/CapabilitiesBusinessLogicTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/PropertiesUtilsTest.java [new file with mode: 0644]
catalog-be/src/test/java/org/openecomp/sdc/be/components/property/CapabilityTestUtils.java [new file with mode: 0644]
catalog-be/src/test/java/org/openecomp/sdc/be/components/property/ComponentInstancePropertyDeclaratorTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/ConsumptionUtilsTest.java [new file with mode: 0644]
catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtilsTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/CapabilitiesValidationTest.java
catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/BaseOperation.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperation.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/operations/ToscaOperationFacade.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java
catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperationTest.java [new file with mode: 0644]
catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/CapabilityTestUtils.java [new file with mode: 0644]
catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverterTest.java
catalog-ui/src/app/models/capability-types.ts
catalog-ui/src/app/models/capability.ts
catalog-ui/src/app/models/properties-inputs/property-be-model.ts
catalog-ui/src/app/models/properties-inputs/property-fe-model.ts
catalog-ui/src/app/models/tosca-presentation.ts
catalog-ui/src/app/modules/directive-module.ts
catalog-ui/src/app/ng2/components/logic/service-consumption/service-consumption.component.ts
catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.html
catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.ts
catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts
catalog-ui/src/app/ng2/pages/req-and-capabilities-editor/capabilities-editor/capabilities-editor.component.ts
catalog-ui/src/app/ng2/pages/service-consumption-editor/service-consumption-editor.component.html
catalog-ui/src/app/ng2/pages/service-consumption-editor/service-consumption-editor.component.ts
catalog-ui/src/app/ng2/services/component-services/service.service.ts
catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/service-consumption/service-consumption-view-model.ts
catalog-ui/src/app/view-models/workspace/tabs/composition/tabs/service-consumption/service-consumption-view.html
catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-editable-view.html
catalog-ui/src/app/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities.less
catalog-ui/src/assets/styles/mixins_old.less
test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/capability/CapabilitiesTest.java
test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/CapabilityDetails.java
test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/CapabilityRestUtils.java

index 75d5836..f2fd377 100644 (file)
@@ -18,28 +18,35 @@ package org.openecomp.sdc.be.components.impl;
 
 import fj.data.Either;
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
 import org.openecomp.sdc.be.components.validation.CapabilitiesValidation;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.CapabilityDefinition;
 import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
 import org.openecomp.sdc.be.model.ComponentParametersView;
 import org.openecomp.sdc.be.model.User;
 import org.openecomp.sdc.be.model.jsontitan.operations.CapabilitiesOperation;
+import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
 import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 import org.openecomp.sdc.exception.ResponseFormat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -47,15 +54,13 @@ import java.util.Optional;
 import java.util.UUID;
 import java.util.stream.Collectors;
 
-@Component("capabilitiesBusinessLogic")
+@org.springframework.stereotype.Component("capabilitiesBusinessLogic")
 public class CapabilitiesBusinessLogic extends BaseBusinessLogic {
     private static final Logger LOGGER = LoggerFactory.getLogger(CapabilitiesBusinessLogic.class);
-    private static final String FAILED_TO_LOCK_COMPONENT_RESPONSE_IS
-            = "Failed to lock component {}. Response is {}";
+    private static final String FAILED_TO_LOCK_COMPONENT_RESPONSE_IS = "Failed to lock component {}. Response is {}";
     private static final String DELETE_CAPABILITIES = "deleteCapability";
     private static final String GET_CAPABILITIES = "getCapabilities";
-    private static final String EXCEPTION_OCCURRED_DURING_CAPABILITIES
-            = "Exception occurred during {}. Response is {}";
+    private static final String EXCEPTION_OCCURRED_DURING_CAPABILITIES = "Exception occurred during {}. Response is {}";
 
     @Autowired
     private CapabilitiesOperation capabilitiesOperation;
@@ -64,7 +69,6 @@ public class CapabilitiesBusinessLogic extends BaseBusinessLogic {
     @Autowired
     private ICapabilityTypeOperation capabilityTypeOperation;
 
-
     public void setCapabilitiesValidation(CapabilitiesValidation capabilitiesValidation) {
         this.capabilitiesValidation = capabilitiesValidation;
     }
@@ -73,67 +77,22 @@ public class CapabilitiesBusinessLogic extends BaseBusinessLogic {
         this.capabilitiesOperation = capabilitiesOperation;
     }
 
-    public Either<List<CapabilityDefinition>, ResponseFormat> createCapabilities(
-            String componentId, List<CapabilityDefinition> capabilityDefinitions,
-            User user, String errorContext, boolean lock) {
-        validateUserExists(user.getUserId(), errorContext, true);
-        Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither
-                = getComponentDetails(componentId);
-        if (componentEither.isRight()) {
-            return Either.right(componentEither.right().value());
-        }
-        org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
-        Either<Boolean, ResponseFormat> capabilitiesValidationEither = capabilitiesValidation
-                .validateCapabilities(capabilityDefinitions, storedComponent, false);
-        if (capabilitiesValidationEither.isRight()) {
-            return Either.right(capabilitiesValidationEither.right().value());
+    public Either<List<CapabilityDefinition>, ResponseFormat> createCapabilities(String componentId,
+                                                                                 List<CapabilityDefinition> capabilityDefinitions,
+                                                                                 User user, String errorContext, boolean lock) {
+        Either<Component, ResponseFormat> validateUserAndCapabilitiesEither =
+                validateUserAndCapabilities(user, componentId, errorContext, capabilityDefinitions);
+        if(validateUserAndCapabilitiesEither.isRight()) {
+            return Either.right(validateUserAndCapabilitiesEither.right().value());
         }
+        Component  storedComponent = validateUserAndCapabilitiesEither.left().value();
 
-        Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock,
-                storedComponent, errorContext);
+        Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock, storedComponent, errorContext);
         if (lockResult.isRight()) {
             return Either.right(lockResult.right().value());
         }
         try {
-            Either<List<CapabilityDefinition>, StorageOperationStatus> result;
-            List<CapabilityDefinition> capabilitiesListStoredInComponent = null;
-            Map<String, List<CapabilityDefinition>> storedComponentCapabilities
-                    = storedComponent.getCapabilities();
-            if (org.apache.commons.collections.MapUtils.isNotEmpty(storedComponentCapabilities)) {
-                CapabilityDefinition capabilityDefinitionToGetType = capabilityDefinitions.get(0);
-                if(Objects.isNull(capabilityDefinitionToGetType)) {
-                    return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
-                }
-                capabilitiesListStoredInComponent
-                        = getCapabilityStoredInComponentByType(capabilityDefinitionToGetType
-                        .getType(), storedComponentCapabilities);
-            }
-            List<CapabilityDefinition> capabilitiesDefListToCreate;
-            List<CapabilityDefinition> capabilitiesToReturn;
-            if (CollectionUtils.isNotEmpty(capabilitiesListStoredInComponent)) {
-                capabilitiesDefListToCreate = capabilityDefinitions.stream()
-                        .map(capabilityDefinition ->
-                                initiateNewCapability(storedComponent, capabilityDefinition))
-                        .collect(Collectors.toList());
-                capabilitiesToReturn = capabilitiesDefListToCreate;
-                capabilitiesDefListToCreate.addAll(capabilitiesListStoredInComponent);
-                result = capabilitiesOperation.updateCapabilities(componentId,
-                        capabilitiesDefListToCreate);
-            } else {
-                capabilitiesToReturn = capabilityDefinitions.stream()
-                        .map(capabilityDefinition -> initiateNewCapability(
-                                storedComponent, capabilityDefinition))
-                        .collect(Collectors.toList());
-                result = capabilitiesOperation.addCapabilities(componentId, capabilitiesToReturn);
-            }
-            if (result.isRight()) {
-                titanDao.rollback();
-                return Either.right(componentsUtils.getResponseFormat(
-                        componentsUtils.convertFromStorageResponse(result.right().value(),
-                                storedComponent.getComponentType()), ""));
-            }
-            titanDao.commit();
-            return Either.left(capabilitiesToReturn);
+            return createCapability(componentId, capabilityDefinitions, storedComponent);
         } catch (Exception e) {
             titanDao.rollback();
             LOGGER.error(EXCEPTION_OCCURRED_DURING_CAPABILITIES, "addOrUpdate", e);
@@ -146,39 +105,99 @@ public class CapabilitiesBusinessLogic extends BaseBusinessLogic {
         }
     }
 
-    public Either<List<CapabilityDefinition>, ResponseFormat> updateCapabilities(
-            String componentId, List<CapabilityDefinition> capabilityDefinitions,
-            User user, String errorContext, boolean lock) {
+
+    private Either<Component, ResponseFormat> validateUserAndCapabilities(User user, String componentId,
+                                                                          String errorContext,
+                                                                          List<CapabilityDefinition> capabilityDefinitions ) {
+        validateUserExists(user.getUserId(), errorContext, true);
+        Either<Component, ResponseFormat> componentEither = getComponentDetails(componentId);
+        if (componentEither.isRight()) {
+            return Either.right(componentEither.right().value());
+        }
+        Component storedComponent = componentEither.left().value();
+        Either<Boolean, ResponseFormat> capabilitiesValidationEither = capabilitiesValidation
+                .validateCapabilities(capabilityDefinitions, storedComponent, false);
+        if (capabilitiesValidationEither.isRight()) {
+            return Either.right(capabilitiesValidationEither.right().value());
+        }
+        return Either.left(storedComponent);
+    }
+
+    private Either<List<CapabilityDefinition>, ResponseFormat> createCapability(String componentId,
+                                                                                List<CapabilityDefinition> capabilityDefinitions,
+                                                                                Component storedComponent) {
+        Either<List<CapabilityDefinition>, StorageOperationStatus> result;
+        List<CapabilityDefinition> capabilitiesListStoredInComponent = null;
+        Map<String, List<CapabilityDefinition>> storedComponentCapabilities = storedComponent.getCapabilities();
+        if (MapUtils.isNotEmpty(storedComponentCapabilities)) {
+            CapabilityDefinition capabilityDefinitionToGetType = capabilityDefinitions.get(0);
+            if (Objects.isNull(capabilityDefinitionToGetType)) {
+                return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
+            }
+            capabilitiesListStoredInComponent = getCapabilityStoredInComponentByType(capabilityDefinitionToGetType
+                    .getType(), storedComponentCapabilities);
+        }
+        List<CapabilityDefinition> capabilitiesDefListToCreate;
+        List<CapabilityDefinition> capabilitiesToReturn;
+        if (CollectionUtils.isNotEmpty(capabilitiesListStoredInComponent)) {
+            capabilitiesDefListToCreate = capabilityDefinitions.stream().map(capabilityDefinition ->
+                    initiateNewCapability(storedComponent, capabilityDefinition)).collect(Collectors.toList());
+            capabilitiesToReturn = capabilitiesDefListToCreate;
+            capabilitiesDefListToCreate.addAll(capabilitiesListStoredInComponent);
+            result = capabilitiesOperation.updateCapabilities(componentId, capabilitiesDefListToCreate);
+        } else {
+            capabilitiesToReturn = capabilityDefinitions.stream().map(capabilityDefinition ->
+                    initiateNewCapability(storedComponent, capabilityDefinition)).collect(Collectors.toList());
+            result = capabilitiesOperation.addCapabilities(componentId, capabilitiesToReturn);
+        }
+        if (result.isRight()) {
+            titanDao.rollback();
+            return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(result
+                    .right().value(), storedComponent.getComponentType()), ""));
+        }
+        Map<String, MapPropertiesDataDefinition> propertiesMap =
+                getCapabilitiesPropertiesDataDefinitionMap(capabilityDefinitions);
+        if (MapUtils.isNotEmpty(propertiesMap)) {
+            StorageOperationStatus storageOperationStatus = capabilitiesOperation
+                    .createOrUpdateCapabilityProperties(componentId, propertiesMap);
+            if (storageOperationStatus != StorageOperationStatus.OK) {
+                titanDao.rollback();
+                return Either.right(componentsUtils.getResponseFormat(storageOperationStatus));
+            }
+        }
+        titanDao.commit();
+        return Either.left(capabilitiesToReturn);
+    }
+
+    public Either<List<CapabilityDefinition>, ResponseFormat> updateCapabilities(String componentId,
+                                                                                 List<CapabilityDefinition> capabilityDefinitions,
+                                                                                 User user, String errorContext, boolean lock) {
         validateUserExists(user.getUserId(), errorContext, true);
-        Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither
-                = getComponentDetails(componentId);
+        Either<Component, ResponseFormat> componentEither = getComponentDetails(componentId);
         if (componentEither.isRight()) {
             return Either.right(componentEither.right().value());
         }
-        org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
+        Component storedComponent = componentEither.left().value();
         Either<Boolean, ResponseFormat> capabilitiesValidationEither = capabilitiesValidation
                 .validateCapabilities(capabilityDefinitions, storedComponent, true);
         if (capabilitiesValidationEither.isRight()) {
             return Either.right(capabilitiesValidationEither.right().value());
         }
 
-        Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock,
-                storedComponent, errorContext);
+        Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock, storedComponent, errorContext);
         if (lockResult.isRight()) {
             return Either.right(lockResult.right().value());
         }
         try {
             Either<List<CapabilityDefinition>, StorageOperationStatus> result;
             List<CapabilityDefinition> capabilitiesListStoredInComponent = null;
-            Map<String, List<CapabilityDefinition>> storedComponentCapabilities
-                    = storedComponent.getCapabilities();
+            Map<String, List<CapabilityDefinition>> storedComponentCapabilities = storedComponent.getCapabilities();
             if (org.apache.commons.collections.MapUtils.isNotEmpty(storedComponentCapabilities)) {
                 CapabilityDefinition capabilityDefinitionToGetType = capabilityDefinitions.get(0);
-                if(Objects.isNull(capabilityDefinitionToGetType)) {
+                if (Objects.isNull(capabilityDefinitionToGetType)) {
                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
                 }
-                capabilitiesListStoredInComponent
-                        = getCapabilityStoredInComponentByType(capabilityDefinitionToGetType
+                capabilitiesListStoredInComponent = getCapabilityStoredInComponentByType(capabilityDefinitionToGetType
                         .getType(), storedComponentCapabilities);
             }
             List<CapabilityDefinition> capabilitiesDefListToUpdate = new ArrayList<>();
@@ -186,54 +205,57 @@ public class CapabilitiesBusinessLogic extends BaseBusinessLogic {
             if (CollectionUtils.isNotEmpty(capabilitiesListStoredInComponent)) {
                 if (capabilityDefinitions.stream().anyMatch(capabilityDefinition ->
                         isCapabilityUsedInServiceComposition(capabilityDefinition, storedComponent))) {
-                    LOGGER.error("Capability can't be edited, since it is"
-                            + " used in service composition");
-                    return Either.right(componentsUtils.getResponseFormat(
-                            ActionStatus.CAPABILITY_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION));
+                    LOGGER.error("Capability can't be edited, since it is" + " used in service composition");
+                    return Either.right(componentsUtils.getResponseFormat(ActionStatus.
+                            CAPABILITY_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION));
                 }
                 for (CapabilityDefinition capabilityDefinitionToUpdate : capabilityDefinitions) {
-                    capabilitiesToReturn = capabilitiesListStoredInComponent.stream()
-                            .filter(capToUpdate -> capToUpdate.getUniqueId()
-                                    .equals(capabilityDefinitionToUpdate.getUniqueId()))
+                    capabilitiesToReturn = capabilitiesListStoredInComponent.stream().filter(capToUpdate ->
+                            capToUpdate.getUniqueId().equals(capabilityDefinitionToUpdate.getUniqueId()))
                             .map(capabilityDefinition -> updateCapability(capabilityDefinition,
-                                    capabilityDefinitionToUpdate)).collect(Collectors.toList());
-                    capabilitiesListStoredInComponent.removeIf(capToUpdate ->
-                            capToUpdate.getUniqueId().equals(capabilityDefinitionToUpdate.getUniqueId()));
+                                    capabilityDefinitionToUpdate, storedComponent)).collect(Collectors.toList());
+                    capabilitiesListStoredInComponent.removeIf(capToUpdate -> capToUpdate.getUniqueId()
+                            .equals(capabilityDefinitionToUpdate.getUniqueId()));
                     if (CollectionUtils.isNotEmpty(capabilitiesToReturn)) {
                         capabilitiesListStoredInComponent.addAll(capabilitiesToReturn);
                         capabilitiesDefListToUpdate.addAll(capabilitiesListStoredInComponent);
                     } else {
                         Either<List<CapabilityDefinition>, ResponseFormat> capTypeUpdateEither
-                                = handleCapabilityTypeUpdateWhenNewTypeExist(storedComponent,
-                                storedComponent.getCapabilities(), capabilitiesToReturn, capabilityDefinitionToUpdate);
+                                = handleCapabilityTypeUpdateWhenNewTypeExist(storedComponent, storedComponent
+                                .getCapabilities(), capabilitiesToReturn, capabilityDefinitionToUpdate);
                         if (capTypeUpdateEither.isRight()) {
                             return Either.right(capTypeUpdateEither.right().value());
                         }
                         capabilitiesDefListToUpdate = capTypeUpdateEither.left().value();
                     }
                 }
-                result = capabilitiesOperation.updateCapabilities(componentId,
-                        capabilitiesDefListToUpdate);
+                result = capabilitiesOperation.updateCapabilities(componentId, capabilitiesDefListToUpdate);
             } else {
                 Either<List<CapabilityDefinition>, ResponseFormat> capabilityDefinitionToDelete
-                        = handleCapabilityTypeUpdateWhenNewTypeNotExist(capabilityDefinitions,
-                        storedComponent, storedComponentCapabilities);
+                        = handleCapabilityTypeUpdateWhenNewTypeNotExist(capabilityDefinitions, storedComponent,
+                        storedComponentCapabilities);
                 if (capabilityDefinitionToDelete != null) {
                     return capabilityDefinitionToDelete;
                 }
-                capabilitiesToReturn = capabilityDefinitions.stream()
-                        .map(capabilityDefinition -> initiateNewCapability(
-                                storedComponent, capabilityDefinition))
-                        .collect(Collectors.toList());
+                capabilitiesToReturn = capabilityDefinitions.stream().map(capabilityDefinition ->
+                        initiateNewCapability(storedComponent, capabilityDefinition)).collect(Collectors.toList());
                 result = capabilitiesOperation.addCapabilities(componentId, capabilitiesToReturn);
             }
             if (result.isRight()) {
                 titanDao.rollback();
-                return Either.right(componentsUtils.getResponseFormat(
-                        componentsUtils.convertFromStorageResponse(result.right().value(),
-                                storedComponent.getComponentType()), ""));
+                return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(result
+                        .right().value(), storedComponent.getComponentType()), ""));
+            }
+            Map<String, MapPropertiesDataDefinition> propertiesMap =
+                    getCapabilitiesPropertiesDataDefinitionMap(capabilityDefinitions);
+            if (MapUtils.isNotEmpty(propertiesMap)) {
+                StorageOperationStatus storageOperationStatus = capabilitiesOperation
+                        .createOrUpdateCapabilityProperties(componentId, propertiesMap);
+                if (storageOperationStatus != StorageOperationStatus.OK) {
+                    titanDao.rollback();
+                    return Either.right(componentsUtils.getResponseFormat(storageOperationStatus));
+                }
             }
-
             titanDao.commit();
             return Either.left(capabilitiesToReturn);
         } catch (Exception e) {
@@ -249,30 +271,36 @@ public class CapabilitiesBusinessLogic extends BaseBusinessLogic {
     }
 
     private Either<List<CapabilityDefinition>, ResponseFormat> handleCapabilityTypeUpdateWhenNewTypeExist(
-            org.openecomp.sdc.be.model.Component storedComponent, Map<String,
-            List<CapabilityDefinition>> storedComponentCapabilities,
+            Component storedComponent,
+            Map<String, List<CapabilityDefinition>> storedComponentCapabilities,
             List<CapabilityDefinition> capabilitiesToReturn,
             CapabilityDefinition capabilityDefinitionToUpdate) {
+
         List<CapabilityDefinition> capabilitiesListStoredInComponent;
         List<CapabilityDefinition> capabilitiesDefsToCreateOrUpdate = new ArrayList<>();
-        Optional<CapabilityDefinition> definitionOptional = storedComponentCapabilities
-                .values().stream().flatMap(Collection::stream)
-                .filter(capabilityDefinition -> capabilityDefinition.getUniqueId()
+        Optional<CapabilityDefinition> definitionOptional = storedComponentCapabilities.values().stream()
+                .flatMap(Collection::stream).filter(capabilityDefinition -> capabilityDefinition.getUniqueId()
                         .equals(capabilityDefinitionToUpdate.getUniqueId())).findAny();
         if (!definitionOptional.isPresent()) {
-            return Either.right(componentsUtils.getResponseFormat(
-                    ActionStatus.CAPABILITY_NOT_FOUND, storedComponent.getUniqueId()));
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND,
+                    storedComponent.getUniqueId()));
         }
         CapabilityDefinition capabilityDefinitionToDelete = definitionOptional.get();
 
-        capabilitiesListStoredInComponent = getCapabilityStoredInComponentByType(
-                capabilityDefinitionToUpdate.getType(), storedComponentCapabilities);
+        capabilitiesListStoredInComponent = getCapabilityStoredInComponentByType(capabilityDefinitionToUpdate.getType(),
+                storedComponentCapabilities);
         Either<List<CapabilityDefinition>, StorageOperationStatus> deleteCapabilityEither
                 = deleteCapability(storedComponent, storedComponentCapabilities, capabilityDefinitionToDelete);
         if (deleteCapabilityEither.isRight()) {
             titanDao.rollback();
             return Either.right(componentsUtils.getResponseFormat(deleteCapabilityEither.right().value()));
         }
+        StorageOperationStatus deleteStorageOperationStatus = capabilitiesOperation
+                .deleteCapabilityProperties(storedComponent, buildCapPropKey(capabilityDefinitionToDelete));
+        if (deleteStorageOperationStatus != StorageOperationStatus.OK) {
+            titanDao.rollback();
+            return Either.right(componentsUtils.getResponseFormat(deleteStorageOperationStatus));
+        }
         capabilitiesToReturn.add(initiateNewCapability(storedComponent, capabilityDefinitionToUpdate));
 
         capabilitiesDefsToCreateOrUpdate.addAll(capabilitiesToReturn);
@@ -282,21 +310,20 @@ public class CapabilitiesBusinessLogic extends BaseBusinessLogic {
 
     private Either<List<CapabilityDefinition>, ResponseFormat> handleCapabilityTypeUpdateWhenNewTypeNotExist(
             List<CapabilityDefinition> capabilityDefinitions,
-            org.openecomp.sdc.be.model.Component storedComponent,
+            Component storedComponent,
             Map<String, List<CapabilityDefinition>> storedComponentCapabilities) {
         for (CapabilityDefinition capabilityDefinitionToUpdate : capabilityDefinitions) {
 
-            Optional<CapabilityDefinition> definitionOptional = storedComponentCapabilities.values()
-                    .stream().flatMap(Collection::stream)
-                    .filter(capabilityDefinition -> capabilityDefinition.getUniqueId()
+            Optional<CapabilityDefinition> definitionOptional = storedComponentCapabilities.values().stream()
+                    .flatMap(Collection::stream).filter(capabilityDefinition -> capabilityDefinition.getUniqueId()
                             .equals(capabilityDefinitionToUpdate.getUniqueId())).findAny();
             if (!definitionOptional.isPresent()) {
-                return Either.right(componentsUtils.getResponseFormat(
-                        ActionStatus.CAPABILITY_NOT_FOUND, storedComponent.getUniqueId()));
+                return Either.right(componentsUtils.getResponseFormat(ActionStatus
+                        .CAPABILITY_NOT_FOUND, storedComponent.getUniqueId()));
             }
             CapabilityDefinition capabilityDefinitionToDelete = definitionOptional.get();
-            Boolean isCapabilityUsedInServiceComposition = isCapabilityUsedInServiceComposition(
-                    capabilityDefinitionToDelete, storedComponent);
+            Boolean isCapabilityUsedInServiceComposition = isCapabilityUsedInServiceComposition(capabilityDefinitionToDelete,
+                    storedComponent);
             if (isCapabilityUsedInServiceComposition) {
                 LOGGER.error("Capability {} can't be edited, since it is used in service composition",
                         capabilityDefinitionToDelete.getUniqueId());
@@ -305,125 +332,88 @@ public class CapabilitiesBusinessLogic extends BaseBusinessLogic {
                         capabilityDefinitionToDelete.getName()));
             }
             Either<List<CapabilityDefinition>, StorageOperationStatus> deleteCapabilityEither
-                    = deleteCapability(storedComponent, storedComponentCapabilities,
-                    capabilityDefinitionToDelete);
+                    = deleteCapability(storedComponent, storedComponentCapabilities, capabilityDefinitionToDelete);
             if (deleteCapabilityEither.isRight()) {
                 titanDao.rollback();
                 return Either.right(componentsUtils.getResponseFormat(deleteCapabilityEither.right().value()));
             }
+            StorageOperationStatus deleteStorageOperationStatus = capabilitiesOperation
+                    .deleteCapabilityProperties(storedComponent, buildCapPropKey(capabilityDefinitionToDelete));
+            if (deleteStorageOperationStatus != StorageOperationStatus.OK) {
+                titanDao.rollback();
+                return Either.right(componentsUtils.getResponseFormat(deleteStorageOperationStatus));
+            }
         }
         return null;
     }
 
-    public Either<CapabilityDefinition, ResponseFormat> getCapability(
-            String componentId,
-            String capabilityToGet, User user, boolean lock) {
+    public Either<CapabilityDefinition, ResponseFormat> getCapability(String componentId, String capabilityToGet,
+                                                                      User user, boolean lock) {
         validateUserExists(user.getUserId(), GET_CAPABILITIES, true);
-        Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither
-                = getComponentDetails(componentId);
+        Either<Component, ResponseFormat> componentEither = getComponentDetails(componentId);
         if (componentEither.isRight()) {
             return Either.right(componentEither.right().value());
         }
-        org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
+        Component storedComponent = componentEither.left().value();
 
-        Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock,
-                storedComponent, GET_CAPABILITIES);
+        Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock, storedComponent, GET_CAPABILITIES);
         if (lockResult.isRight()) {
             return Either.right(lockResult.right().value());
         }
         try {
-            List<CapabilityDefinition> capabilityDefinitions = storedComponent.getCapabilities()
-                    .values().stream()
-                    .flatMap(Collection::stream).collect(Collectors.toList());
-            if (capabilityDefinitions.isEmpty()) {
-                return Either.right(componentsUtils.getResponseFormat(
-                        ActionStatus.CAPABILITY_NOT_FOUND, componentId));
+            Either<CapabilityDefinition, ResponseFormat> getCapabilityDefinitionEither =
+                    getCapabilityDefinition(capabilityToGet, storedComponent);
+            if (getCapabilityDefinitionEither.isRight()) {
+                return Either.right(getCapabilityDefinitionEither.right().value());
             }
-
-            CapabilityDefinition capabilityDefinitionToReturn;
-            Optional<CapabilityDefinition> capabilityDefinitionOptional
-                    = capabilityDefinitions.stream()
-                    .filter(capabilityDefinition -> capabilityDefinition.getUniqueId()
-                            .equals(capabilityToGet)).findAny();
-            if (capabilityDefinitionOptional.isPresent()) {
-                capabilityDefinitionToReturn = capabilityDefinitionOptional.get();
-            } else {
-                return Either.right(componentsUtils.getResponseFormat(
-                        ActionStatus.CAPABILITY_NOT_FOUND, componentId));
-            }
-
-            return Either.left(capabilityDefinitionToReturn);
+            return Either.left(getCapabilityDefinitionEither.left().value());
         } catch (Exception e) {
             LOGGER.error(EXCEPTION_OCCURRED_DURING_CAPABILITIES, "get", e);
-            return Either.right(componentsUtils.getResponseFormat(
-                    ActionStatus.CAPABILITY_NOT_FOUND, componentId));
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND, componentId));
         } finally {
             if (lockResult.isLeft() && lockResult.left().value()) {
                 graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
-                        NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType()
-                                .getValue()));
+                        NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
             }
         }
     }
 
-    public Either<CapabilityDefinition, ResponseFormat> deleteCapability(
-            String componentId, String capabilityIdToDelete, User user,
-            boolean lock) {
+    private Either<CapabilityDefinition, ResponseFormat> getCapabilityDefinition(String capabilityIdToGet,
+                                                                                 Component storedComponent) {
+        List<CapabilityDefinition> capabilityDefinitions = storedComponent.getCapabilities().values()
+                .stream().flatMap(Collection::stream).collect(Collectors.toList());
+        if (capabilityDefinitions.isEmpty()) {
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND,
+                    storedComponent.getUniqueId()));
+        }
+        CapabilityDefinition capabilityDefinitionToReturn;
+        Optional<CapabilityDefinition> capabilityDefinitionOptional = capabilityDefinitions.stream()
+                .filter(capabilityDefinition -> capabilityDefinition.getUniqueId().equals(capabilityIdToGet)).findAny();
+        if (capabilityDefinitionOptional.isPresent()) {
+            capabilityDefinitionToReturn = capabilityDefinitionOptional.get();
+        } else {
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND,
+                    storedComponent.getUniqueId()));
+        }
+
+        return Either.left(capabilityDefinitionToReturn);
+    }
+
+    public Either<CapabilityDefinition, ResponseFormat> deleteCapability(String componentId, String capabilityIdToDelete,
+                                                                         User user, boolean lock) {
         validateUserExists(user.getUserId(), DELETE_CAPABILITIES, true);
-        Either<org.openecomp.sdc.be.model.Component, ResponseFormat> componentEither
-                = getComponentDetails(componentId);
+        Either<Component, ResponseFormat> componentEither = getComponentDetails(componentId);
         if (componentEither.isRight()) {
             return Either.right(componentEither.right().value());
         }
-        org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
+        Component storedComponent = componentEither.left().value();
 
-        Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock,
-                storedComponent, DELETE_CAPABILITIES);
+        Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock, storedComponent, DELETE_CAPABILITIES);
         if (lockResult.isRight()) {
             return Either.right(lockResult.right().value());
         }
-
         try {
-            Map<String, List<CapabilityDefinition>> storedComponentCapabilities
-                    = storedComponent.getCapabilities();
-            if (storedComponentCapabilities.isEmpty()) {
-                return Either.right(componentsUtils.getResponseFormat(
-                        ActionStatus.CAPABILITY_NOT_FOUND, componentId));
-            }
-
-            Optional<CapabilityDefinition> definitionOptional = storedComponentCapabilities
-                    .values().stream().flatMap(Collection::stream)
-                    .filter(capabilityDefinition -> capabilityDefinition.getUniqueId()
-                            .equals(capabilityIdToDelete)).findAny();
-            if (!definitionOptional.isPresent()) {
-                return Either.right(componentsUtils.getResponseFormat(
-                        ActionStatus.CAPABILITY_NOT_FOUND, componentId));
-            }
-            CapabilityDefinition capabilityDefinitionToDelete = definitionOptional.get();
-            Boolean isCapabilityUsedInServiceComposition
-                    = isCapabilityUsedInServiceComposition(capabilityDefinitionToDelete, storedComponent);
-            if (isCapabilityUsedInServiceComposition) {
-                LOGGER.error("Capability {} can't be deleted, since it is used in service composition",
-                        capabilityDefinitionToDelete.getUniqueId());
-                return Either.right(componentsUtils.getResponseFormat(
-                        ActionStatus.CAPABILITY_DELETION_NOT_ALLOWED_USED_IN_COMPOSITION,
-                        capabilityDefinitionToDelete.getName()));
-            }
-
-            Either<List<CapabilityDefinition>, StorageOperationStatus> result
-                    = deleteCapability(storedComponent, storedComponentCapabilities,
-                    capabilityDefinitionToDelete);
-            if (result.isRight()) {
-                titanDao.rollback();
-                LOGGER.error("Failed to delete capability  from component {}. Response is {}",
-                        storedComponent.getName(), result.right().value());
-                return Either.right(componentsUtils.getResponseFormat(
-                        componentsUtils.convertFromStorageResponse(result.right().value(),
-                                storedComponent.getComponentType())));
-            }
-
-            titanDao.commit();
-            return Either.left(capabilityDefinitionToDelete);
+            return deleteCapability(capabilityIdToDelete, storedComponent);
         } catch (Exception e) {
             LOGGER.error(EXCEPTION_OCCURRED_DURING_CAPABILITIES, "delete", e);
             titanDao.rollback();
@@ -436,16 +426,61 @@ public class CapabilitiesBusinessLogic extends BaseBusinessLogic {
         }
     }
 
-    private Either<List<CapabilityDefinition>, StorageOperationStatus> deleteCapability(
-            org.openecomp.sdc.be.model.Component storedComponent,
-            Map<String, List<CapabilityDefinition>> storedComponentCapabilities,
-            CapabilityDefinition capabilityDefinitionToDelete) {
-        List<CapabilityDefinition> capabilitiesListStoredInComponent =
-                getCapabilityStoredInComponentByType(capabilityDefinitionToDelete.getType(),
-                        storedComponentCapabilities);
-        if(capabilitiesListStoredInComponent == null) {
-           return Either.right(StorageOperationStatus.BAD_REQUEST);
+    private Either<CapabilityDefinition, ResponseFormat> deleteCapability(String capabilityIdToDelete,
+                                                                          Component storedComponent) {
+        Map<String, List<CapabilityDefinition>> storedComponentCapabilities = storedComponent.getCapabilities();
+        if (storedComponentCapabilities.isEmpty()) {
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND, storedComponent.getUniqueId()));
         }
+        Either<CapabilityDefinition, ResponseFormat> capabilityDefinitionToDeleteEither =
+                getAndValidateCapabilitiesToDelete(storedComponent, storedComponentCapabilities, capabilityIdToDelete);
+
+        if(capabilityDefinitionToDeleteEither.isRight()) {
+            return Either.right(capabilityDefinitionToDeleteEither.right().value());
+        }
+        Either<List<CapabilityDefinition>, StorageOperationStatus> result = deleteCapability(storedComponent,
+                storedComponentCapabilities, capabilityDefinitionToDeleteEither.left().value());
+        if (result.isRight()) {
+            titanDao.rollback();
+            LOGGER.error("Failed to delete capability  from component {}. Response is {}", storedComponent.getName(),
+                    result.right().value());
+            return Either.right(componentsUtils.getResponseFormat(
+                    componentsUtils.convertFromStorageResponse(result.right().value(),
+                            storedComponent.getComponentType())));
+        }
+        titanDao.commit();
+
+        return Either.left(capabilityDefinitionToDeleteEither.left().value());
+    }
+
+    private Either<CapabilityDefinition, ResponseFormat> getAndValidateCapabilitiesToDelete(Component storedComponent,
+                                                                                            Map<String, List<CapabilityDefinition>> storedComponentCapabilities,
+                                                                                            String capabilityIdToDelete) {
+
+        Optional<CapabilityDefinition> definitionOptional = storedComponentCapabilities.values().stream()
+                .flatMap(Collection::stream).filter(capabilityDefinition -> capabilityDefinition.getUniqueId()
+                        .equals(capabilityIdToDelete)).findAny();
+        if (!definitionOptional.isPresent()) {
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND, storedComponent.getUniqueId()));
+        }
+        CapabilityDefinition capabilityDefinitionToDelete = definitionOptional.get();
+        Boolean isCapabilityUsedInServiceComposition
+                = isCapabilityUsedInServiceComposition(capabilityDefinitionToDelete, storedComponent);
+        if (isCapabilityUsedInServiceComposition) {
+            LOGGER.error("Capability {} can't be deleted, since it is used in service composition",
+                    capabilityDefinitionToDelete.getUniqueId());
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus
+                    .CAPABILITY_DELETION_NOT_ALLOWED_USED_IN_COMPOSITION, capabilityDefinitionToDelete.getName()));
+        }
+
+        return Either.left(capabilityDefinitionToDelete);
+    }
+    private Either<List<CapabilityDefinition>, StorageOperationStatus> deleteCapability(Component storedComponent,
+                                                                                        Map<String, List<CapabilityDefinition>> storedComponentCapabilities,
+                                                                                        CapabilityDefinition capabilityDefinitionToDelete) {
+
+        List<CapabilityDefinition> capabilitiesListStoredInComponent =
+                getCapabilityStoredInComponentByType(capabilityDefinitionToDelete.getType(), storedComponentCapabilities);
         capabilitiesListStoredInComponent.removeIf(capabilityDefinition ->
                 capabilityDefinition.getUniqueId().equals(capabilityDefinitionToDelete.getUniqueId()));
         Either<List<CapabilityDefinition>, StorageOperationStatus> result;
@@ -461,34 +496,35 @@ public class CapabilitiesBusinessLogic extends BaseBusinessLogic {
             result = capabilitiesOperation.updateCapabilities(storedComponent.getUniqueId(),
                     capabilitiesListStoredInComponent);
         }
+        if (result.isLeft()) {
+            StorageOperationStatus deleteStorageOperationStatus = capabilitiesOperation
+                    .deleteCapabilityProperties(storedComponent, buildCapPropKey(capabilityDefinitionToDelete));
+            if (deleteStorageOperationStatus != StorageOperationStatus.OK) {
+                result = Either.right(deleteStorageOperationStatus);
+            }
+        }
         return result;
     }
 
 
-    private Either<org.openecomp.sdc.be.model.Component, ResponseFormat> getComponentDetails(
-            String componentId) {
+    private Either<Component, ResponseFormat> getComponentDetails(String componentId) {
         ComponentParametersView filter = new ComponentParametersView(true);
         filter.setIgnoreCapabilities(false);
         filter.setIgnoreCapabiltyProperties(false);
-        Either<org.openecomp.sdc.be.model.Component, StorageOperationStatus>
-                componentStorageOperationStatusEither = toscaOperationFacade
-                .getToscaElement(componentId, filter);
+        Either<Component, StorageOperationStatus> componentStorageOperationStatusEither =
+                toscaOperationFacade.getToscaElement(componentId, filter);
         if (componentStorageOperationStatusEither.isRight()) {
             StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
             LOGGER.error("Failed to fetch component information by component id {}, Response is {}",
                     componentId, errorStatus);
-            return Either.right(componentsUtils.getResponseFormat(componentsUtils
-                    .convertFromStorageResponse(errorStatus)));
+            return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
         }
         return Either.left(componentStorageOperationStatusEither.left().value());
     }
 
-    private Either<Boolean, ResponseFormat> lockComponentResult(
-            boolean lock, org.openecomp.sdc.be.model.Component component,
-            String action) {
+    private Either<Boolean, ResponseFormat> lockComponentResult(boolean lock, Component component, String action) {
         if (lock) {
-            Either<Boolean, ResponseFormat> lockResult = lockComponent(component.getUniqueId(),
-                    component, action);
+            Either<Boolean, ResponseFormat> lockResult = lockComponent(component.getUniqueId(), component, action);
             if (lockResult.isRight()) {
                 LOGGER.debug(FAILED_TO_LOCK_COMPONENT_RESPONSE_IS, component.getName(),
                         lockResult.right().value().getFormattedMessage());
@@ -499,19 +535,14 @@ public class CapabilitiesBusinessLogic extends BaseBusinessLogic {
         return Either.left(true);
     }
 
-    private List<CapabilityDefinition> getCapabilityStoredInComponentByType(
-            String capabilityType, Map<String,
+    private List<CapabilityDefinition> getCapabilityStoredInComponentByType(String capabilityType, Map<String,
             List<CapabilityDefinition>> capabilities) {
-        Optional<Map.Entry<String, List<CapabilityDefinition>>> entryOptional
-                = capabilities.entrySet().stream().
-                filter(map -> map.getKey().equals(capabilityType)).findFirst();
-        return entryOptional.map(Map.Entry::getValue).orElse(null);
-
+        Optional<Map.Entry<String, List<CapabilityDefinition>>> entryOptional = capabilities.entrySet().stream()
+                .filter(map -> map.getKey().equals(capabilityType)).findFirst();
+        return entryOptional.map(Map.Entry::getValue).orElse(Collections.emptyList());
     }
 
-    private CapabilityDefinition initiateNewCapability(
-            org.openecomp.sdc.be.model.Component component,
-            CapabilityDefinition capabilityDefinition) {
+    private CapabilityDefinition initiateNewCapability(Component component, CapabilityDefinition capabilityDefinition) {
         if (StringUtils.isEmpty(capabilityDefinition.getUniqueId()))
             capabilityDefinition.setUniqueId(UUID.randomUUID().toString());
         if (StringUtils.isEmpty(capabilityDefinition.getOwnerId()))
@@ -519,36 +550,58 @@ public class CapabilitiesBusinessLogic extends BaseBusinessLogic {
         if (StringUtils.isEmpty(capabilityDefinition.getOwnerName()))
             capabilityDefinition.setOwnerName(component.getName());
         capabilityDefinition.setLeftOccurrences(capabilityDefinition.getMaxOccurrences());
+        List<ComponentInstanceProperty> capabilityProperties = capabilityDefinition.getProperties();
+        initiateProperties(capabilityDefinition, capabilityProperties);
         return capabilityDefinition;
     }
 
+    private void initiateProperties(CapabilityDefinition capabilityDefinition,
+                                    List<ComponentInstanceProperty> capabilityProperties) {
+        if (CollectionUtils.isNotEmpty(capabilityProperties)) {
+            capabilityProperties.stream().filter(prop -> prop != null && StringUtils.isEmpty(prop.getUniqueId()))
+                    .forEach(propDef -> {
+                        String uid = UniqueIdBuilder.buildRequirementUid(capabilityDefinition.getUniqueId(), propDef.getName());
+                        propDef.setUniqueId(uid);
+                        propDef.setParentUniqueId(capabilityDefinition.getUniqueId());
+                    });
+        }
+    }
+
     private CapabilityDefinition updateCapability(CapabilityDefinition storedCapability,
-                                                  CapabilityDefinition capabilityToUpdate) {
+                                                  CapabilityDefinition capabilityToUpdate, Component component) {
         storedCapability.setName(capabilityToUpdate.getName());
         storedCapability.setDescription(capabilityToUpdate.getDescription());
         storedCapability.setType(capabilityToUpdate.getType());
         storedCapability.setValidSourceTypes(capabilityToUpdate.getValidSourceTypes());
         storedCapability.setMinOccurrences(capabilityToUpdate.getMinOccurrences());
         storedCapability.setMaxOccurrences(capabilityToUpdate.getMaxOccurrences());
+        if (!storedCapability.getType().equals(capabilityToUpdate.getType())) {
+            List<ComponentInstanceProperty> capabilityProperties = capabilityToUpdate.getProperties();
+            initiateProperties(capabilityToUpdate, capabilityProperties);
+            storedCapability.setProperties(capabilityToUpdate.getProperties());
+        }
+        if (!storedCapability.getName().equals(capabilityToUpdate.getName())) {
+            StorageOperationStatus deleteStorageOperationStatus = capabilitiesOperation
+                    .deleteCapabilityProperties(component, buildCapPropKey(storedCapability));
+            if (deleteStorageOperationStatus != StorageOperationStatus.OK) {
+                titanDao.rollback();
+            }
+        }
 
         return storedCapability;
     }
 
 
-    private Boolean isCapabilityUsedInServiceComposition(
-            CapabilityDefinition capabilityDefinition,
-            org.openecomp.sdc.be.model.Component component) {
-        Either<List<org.openecomp.sdc.be.model.Component>, StorageOperationStatus>
-                componentList = toscaOperationFacade
+    private Boolean isCapabilityUsedInServiceComposition(CapabilityDefinition capabilityDefinition, Component component) {
+        Either<List<Component>, StorageOperationStatus> componentList = toscaOperationFacade
                 .getParentComponents(component.getUniqueId());
         if (componentList.isRight()) {
             return Boolean.FALSE;
         }
         return componentList.left().value().stream().flatMap(parentComponent -> parentComponent
-                .getComponentInstancesRelations().stream())
-                .flatMap(requirementCapabilityRelDef -> requirementCapabilityRelDef.getRelationships().stream())
-                .anyMatch(capabilityRequirementRelationship -> capabilityRequirementRelationship
-                        .getRelation().getCapabilityUid().equals(capabilityDefinition.getUniqueId()));
+                .getComponentInstancesRelations().stream()).flatMap(requirementCapabilityRelDef ->
+                requirementCapabilityRelDef.getRelationships().stream()).anyMatch(capabilityRequirementRelationship ->
+                capabilityRequirementRelationship.getRelation().getCapabilityUid().equals(capabilityDefinition.getUniqueId()));
     }
 
     public Either<Map<String, CapabilityTypeDefinition>, ResponseFormat> getAllCapabilityTypes() {
@@ -557,17 +610,38 @@ public class CapabilitiesBusinessLogic extends BaseBusinessLogic {
         if (capabilityTypeCacheAll.isRight()) {
             TitanOperationStatus operationStatus = capabilityTypeCacheAll.right().value();
             if (TitanOperationStatus.NOT_FOUND == operationStatus) {
-                BeEcompErrorManager.getInstance().logInternalDataError("FetchCapabilityTypes", "Capability types are "
-                                + "not loaded",
-                        BeEcompErrorManager.ErrorSeverity.ERROR);
+                BeEcompErrorManager.getInstance().logInternalDataError("FetchCapabilityTypes",
+                        "Capability types are not loaded", BeEcompErrorManager.ErrorSeverity.ERROR);
                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.DATA_TYPE_CANNOT_BE_EMPTY));
             } else {
-                BeEcompErrorManager.getInstance().logInternalFlowError("FetchCapabilityTypes", "Failed to fetch capability "
-                                + "types",
-                        BeEcompErrorManager.ErrorSeverity.ERROR);
+                BeEcompErrorManager.getInstance().logInternalFlowError("FetchCapabilityTypes",
+                        "Failed to fetch capability types", BeEcompErrorManager.ErrorSeverity.ERROR);
                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
             }
         }
         return Either.left(capabilityTypeCacheAll.left().value());
     }
+
+    private Map<String, MapPropertiesDataDefinition> getCapabilitiesPropertiesDataDefinitionMap(
+            List<CapabilityDefinition> capabilityDefinitions) {
+        CapabilityDefinition capabilityDefinitionToAddOrUpdateCapProp = capabilityDefinitions.get(0);
+        List<ComponentInstanceProperty> componentInstanceProperties = null;
+        if (Objects.nonNull(capabilityDefinitionToAddOrUpdateCapProp)) {
+            componentInstanceProperties = capabilityDefinitionToAddOrUpdateCapProp.getProperties();
+        }
+        Map<String, MapPropertiesDataDefinition> propertiesMap = new HashMap<>();
+        if (CollectionUtils.isNotEmpty(componentInstanceProperties)) {
+            MapPropertiesDataDefinition dataToCreate = new MapPropertiesDataDefinition();
+            for (ComponentInstanceProperty cip : componentInstanceProperties) {
+                dataToCreate.put(cip.getName(), new PropertyDataDefinition(cip));
+            }
+            propertiesMap.put(buildCapPropKey(capabilityDefinitionToAddOrUpdateCapProp), dataToCreate);
+        }
+        return propertiesMap;
+    }
+
+    private String buildCapPropKey(CapabilityDefinition capabilityDefinitionToAddOrUpdateCapProp) {
+        return capabilityDefinitionToAddOrUpdateCapProp.getType() + ModelConverter.CAP_PROP_DELIM +
+                capabilityDefinitionToAddOrUpdateCapProp.getName();
+    }
 }
index 3bae240..71b1257 100644 (file)
 
 package org.openecomp.sdc.be.components.impl;
 
-import static org.openecomp.sdc.be.components.property.GetInputUtils.isGetInputValueForInput;
-
 import com.google.common.collect.Sets;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.UUID;
-import java.util.function.BiConsumer;
-import java.util.stream.Collectors;
-
 import fj.data.Either;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
@@ -49,7 +30,7 @@ import org.openecomp.sdc.be.components.impl.instance.ComponentInstanceChangeOper
 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.utils.PropertiesUtils;
 import org.openecomp.sdc.be.components.validation.ComponentValidations;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
@@ -86,6 +67,7 @@ import org.openecomp.sdc.be.model.GroupDefinition;
 import org.openecomp.sdc.be.model.InputDefinition;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.LifecycleStateEnum;
+import org.openecomp.sdc.be.model.PolicyDefinition;
 import org.openecomp.sdc.be.model.PropertyDefinition;
 import org.openecomp.sdc.be.model.PropertyDefinition.PropertyNames;
 import org.openecomp.sdc.be.model.RelationshipInfo;
@@ -94,23 +76,6 @@ import org.openecomp.sdc.be.model.RequirementDefinition;
 import org.openecomp.sdc.be.model.Resource;
 import org.openecomp.sdc.be.model.Service;
 import org.openecomp.sdc.be.model.User;
-import org.openecomp.sdc.be.model.ComponentInstancePropInput;
-import org.openecomp.sdc.be.model.LifecycleStateEnum;
-import org.openecomp.sdc.be.model.ArtifactDefinition;
-import org.openecomp.sdc.be.model.DataTypeDefinition;
-import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.GroupDefinition;
-import org.openecomp.sdc.be.model.InputDefinition;
-import org.openecomp.sdc.be.model.InterfaceDefinition;
-import org.openecomp.sdc.be.model.LifecycleStateEnum;
-import org.openecomp.sdc.be.model.PolicyDefinition;
-import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.PropertyDefinition.PropertyNames;
-import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
-import org.openecomp.sdc.be.model.ComponentInstance;
-import org.openecomp.sdc.be.model.ComponentInstanceInput;
-import org.openecomp.sdc.be.model.ComponentInstanceProperty;
-import org.openecomp.sdc.be.model.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;
@@ -133,6 +98,25 @@ import org.openecomp.sdc.common.util.ValidationUtils;
 import org.openecomp.sdc.exception.ResponseFormat;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.UUID;
+import java.util.function.BiConsumer;
+import java.util.stream.Collectors;
+
+import static org.openecomp.sdc.be.components.property.GetInputUtils.isGetInputValueForInput;
+import static org.openecomp.sdc.be.components.utils.PropertiesUtils.getPropertyCapabilityOfChildInstance;
+
 @org.springframework.stereotype.Component
 public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
 
@@ -417,7 +401,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         }
 
 
-        resourceInstance.setProperties(ProxyServicePropertiesUtils.getProperties(service));
+        resourceInstance.setProperties(PropertiesUtils.getProperties(service));
 
         List<InputDefinition> serviceInputs = service.getInputs();
         resourceInstance.setInputs(serviceInputs);
@@ -1789,9 +1773,20 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
 
         try {
             for (ComponentInstanceProperty property: properties) {
+                String propertyParentUniqueId = property.getParentUniqueId();
                 Either<String, ResponseFormat> updatedPropertyValue = updatePropertyObjectValue(property, false);
-                updatedPropertyValue.bimap(updatedValue -> updatePropertyOnContainerComponent(property,updatedValue, containerComponent, foundResourceInstance),
-                        responseFormat -> Either.right(responseFormat));
+                Optional<CapabilityDefinition>
+                        capPropDefinition = getPropertyCapabilityOfChildInstance(propertyParentUniqueId, foundResourceInstance.getCapabilities());
+                if(capPropDefinition.isPresent()) {
+                    updatedPropertyValue
+                            .bimap(updatedValue -> updateCapabilityPropFromUpdateInstProp(property, updatedValue,
+                                    containerComponent, foundResourceInstance, capPropDefinition.get().getType(),
+                                    capPropDefinition.get().getName()), Either::right);
+                }
+                else {
+                    updatedPropertyValue.bimap(updatedValue -> updatePropertyOnContainerComponent(property, updatedValue,
+                            containerComponent, foundResourceInstance), Either::right);
+                }
             }
 
             Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade.updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
@@ -1814,21 +1809,71 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         }
     }
 
-    private ResponseFormat updateCapabilityPropertyOnContainerComponent(ComponentInstanceProperty property, String newValue, Component containerComponent, ComponentInstance foundResourceInstance,
+    private ResponseFormat updateCapabilityPropertyOnContainerComponent(ComponentInstanceProperty property,
+                                                                        String newValue, Component containerComponent, ComponentInstance foundResourceInstance,
                                                                         String capabilityType, String capabilityName) {
         String componentInstanceUniqueId = foundResourceInstance.getUniqueId();
-        StringBuilder sb = new StringBuilder(componentInstanceUniqueId);
-        sb.append(ModelConverter.CAP_PROP_DELIM).append(property.getOwnerId()).append(ModelConverter.CAP_PROP_DELIM).append(capabilityType).append(ModelConverter.CAP_PROP_DELIM).append(capabilityName);
+        StringBuffer sb = new StringBuffer(componentInstanceUniqueId);
+        sb.append(ModelConverter.CAP_PROP_DELIM).append(property.getOwnerId()).append(ModelConverter.CAP_PROP_DELIM)
+                .append(capabilityType).append(ModelConverter.CAP_PROP_DELIM).append(capabilityName);
         String capKey = sb.toString();
 
-        Map<String, List<CapabilityDefinition>> capabilities = Optional.ofNullable(foundResourceInstance.getCapabilities())
-                .orElse(Collections.emptyMap());
-        List<CapabilityDefinition> capPerType = Optional.ofNullable(capabilities.get(capabilityType)).orElse(Collections.emptyList());
-        Optional<CapabilityDefinition> cap = capPerType.stream().filter(c -> c.getName().equals(capabilityName)).findAny();
+        ResponseFormat actionStatus = updateCapPropOnContainerComponent(property, newValue, containerComponent,
+                foundResourceInstance, capabilityType, capabilityName, componentInstanceUniqueId, capKey);
+        if (actionStatus != null) {
+            return actionStatus;
+        }
+
+        return componentsUtils.getResponseFormat(ActionStatus.OK);
+    }
+
+    private ResponseFormat updateCapabilityPropFromUpdateInstProp(ComponentInstanceProperty property,
+                                                                  String newValue, Component containerComponent,
+                                                                  ComponentInstance foundResourceInstance,
+                                                                  String capabilityType, String capabilityName) {
+        String componentInstanceUniqueId = foundResourceInstance.getUniqueId();
+        Either<Component, StorageOperationStatus> getComponentRes =
+                toscaOperationFacade.getToscaFullElement(foundResourceInstance.getComponentUid());
+        if(getComponentRes.isRight()) {
+            return componentsUtils.getResponseFormat(getComponentRes.right().value());
+        }
+        String propOwner;
+        if(!PropertiesUtils.isNodeServiceProxy(getComponentRes.left().value())) {
+            propOwner = componentInstanceUniqueId;
+        } else {
+            propOwner = foundResourceInstance.getSourceModelUid();
+        }
+        StringBuffer sb = new StringBuffer(componentInstanceUniqueId);
+
+        sb.append(ModelConverter.CAP_PROP_DELIM).append(propOwner).append(ModelConverter.CAP_PROP_DELIM)
+                .append(capabilityType).append(ModelConverter.CAP_PROP_DELIM).append(capabilityName);
+        String capKey = sb.toString();
+
+        ResponseFormat actionStatus = updateCapPropOnContainerComponent(property, newValue, containerComponent,
+                foundResourceInstance, capabilityType, capabilityName, componentInstanceUniqueId, capKey);
+        if (actionStatus != null) {
+            return actionStatus;
+        }
+
+        return componentsUtils.getResponseFormat(ActionStatus.OK);
+    }
+
+    private ResponseFormat updateCapPropOnContainerComponent(ComponentInstanceProperty property, String newValue,
+                                                             Component containerComponent,
+                                                             ComponentInstance foundResourceInstance,
+                                                             String capabilityType, String capabilityName,
+                                                             String componentInstanceUniqueId, String capKey) {
+        Map<String, List<CapabilityDefinition>> capabilities =
+                Optional.ofNullable(foundResourceInstance.getCapabilities()).orElse(Collections.emptyMap());
+        List<CapabilityDefinition> capPerType =
+                Optional.ofNullable(capabilities.get(capabilityType)).orElse(Collections.EMPTY_LIST);
+        Optional<CapabilityDefinition> cap =
+                capPerType.stream().filter(c -> c.getName().equals(capabilityName)).findAny();
         if (cap.isPresent()) {
             List<ComponentInstanceProperty> capProperties = cap.get().getProperties();
             if (capProperties != null) {
-                Optional<ComponentInstanceProperty> instanceProperty = capProperties.stream().filter(p -> p.getUniqueId().equals(property.getUniqueId())).findAny();
+                Optional<ComponentInstanceProperty> instanceProperty =
+                        capProperties.stream().filter(p -> p.getUniqueId().equals(property.getUniqueId())).findAny();
                 StorageOperationStatus status;
                 if (instanceProperty.isPresent()) {
                     instanceProperty.get().setValue(newValue);
@@ -1836,9 +1881,11 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
                     path.add(componentInstanceUniqueId);
                     path.add(capKey);
                     instanceProperty.get().setPath(path);
-                    status = toscaOperationFacade.updateComponentInstanceCapabiltyProperty(containerComponent, componentInstanceUniqueId, capKey, instanceProperty.get());
+                    status = toscaOperationFacade.updateComponentInstanceCapabiltyProperty(containerComponent,
+                            componentInstanceUniqueId, capKey, instanceProperty.get());
                     if (status != StorageOperationStatus.OK) {
-                        ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
+                        ActionStatus actionStatus =
+                                componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
                         return componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "");
 
                     }
@@ -1846,20 +1893,25 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
                 }
             }
         }
-
-
-        return componentsUtils.getResponseFormat(ActionStatus.OK);
+        return null;
     }
 
-    private ResponseFormat updatePropertyOnContainerComponent(ComponentInstanceProperty property, String newValue, Component containerComponent, ComponentInstance foundResourceInstance) {
-        List<ComponentInstanceProperty> instanceProperties = containerComponent.getComponentInstancesProperties().get(foundResourceInstance.getUniqueId());
-        Optional<ComponentInstanceProperty> instanceProperty = instanceProperties.stream().filter(p -> p.getUniqueId().equals(property.getUniqueId())).findAny();
+    private ResponseFormat updatePropertyOnContainerComponent(ComponentInstanceProperty property, String newValue,
+                                                              Component containerComponent, ComponentInstance foundResourceInstance) {
+        List<ComponentInstanceProperty> instanceProperties =
+                containerComponent.getComponentInstancesProperties().get(foundResourceInstance.getUniqueId());
+        Optional<ComponentInstanceProperty> instanceProperty =
+                instanceProperties.stream().filter(p -> p.getUniqueId().equals(property.getUniqueId())).findAny();
         StorageOperationStatus status;
         instanceProperty.get().setValue(newValue);
         if (instanceProperty.isPresent()) {
-            status = toscaOperationFacade.updateComponentInstanceProperty(containerComponent, foundResourceInstance.getUniqueId(), property);
+            status = toscaOperationFacade
+                    .updateComponentInstanceProperty(containerComponent, foundResourceInstance.getUniqueId(),
+                            property);
         } else {
-            status = toscaOperationFacade.addComponentInstanceProperty(containerComponent, foundResourceInstance.getUniqueId(), property);
+            status = toscaOperationFacade
+                    .addComponentInstanceProperty(containerComponent, foundResourceInstance.getUniqueId(),
+                            property);
         }
         if (status != StorageOperationStatus.OK) {
             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
index de2839f..5cdaa6a 100644 (file)
 
 package org.openecomp.sdc.be.components.impl;
 
+import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.createMappedCapabilityPropertyDefaultValue;
 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.createMappedInputPropertyDefaultValue;
 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.createMappedOutputDefaultValue;
 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getInterfaceDefinitionFromComponentByInterfaceId;
 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getInterfaceDefinitionFromComponentByInterfaceType;
 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getOperationFromInterfaceDefinition;
 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToComponentInput;
+import static org.openecomp.sdc.be.components.utils.PropertiesUtils.getPropertyCapabilityFromAllCapProps;
+import static org.openecomp.sdc.be.components.utils.PropertiesUtils.isCapabilityProperty;
 import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.SELF;
 
 import com.google.gson.Gson;
@@ -51,7 +54,9 @@ import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.ArtifactDefinition;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
 import org.openecomp.sdc.be.model.InputDefinition;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.Operation;
@@ -459,11 +464,28 @@ public class InterfaceOperationBusinessLogic extends BaseBusinessLogic {
 
     private String getInputToscaDefaultValue(OperationInputDefinition input,
                                              org.openecomp.sdc.be.model.Component component) {
-        Map<String, List<String>> defaultInputValue;
+        Map<String, List<String>> defaultInputValue = null;
         if (isOperationInputMappedToComponentInput(input, component.getInputs())) {
             String propertyName = input.getInputId().substring(input.getInputId().indexOf('.') + 1);
                        setParentPropertyTypeAndInputPath(input, component);
             defaultInputValue = createMappedInputPropertyDefaultValue(propertyName);
+        } else if (isCapabilityProperty(input.getInputId(), component).isPresent()) {
+            ComponentInstanceProperty instanceProperty = isCapabilityProperty(input.getInputId(), component).get();
+            String parentPropertyId = instanceProperty.getParentUniqueId();
+            Map<String, List<CapabilityDefinition>> componentCapabilities = component.getCapabilities();
+            if(MapUtils.isNotEmpty(componentCapabilities)) {
+                List<CapabilityDefinition> capabilityDefinitionList = componentCapabilities.values().stream()
+                        .flatMap(Collection::stream).filter(capabilityDefinition -> capabilityDefinition.getOwnerId()
+                                .equals(component.getUniqueId())).collect(Collectors.toList());
+                Optional<CapabilityDefinition> propertyCapability = getPropertyCapabilityFromAllCapProps(parentPropertyId,
+                        capabilityDefinitionList);
+                if (propertyCapability.isPresent()) {
+                    String propertyName = instanceProperty.getName();
+                    defaultInputValue = createMappedCapabilityPropertyDefaultValue(propertyCapability.get().getName(),
+                            propertyName);
+                }
+            }
+
         } else {
             //Currently inputs can only be mapped to a declared input or an other operation outputs
             defaultInputValue = createMappedOutputDefaultValue(SELF, input.getInputId());
index d1bfcc8..a586e23 100644 (file)
@@ -22,6 +22,8 @@ package org.openecomp.sdc.be.components.impl;
 
 import static org.apache.commons.collections.CollectionUtils.isEmpty;
 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
+import static org.openecomp.sdc.be.components.utils.ConsumptionUtils.handleConsumptionInputMappedToCapabilityProperty;
+import static org.openecomp.sdc.be.components.utils.ConsumptionUtils.isAssignedValueFromValidType;
 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getOperationOutputName;
 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToOtherOperationOutput;
 import static org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum.UPDATE_SERVICE_METADATA;
@@ -64,6 +66,7 @@ import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
 import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
 import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
+import org.openecomp.sdc.be.components.utils.PropertiesUtils;
 import org.openecomp.sdc.be.components.validation.NodeFilterValidator;
 import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
@@ -91,6 +94,7 @@ import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributi
 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
 import org.openecomp.sdc.be.model.ArtifactDefinition;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.ComponentInstance;
 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
@@ -118,8 +122,6 @@ import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
 import org.openecomp.sdc.be.model.tosca.ToscaFunctions;
-import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
-import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
@@ -475,12 +477,20 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         ServiceConsumptionSource sourceValue = ServiceConsumptionSource.getSourceValue(source);
 
         if(STATIC.equals(sourceValue)) {
+            // Validate constraint on input value
+            Either<Boolean, ResponseFormat> constraintValidationResult =
+                    validateOperationInputConstraint(operationInputDefinition, consumptionValue, type);
+
+            if (constraintValidationResult.isRight()) {
+                return Either.right(constraintValidationResult.right().value());
+            }
             return handleConsumptionStaticValue(consumptionValue, type, operation,
                     operationInputDefinition);
         }
 
         if (Objects.isNull(sourceValue)) {
             List<PropertyDefinition> propertyDefinitions;
+            Map<String, List<CapabilityDefinition>> capabilities = null;
             String componentName;
             List<OperationOutputDefinition> outputs = null;
             if (source.equals(containerService.getUniqueId())) {
@@ -505,6 +515,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
                 ComponentInstance componentInstance = getComponentInstance.get();
                 operationInputDefinition.setSource(componentInstance.getUniqueId());
                 propertyDefinitions = componentInstance.getProperties();
+                capabilities = componentInstance.getCapabilities();
                 componentName = source.equals(serviceInstanceId) ? SELF : componentInstance.getName();
                 if (MapUtils.isNotEmpty(componentInstance.getInterfaces())) {
                     Map<String, InterfaceDataDefinition> componentInstanceInterfaces =
@@ -522,7 +533,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
                         operationInputDefinition);
             }
             return handleConsumptionPropertyValue(operation, operationInputDefinition,
-                    serviceConsumptionData, propertyDefinitions, outputs, consumptionValue, componentName);
+                    serviceConsumptionData, propertyDefinitions, capabilities, outputs, componentName);
         }
 
         operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.SOURCE, source);
@@ -545,12 +556,14 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
 
     private Either<Operation, ResponseFormat> handleConsumptionPropertyValue(
             Operation operation, OperationInputDefinition operationInputDefinition,
-            ServiceConsumptionData serviceConsumptionData, List<PropertyDefinition> properties,
-            List<OperationOutputDefinition> outputs, String consumptionValue, String componentName) {
+            ServiceConsumptionData serviceConsumptionData, List<PropertyDefinition> properties,Map<String,
+            List<CapabilityDefinition>> capabilities,
+            List<OperationOutputDefinition> outputs,  String componentName) {
 
         if (CollectionUtils.isEmpty(properties) && CollectionUtils.isEmpty(outputs)) {
             return Either.left(operation);
         }
+        String consumptionValue = serviceConsumptionData.getValue();
 
         if (CollectionUtils.isNotEmpty(outputs)
                 && isOperationInputMappedToOtherOperationOutput(getOperationOutputName(consumptionValue), outputs)) {
@@ -558,10 +571,16 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
                     consumptionValue, componentName);
         }
 
-        if (CollectionUtils.isNotEmpty(properties)) {
+        if (CollectionUtils.isNotEmpty(properties) && PropertiesUtils.isNodeProperty(consumptionValue, properties)) {
             return handleConsumptionInputMappedToProperty(operation, operationInputDefinition, serviceConsumptionData,
                     properties, componentName);
         }
+
+        if (MapUtils.isNotEmpty(capabilities)) {
+            return handleConsumptionInputMappedToCapabilityProperty(operation, operationInputDefinition,
+                    serviceConsumptionData, capabilities, componentName);
+        }
+
         return Either.left(operation);
     }
 
@@ -672,7 +691,9 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
 
                        ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
                        propertyDefinition.setType(operationInputDefinition.getParentPropertyType());
-                       inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
+            if (operationInputDefinition.getParentPropertyType() != null) {
+                inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
+            }
 
                        return PropertyValueConstraintValidationUtil.getInstance()
                                        .validatePropertyConstraints(Collections.singletonList(inputDefinition), applicationDataTypeCache);
@@ -719,25 +740,6 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         return Either.left(operation);
     }
 
-
-    private boolean isAssignedValueFromValidType(String operationInputType, Object actualValue) {
-        if (actualValue instanceof String) {
-            // validate static value
-            ToscaPropertyType actualType = ToscaPropertyType.isValidType(operationInputType);
-            PropertyTypeValidator validator = actualType.getValidator();
-            return validator.isValid((String)actualValue, operationInputType);
-        } else if (actualValue instanceof PropertyDefinition) {
-            // validate input / property value
-            String actualType = ((PropertyDefinition) actualValue).getType();
-            return actualType.equalsIgnoreCase(operationInputType);
-        } else if (actualValue instanceof OperationOutputDefinition) {
-            // validate input / output value
-            String actualType = ((OperationOutputDefinition) actualValue).getType();
-            return actualType.equalsIgnoreCase(operationInputType);
-        }
-        return false;
-    }
-
     private void addGetInputValueToOperationInput(Operation operation,
                                                   OperationInputDefinition operationInputDefinition,
                                                   InputDefinition inputForValue) {
index 2ca6ca4..e9289de 100644 (file)
@@ -194,7 +194,7 @@ public class CertificationChangeTransition extends LifeCycleTransition {
                 }
             }
             updateCalculatedCapabilitiesRequirements(componentAfterCertification);
-            updateCapReqOwnerId(componentAfterCertification);
+            updateCapReqPropertiesOwnerId(componentAfterCertification);
             result = Either.left(componentAfterCertification);
             return result;
         } finally {
@@ -214,9 +214,9 @@ public class CertificationChangeTransition extends LifeCycleTransition {
 
     }
 
-    private void updateCapReqOwnerId(Component component) {
+    private void updateCapReqPropertiesOwnerId(Component component) {
         if(component.isTopologyTemplate() && ToscaUtils.isNotComplexVfc(component)) {
-            toscaOperationFacade.updateCapReqOwnerId(component.getUniqueId());
+            toscaOperationFacade.updateCapReqPropertiesOwnerId(component.getUniqueId());
         }
     }
 
index 0c44642..33b6250 100644 (file)
@@ -123,7 +123,7 @@ public class CheckoutTransition extends LifeCycleTransition {
                     }
                 }
                 handleCalculatedCapabilitiesRequirements(clonedComponent);
-               updateCapReqOwnerId(clonedComponent);
+               updateCapReqPropertiesOwnerId(clonedComponent);
             }
 
         } finally {
@@ -149,9 +149,9 @@ public class CheckoutTransition extends LifeCycleTransition {
         }
     }
 
-    private void updateCapReqOwnerId(Component component) {
+    private void updateCapReqPropertiesOwnerId(Component component) {
         if(component.isTopologyTemplate() && ToscaUtils.isNotComplexVfc(component)) {
-            toscaOperationFacade.updateCapReqOwnerId(component.getUniqueId());
+            toscaOperationFacade.updateCapReqPropertiesOwnerId(component.getUniqueId());
         }
     }
     private StorageOperationStatus upgradeToLatestGenericData(Component clonedComponent) {
index c716e24..21f26a3 100644 (file)
@@ -8,8 +8,10 @@ import java.util.Map;
 import java.util.Optional;
 import org.apache.commons.collections.CollectionUtils;
 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
+import org.openecomp.sdc.be.components.utils.PropertiesUtils;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.impl.ComponentsUtils;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.ComponentInstance;
 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
@@ -62,12 +64,35 @@ public class ComponentInstancePropertyDeclarator extends DefaultPropertyDeclarat
 
     @Override
     public StorageOperationStatus unDeclarePropertiesAsInputs(Component component, InputDefinition input) {
-        List<ComponentInstanceProperty> componentInstancePropertiesDeclaredAsInput = componentInstanceBusinessLogic.getComponentInstancePropertiesByInputId(component, input.getUniqueId());
-        if (CollectionUtils.isEmpty(componentInstancePropertiesDeclaredAsInput)) {
-            return StorageOperationStatus.OK;
+
+        Optional<ComponentInstanceProperty> propertyByInputId = PropertiesUtils.getPropertyByInputId(component,
+                input.getUniqueId());
+        if(propertyByInputId.isPresent()) {
+            List<ComponentInstanceProperty> capabilityPropertyDeclaredAsInput =
+                   PropertiesUtils.getCapabilityProperty(propertyByInputId.get(), input.getUniqueId());
+            capabilityPropertyDeclaredAsInput.forEach(cmptInstanceProperty -> prepareValueBeforeDeleteOfCapProp(input,
+                    cmptInstanceProperty));
+
+            Optional<CapabilityDefinition> propertyCapabilityOptional = PropertiesUtils.getPropertyCapabilityOfChildInstance(
+                    capabilityPropertyDeclaredAsInput.get(0).getParentUniqueId(), component.getCapabilities());
+            if(!propertyCapabilityOptional.isPresent()) {
+                return StorageOperationStatus.OK;
+            }
+
+            return toscaOperationFacade.updateInstanceCapabilityProperty(component, input.getInstanceUniqueId(),
+                    capabilityPropertyDeclaredAsInput.get(0), propertyCapabilityOptional.get() );
+        } else {
+            List<ComponentInstanceProperty> componentInstancePropertiesDeclaredAsInput = componentInstanceBusinessLogic
+                    .getComponentInstancePropertiesByInputId(component, input.getUniqueId());
+            if (CollectionUtils.isEmpty(componentInstancePropertiesDeclaredAsInput)) {
+                return StorageOperationStatus.OK;
+            }
+            componentInstancePropertiesDeclaredAsInput.forEach(cmptInstanceProperty -> prepareValueBeforeDelete(input,
+                    cmptInstanceProperty, cmptInstanceProperty.getPath()));
+            return toscaOperationFacade.updateComponentInstanceProperties(component,
+                    componentInstancePropertiesDeclaredAsInput.get(0).getComponentInstanceId(),
+                    componentInstancePropertiesDeclaredAsInput);
         }
-        componentInstancePropertiesDeclaredAsInput.forEach(cmptInstanceProperty -> prepareValueBeforeDelete(input, cmptInstanceProperty, cmptInstanceProperty.getPath()));
-        return toscaOperationFacade.updateComponentInstanceProperties(component, componentInstancePropertiesDeclaredAsInput.get(0).getComponentInstanceId(), componentInstancePropertiesDeclaredAsInput);
     }
 
 }
index 02b261b..b6736fd 100644 (file)
@@ -18,12 +18,14 @@ import java.util.stream.Collectors;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.json.simple.JSONObject;
+import org.openecomp.sdc.be.components.utils.PropertiesUtils;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.GetPolicyValueDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertiesOwner;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.impl.ComponentsUtils;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.ComponentInstancePropInput;
 import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement;
@@ -42,6 +44,7 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties
 
     private static final Logger log = Logger.getLogger(DefaultPropertyDeclarator.class);
     private static final short LOOP_PROTECTION_LEVEL = 10;
+    private static final String UNDERSCORE = "_";
     private final Gson gson = new Gson();
     private ComponentsUtils componentsUtils;
     private PropertyOperation propertyOperation;
@@ -95,7 +98,7 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties
     }
 
     private Either<List<InputDefinition>, StorageOperationStatus> declarePropertiesAsInputs(Component component, PROPERTYOWNER propertiesOwner, List<ComponentInstancePropInput> propsToDeclare) {
-        PropertiesDeclarationData inputsProperties = createInputsAndOverridePropertiesValues(component.getUniqueId(), propertiesOwner, propsToDeclare);
+        PropertiesDeclarationData inputsProperties = createInputsAndOverridePropertiesValues(component, propertiesOwner, propsToDeclare);
         return updatePropertiesValues(component, propertiesOwner.getUniqueId(), inputsProperties.getPropertiesToUpdate())
                 .left()
                 .map(updatePropsRes -> inputsProperties.getInputsToCreate());
@@ -155,17 +158,17 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties
     }
 
 
-    private PropertiesDeclarationData createInputsAndOverridePropertiesValues(String componentId, PROPERTYOWNER propertiesOwner, List<ComponentInstancePropInput> propsToDeclare) {
+    private PropertiesDeclarationData createInputsAndOverridePropertiesValues(Component component, PROPERTYOWNER propertiesOwner, List<ComponentInstancePropInput> propsToDeclare) {
         List<PROPERTYTYPE> declaredProperties = new ArrayList<>();
         List<InputDefinition> createdInputs = propsToDeclare.stream()
-                .map(propInput -> declarePropertyInput(componentId, propertiesOwner, declaredProperties, propInput))
+                .map(propInput -> declarePropertyInput(component, propertiesOwner, declaredProperties, propInput))
                 .collect(Collectors.toList());
         return new PropertiesDeclarationData(createdInputs, null, declaredProperties);
     }
 
-    private InputDefinition declarePropertyInput(String componentId, PROPERTYOWNER propertiesOwner, List<PROPERTYTYPE> declaredProperties, ComponentInstancePropInput propInput) {
+    private InputDefinition declarePropertyInput(Component component, PROPERTYOWNER propertiesOwner, List<PROPERTYTYPE> declaredProperties, ComponentInstancePropInput propInput) {
         PropertyDataDefinition prop = resolveProperty(declaredProperties, propInput);
-        InputDefinition inputDefinition = createInput(componentId, propertiesOwner, propInput, prop);
+        InputDefinition inputDefinition = createInput(component, propertiesOwner, propInput, prop);
         PROPERTYTYPE declaredProperty = createDeclaredProperty(prop);
         if(!declaredProperties.contains(declaredProperty)){
             declaredProperties.add(declaredProperty);
@@ -174,15 +177,27 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties
         return inputDefinition;
     }
 
-    private InputDefinition createInput(String componentId, PROPERTYOWNER propertiesOwner,
+    private InputDefinition createInput(Component component, PROPERTYOWNER propertiesOwner,
                                         ComponentInstancePropInput propInput, PropertyDataDefinition prop) {
         String generatedInputPrefix = propertiesOwner.getNormalizedName();
         if (propertiesOwner.getUniqueId().equals(propInput.getParentUniqueId())) {
             //Creating input from property create on self using add property..Do not add the prefix
             generatedInputPrefix = null;
         }
+
+        Optional<CapabilityDefinition> propertyCapability = PropertiesUtils.getPropertyCapabilityOfChildInstance(propInput
+                .getParentUniqueId(), component.getCapabilities());
+        if (propertyCapability.isPresent()) {
+            String capName = propertyCapability.get().getName();
+            if(capName.contains(".")) {
+                capName = capName.replaceAll("\\.", UNDERSCORE);
+            }
+            generatedInputPrefix = generatedInputPrefix ==  null || generatedInputPrefix.isEmpty()?
+                    capName : generatedInputPrefix + UNDERSCORE + capName;
+        }
+
         String generatedInputName = generateInputName(generatedInputPrefix, propInput);
-        return createInputFromProperty(componentId, propertiesOwner, generatedInputName, propInput, prop);
+        return createInputFromProperty(component.getUniqueId(), propertiesOwner, generatedInputName, propInput, prop);
     }
 
     private String generateInputName(String inputName, ComponentInstancePropInput propInput) {
@@ -212,7 +227,7 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties
         }
 
         while(startingIndex < parsedPropNames.length){
-            prefix.append("_");
+            prefix.append(UNDERSCORE);
             prefix.append(parsedPropNames[startingIndex]);
             startingIndex ++;
         }
@@ -403,6 +418,31 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties
     }
 
     Either<InputDefinition, ResponseFormat>  prepareValueBeforeDelete(InputDefinition inputForDelete, PropertyDataDefinition inputValue, List<String> pathOfComponentInstances) {
+        Either<InputDefinition, ResponseFormat> deleteEither = prepareValueBeforeDelete(inputForDelete, inputValue);
+
+        Either<String, TitanOperationStatus> findDefaultValue = propertyOperation.findDefaultValueFromSecondPosition(pathOfComponentInstances, inputValue.getUniqueId(),
+                (String) inputValue.getDefaultValue());
+        if (findDefaultValue.isRight()) {
+            deleteEither = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(findDefaultValue.right().value()))));
+            return deleteEither;
+
+        }
+        String defaultValue = findDefaultValue.left().value();
+        inputValue.setDefaultValue(defaultValue);
+        log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue);
+        return deleteEither;
+    }
+
+    Either<InputDefinition, ResponseFormat>  prepareValueBeforeDeleteOfCapProp(InputDefinition inputForDelete,
+                                                                               PropertyDataDefinition inputValue) {
+        Either<InputDefinition, ResponseFormat> deleteEither = prepareValueBeforeDelete(inputForDelete, inputValue);
+        inputValue.setDefaultValue(inputForDelete.getDefaultValue());
+        log.debug("The returned default value in ResourceInstanceProperty is {}", inputForDelete.getDefaultValue());
+        return deleteEither;
+    }
+
+    private Either<InputDefinition, ResponseFormat> prepareValueBeforeDelete(InputDefinition inputForDelete,
+                                                                             PropertyDataDefinition inputValue) {
         Either<InputDefinition, ResponseFormat> deleteEither = Either.left(inputForDelete);
         String value = inputValue.getValue();
         Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(value);
@@ -410,36 +450,28 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties
         resetInputName(mappedToscaTemplate, inputForDelete.getName());
 
         value = "";
-        if(!mappedToscaTemplate.isEmpty()){
-            Either result = cleanNestedMap(mappedToscaTemplate , true);
+        if (!mappedToscaTemplate.isEmpty()) {
+            Either result = cleanNestedMap(mappedToscaTemplate, true);
             Map modifiedMappedToscaTemplate = mappedToscaTemplate;
-            if (result.isLeft())
-                modifiedMappedToscaTemplate = (Map)result.left().value();
-            else
-                log.warn("Map cleanup failed -> " +result.right().value().toString());    //continue, don't break operation
+            if (result.isLeft()) {
+                modifiedMappedToscaTemplate = (Map) result.left().value();
+            } else {
+                log.warn("Map cleanup failed -> " + result.right().value()
+                        .toString());    //continue, don't break operation
+            }
             value = gson.toJson(modifiedMappedToscaTemplate);
         }
         inputValue.setValue(value);
 
 
         List<GetInputValueDataDefinition> getInputsValues = inputValue.getGetInputValues();
-        if(getInputsValues != null && !getInputsValues.isEmpty()){
-            Optional<GetInputValueDataDefinition> op = getInputsValues.stream().filter(gi -> gi.getInputId().equals(inputForDelete.getUniqueId())).findAny();
-            if(op.isPresent()){
-                getInputsValues.remove(op.get());
-            }
+        if (getInputsValues != null && !getInputsValues.isEmpty()) {
+            Optional<GetInputValueDataDefinition> op =
+                    getInputsValues.stream().filter(gi -> gi.getInputId().equals(inputForDelete.getUniqueId()))
+                            .findAny();
+            op.ifPresent(getInputsValues::remove);
         }
         inputValue.setGetInputValues(getInputsValues);
-
-        Either<String, TitanOperationStatus> findDefaultValue = propertyOperation.findDefaultValueFromSecondPosition(pathOfComponentInstances, inputValue.getUniqueId(), inputValue.getDefaultValue());
-        if (findDefaultValue.isRight()) {
-            deleteEither = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(findDefaultValue.right().value()))));
-            return deleteEither;
-
-        }
-        String defaultValue = findDefaultValue.left().value();
-        inputValue.setDefaultValue(defaultValue);
-        log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue);
         return deleteEither;
     }
 
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/ConsumptionUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/ConsumptionUtils.java
new file mode 100644 (file)
index 0000000..e90bcfb
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * 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 com.google.gson.Gson;
+import fj.data.Either;
+import org.apache.commons.collections.CollectionUtils;
+import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
+import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition;
+import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
+import org.openecomp.sdc.be.model.Operation;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.tosca.ToscaFunctions;
+import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
+import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator;
+import org.openecomp.sdc.be.types.ServiceConsumptionData;
+import org.openecomp.sdc.exception.ResponseFormat;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class ConsumptionUtils {
+
+    private ConsumptionUtils() {
+
+    }
+
+    public static Either<Operation, ResponseFormat> handleConsumptionInputMappedToCapabilityProperty(
+            Operation operation,
+            OperationInputDefinition operationInputDefinition, ServiceConsumptionData serviceConsumptionData,
+            Map<String, List<CapabilityDefinition>> capabilities, String componentName) {
+
+        List<CapabilityDefinition> componentCapabilityDefinitions = capabilities.values().stream()
+                .flatMap(Collection::stream)
+                .collect(Collectors.toList());
+        if (CollectionUtils.isEmpty(componentCapabilityDefinitions)) {
+            return Either.left(operation);
+        }
+
+        for (CapabilityDefinition capabilityDefinition : componentCapabilityDefinitions) {
+            String capabilityName = capabilityDefinition.getName();
+            List<ComponentInstanceProperty> capabilityProperties = capabilityDefinition.getProperties();
+            if (CollectionUtils.isEmpty(capabilityProperties)) {
+                continue;
+            }
+            for (ComponentInstanceProperty capabilityProperty : capabilityProperties) {
+                String capabilityPropertyName = capabilityProperty.getName();
+                String capabilityPropertyIdentifier = capabilityName + "_" + capabilityPropertyName;
+                if (capabilityPropertyIdentifier.equals(serviceConsumptionData.getValue())) {
+                    boolean isInputTypeSimilarToOperation =
+                            isAssignedValueFromValidType(operationInputDefinition.getType(), capabilityProperty);
+                    if (!isInputTypeSimilarToOperation) {
+                        return Either.right(getResponseFormatManager().getResponseFormat(
+                                ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
+                    }
+                    addCapabilityPropertyToInputValue(componentName, capabilityName, operation,
+                            operationInputDefinition, capabilityProperty);
+                }
+            }
+        }
+        return Either.left(operation);
+    }
+
+    private static void addCapabilityPropertyToInputValue(String componentName, String capabilityName, Operation operation,
+                                                   OperationInputDefinition operationInputDefinition,
+                                                   PropertyDefinition capabilityProperty) {
+
+        List<String> getPropertyValues = new ArrayList<>();
+        getPropertyValues.add(componentName);
+        getPropertyValues.add(capabilityName);
+        getPropertyValues.add(capabilityProperty.getName());
+
+        Map<String, List<String>> getProperty = new HashMap<>();
+        getProperty.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), getPropertyValues);
+
+        operationInputDefinition.setSourceProperty(capabilityProperty.getUniqueId());
+        operation.getInputs().delete(operationInputDefinition);
+        operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_PROPERTY,
+                getPropertyValues);
+        operationInputDefinition.setValue((new Gson()).toJson(getProperty));
+        operation.getInputs().add(operationInputDefinition);
+    }
+
+    public static boolean isAssignedValueFromValidType(String operationInputType, Object actualValue) {
+        if (actualValue instanceof String) {
+            // validate static value
+            ToscaPropertyType actualType = ToscaPropertyType.isValidType(operationInputType);
+            PropertyTypeValidator validator = actualType.getValidator();
+            return validator.isValid((String)actualValue, operationInputType);
+        } else if (actualValue instanceof PropertyDefinition) {
+            // validate input / property value
+            String actualType = ((PropertyDefinition) actualValue).getType();
+            return actualType.equalsIgnoreCase(operationInputType);
+        } else if (actualValue instanceof OperationOutputDefinition) {
+            // validate input / output value
+            String actualType = ((OperationOutputDefinition) actualValue).getType();
+            return actualType.equalsIgnoreCase(operationInputType);
+        }
+        return false;
+    }
+
+    private static ResponseFormatManager getResponseFormatManager() {
+        return ResponseFormatManager.getInstance();
+    }
+}
index 0ee6264..38cdeb8 100644 (file)
@@ -87,14 +87,18 @@ public class InterfaceOperationUtils {
     }
 
     public static boolean isOperationInputMappedToComponentInput(OperationInputDefinition input,
-                                                                 List<InputDefinition> inputs) {
+                                                                                    List<InputDefinition> inputs) {
         if (CollectionUtils.isEmpty(inputs)) {
             return false;
         }
-        return inputs.stream().anyMatch(inp -> inp.getUniqueId().equals(input.getInputId()))
-                || (input.getInputId().contains(".")
-                && inputs.stream().anyMatch(inp -> inp.getUniqueId().equals(
-                input.getInputId().substring(0, input.getInputId().lastIndexOf('.'))))) ;
+
+        boolean matchedInput = inputs.stream().anyMatch(inp -> inp.getUniqueId().equals(input.getInputId()));
+        if (!matchedInput && input.getInputId().contains(".")) {
+            return inputs.stream()
+                    .anyMatch(inp -> inp.getUniqueId()
+                            .equals(input.getInputId().substring(0, input.getInputId().lastIndexOf('.'))));
+        }
+        return matchedInput;
     }
 
     public static boolean isOperationInputMappedToOtherOperationOutput(String outputName,
@@ -119,6 +123,20 @@ public class InterfaceOperationUtils {
         return getPropertyMap;
     }
 
+    public static Map<String, List<String>> createMappedCapabilityPropertyDefaultValue(String capabilityName,
+                                                                                       String propertyName) {
+        Map<String, List<String>> getPropertyMap = new HashMap<>();
+        List<String> values = new ArrayList<>();
+        values.add(InterfacesOperationsToscaUtil.SELF);
+        values.add(capabilityName);
+
+        if (Objects.nonNull(propertyName) && !propertyName.isEmpty()) {
+            values.addAll(Arrays.asList(propertyName.split("\\.")));
+        }
+        getPropertyMap.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), values);
+        return getPropertyMap;
+    }
+
     /**
      * Get the list of outputs of other operations of all the interfaces in the component.
      * @param currentOperationIdentifier Fully qualified operation name e.g. org.test.interfaces.node.lifecycle.Abc.stop
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/PropertiesUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/PropertiesUtils.java
new file mode 100644 (file)
index 0000000..7bea835
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * 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.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
+import org.openecomp.sdc.be.model.InputDefinition;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.Resource;
+
+import static org.openecomp.sdc.be.components.property.GetInputUtils.isGetInputValueForInput;
+
+public class PropertiesUtils {
+
+    private PropertiesUtils() {
+        //Hiding implicit default constructor
+    }
+
+    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(PropertyDefinition::new)
+                                                    .collect(Collectors.toSet());
+            serviceProperties.addAll(inputs);
+        }
+        serviceProperties =
+                serviceProperties.stream().filter(distinctByKey(PropertyDefinition::getName)).collect(Collectors.toSet());
+        return new ArrayList<>(serviceProperties);
+    }
+
+    public static Optional<ComponentInstanceProperty> isCapabilityProperty(String propertyUniqueId,
+                                               Component containerComponent) {
+
+        Optional<List<ComponentInstanceProperty>> capPropertiesOptional = getCapProperties(containerComponent);
+
+        if(capPropertiesOptional.isPresent()) {
+            return capPropertiesOptional.get().stream().filter(propertyDefinition ->
+                    propertyDefinition.getUniqueId().equals(propertyUniqueId)).findAny();
+        } else {
+            return Optional.empty();
+        }
+    }
+
+    private static Optional<List<ComponentInstanceProperty>> getCapProperties(Component containerComponent) {
+        Map<String, List<CapabilityDefinition>> componentCapabilities = containerComponent.getCapabilities();
+        if(MapUtils.isEmpty(componentCapabilities)){
+            return Optional.empty();
+        }
+        List<CapabilityDefinition> capabilityDefinitionList = componentCapabilities.values()
+                .stream().flatMap(Collection::stream).collect(Collectors.toList());
+        if(CollectionUtils.isEmpty(capabilityDefinitionList)){
+            return Optional.empty();
+        }
+        List<ComponentInstanceProperty> allComponentInstanceCapProperties= new ArrayList<>();
+        capabilityDefinitionList.stream().filter(capabilityDefinition -> CollectionUtils.isNotEmpty(capabilityDefinition
+                .getProperties())).collect(Collectors.toList()).forEach(capabilityDefinition ->
+                allComponentInstanceCapProperties.addAll(capabilityDefinition.getProperties()));
+        return Optional.of(allComponentInstanceCapProperties);
+    }
+
+    public static Optional<CapabilityDefinition> getPropertyCapabilityOfChildInstance(String propertyParentUniqueId,
+                                                                                      Map<String, List<CapabilityDefinition>>
+                                                                               componentCapabilities) {
+        if(MapUtils.isEmpty(componentCapabilities)){
+            return Optional.empty();
+        }
+        List<CapabilityDefinition> capabilityDefinitionList = componentCapabilities.values()
+                .stream().flatMap(Collection::stream).collect(Collectors.toList());
+        if(CollectionUtils.isEmpty(capabilityDefinitionList)){
+            return Optional.empty();
+        }
+        return capabilityDefinitionList.stream()
+                .filter(capabilityDefinition -> capabilityDefinition.getUniqueId().equals(propertyParentUniqueId) &&
+                        capabilityDefinition.getPath().size() == 1)
+                .findAny();
+    }
+
+    public static Optional<CapabilityDefinition> getPropertyCapabilityFromAllCapProps(String propertyParentUniqueId,
+                                                                                      List<CapabilityDefinition>
+                                                                                   capabilityDefinitionList) {
+        return capabilityDefinitionList.stream()
+                .filter(capabilityDefinition -> capabilityDefinition.getUniqueId().equals(propertyParentUniqueId))
+                .findAny();
+    }
+
+    public static boolean isNodeProperty(String propertyName, List<PropertyDefinition> properties) {
+
+        return !CollectionUtils.isEmpty(properties) && properties.stream().anyMatch(property -> property.getName()
+                .equals(propertyName));
+    }
+
+    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
+        Set<Object> seen = new HashSet<>();
+        return t -> seen.add(keyExtractor.apply(t));
+    }
+
+    public static Optional<ComponentInstanceProperty> getPropertyByInputId(Component component, String inputId) {
+        List<InputDefinition> componentInputs = component.getInputs();
+        if(CollectionUtils.isEmpty(componentInputs)) {
+            return Optional.empty();
+        }
+        Optional<InputDefinition> inputDefinition = componentInputs.stream().filter(cip -> cip.getUniqueId()
+                .equals(inputId)).findFirst();
+        if(!inputDefinition.isPresent()) {
+            return Optional.empty();
+        }
+        Optional<List<ComponentInstanceProperty>> capProperties = getCapProperties(component);
+        if(!capProperties.isPresent()) {
+            return Optional.empty();
+        }
+
+        return capProperties.get().stream().filter(capProp -> CollectionUtils.isNotEmpty(capProp.getGetInputValues()) &&
+                capProp.getGetInputValues().stream().anyMatch(capPropInp -> capPropInp.getInputId().equals(inputId)) &&
+                capProp.getUniqueId().equals(inputDefinition.get().getPropertyId())).findAny();
+    }
+
+    public static List<ComponentInstanceProperty> getCapabilityProperty(ComponentInstanceProperty capabilityProperty,
+                                                                  String inputId) {
+        List<ComponentInstanceProperty> resList = new ArrayList<>();
+        List<GetInputValueDataDefinition> inputsValues = capabilityProperty.getGetInputValues();
+        if (CollectionUtils.isNotEmpty(inputsValues) &&  inputsValues.stream().anyMatch(inputData ->
+                isGetInputValueForInput(inputData, inputId))) {
+                resList.add(capabilityProperty);
+        }
+        return resList;
+    }
+
+    public static boolean isNodeServiceProxy(Component component) {
+        if (component.getComponentType().equals(ComponentTypeEnum.SERVICE)) {
+            return true;
+        }
+        Resource resource = (Resource) component;
+        ResourceTypeEnum resType = resource.getResourceType();
+        return resType.equals(ResourceTypeEnum.ServiceProxy);
+    }
+}
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
deleted file mode 100644 (file)
index b9b7ab6..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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 726e9df..2c69ee5 100644 (file)
@@ -46,8 +46,8 @@ public class CapabilitiesValidation {
             org.openecomp.sdc.be.model.Component component, boolean isUpdate) {
 
         for(CapabilityDefinition capabilityDefinition : capabilities) {
-            Either<Boolean, ResponseFormat> validateCapabilityResponse = validateCapability(
-                    capabilityDefinition, component, isUpdate);
+            Either<Boolean, ResponseFormat> validateCapabilityResponse = validateCapability(capabilityDefinition,
+                    component, isUpdate);
             if (validateCapabilityResponse.isRight()) {
                 return validateCapabilityResponse;
             }
@@ -77,13 +77,11 @@ public class CapabilitiesValidation {
         if (capabilityTypeEmptyEither.isRight()) {
             return Either.right(capabilityTypeEmptyEither.right().value());
         }
-
         Either<Boolean, ResponseFormat> capabilityOccurrencesValidationEither =
                 validateOccurrences(capabilityDefinition, responseFormatManager);
         if (capabilityOccurrencesValidationEither.isRight()) {
             return Either.right(capabilityOccurrencesValidationEither.right().value());
         }
-
         return Either.left(Boolean.FALSE);
     }
 
@@ -93,8 +91,7 @@ public class CapabilitiesValidation {
         String minOccurrences = capabilityDefinition.getMinOccurrences();
         if(maxOccurrences != null && minOccurrences != null) {
             Either<Boolean, ResponseFormat> capabilityOccurrencesValidationEither =
-                    validateOccurrences(responseFormatManager, minOccurrences,
-                            maxOccurrences);
+                    validateOccurrences(responseFormatManager, minOccurrences, maxOccurrences);
             if (capabilityOccurrencesValidationEither.isRight()) {
                 return Either.right(capabilityOccurrencesValidationEither.right().value());
             }
@@ -163,32 +160,28 @@ public class CapabilitiesValidation {
         return Either.left(Boolean.TRUE);
     }
 
-    private Either<Boolean, ResponseFormat> isCapabilityNameEmpty(
-            ResponseFormatManager responseFormatManager, String capabilityName) {
+    private Either<Boolean, ResponseFormat> isCapabilityNameEmpty(ResponseFormatManager responseFormatManager,
+                                                                  String capabilityName) {
         if (StringUtils.isEmpty(capabilityName)) {
             LOGGER.error("Capability Name is mandatory");
-            ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
-                    .CAPABILITY_NAME_MANDATORY);
+            ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus.CAPABILITY_NAME_MANDATORY);
             return Either.right(errorResponse);
         }
         return Either.left(Boolean.TRUE);
     }
 
-    private Either<Boolean, ResponseFormat> isCapabilityTypeEmpty(
-            ResponseFormatManager responseFormatManager, String capabilityType) {
+    private Either<Boolean, ResponseFormat> isCapabilityTypeEmpty(ResponseFormatManager responseFormatManager,
+                                                                  String capabilityType) {
         if (StringUtils.isEmpty(capabilityType)) {
             LOGGER.error("Capability type is mandatory");
-            ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
-                    .CAPABILITY_TYPE_MANDATORY);
+            ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus.CAPABILITY_TYPE_MANDATORY);
             return Either.right(errorResponse);
         }
         return Either.left(Boolean.TRUE);
     }
 
-
-    private Either<Boolean, ResponseFormat> validateOccurrences        (
-            ResponseFormatManager responseFormatManager,
-            String minOccurrences, String maxOccurrences ) {
+    private Either<Boolean, ResponseFormat> validateOccurrences        (ResponseFormatManager responseFormatManager,
+                                                                    String minOccurrences, String maxOccurrences ) {
         try {
             if (StringUtils.isNotEmpty(maxOccurrences) && "UNBOUNDED".equalsIgnoreCase(maxOccurrences)
                     && Integer.parseInt(minOccurrences) >= 0) {
@@ -211,38 +204,29 @@ public class CapabilitiesValidation {
         return Either.left(Boolean.TRUE);
     }
 
-    private Either<Boolean, ResponseFormat> validateCapabilityNameUnique(
-            CapabilityDefinition capabilityDefinition,
-            org.openecomp.sdc.be.model.Component component,
-            boolean isUpdate) {
+    private Either<Boolean, ResponseFormat> validateCapabilityNameUnique(CapabilityDefinition capabilityDefinition,
+                                                                         org.openecomp.sdc.be.model.Component component,
+                                                                         boolean isUpdate) {
         boolean isCapabilityNameUnique = false;
-
         Map<String, List<CapabilityDefinition>> componentCapabilities = component.getCapabilities();
         if(MapUtils.isEmpty(componentCapabilities)){
             return Either.left(true);
         }
-
         List<CapabilityDefinition> capabilityDefinitionList = componentCapabilities.values()
                 .stream().flatMap(Collection::stream).collect(Collectors.toList());
-
         if(CollectionUtils.isEmpty(capabilityDefinitionList)){
             return Either.left(true);
         }
-
         Map<String, String> capabilityNameMap = new HashMap<>();
-        capabilityDefinitionList.forEach(capability -> capabilityNameMap
-                .put(capability.getUniqueId(), capability.getName()));
+        capabilityDefinitionList.forEach(capability -> capabilityNameMap.put(capability.getUniqueId(), capability.getName()));
 
         if (!capabilityNameMap.values().contains(capabilityDefinition.getName())){
             isCapabilityNameUnique = true;
         }
         if (!isCapabilityNameUnique && isUpdate){
-            List<Map.Entry<String, String>> capNamesEntries = capabilityNameMap.entrySet()
-                    .stream().filter(entry -> entry.getValue()
-                            .equalsIgnoreCase(capabilityDefinition.getName()))
-                    .collect(Collectors.toList());
-            if(capNamesEntries.size() == 1 && capNamesEntries.get(0).getKey()
-                    .equals(capabilityDefinition.getUniqueId())) {
+            List<Map.Entry<String, String>> capNamesEntries = capabilityNameMap.entrySet().stream().filter(entry ->
+                    entry.getValue().equalsIgnoreCase(capabilityDefinition.getName())).collect(Collectors.toList());
+            if(capNamesEntries.size() == 1 && capNamesEntries.get(0).getKey().equals(capabilityDefinition.getUniqueId())) {
                 isCapabilityNameUnique = true;
             }
         }
@@ -252,8 +236,7 @@ public class CapabilitiesValidation {
     private Either<Boolean, ResponseFormat> isCapabilityNameRegexValid(ResponseFormatManager responseFormatManager,
                                                                        String capabilityName) {
         if (!isValidCapabilityName(capabilityName)) {
-            LOGGER.error("Capability name {} is invalid, Only alphanumeric chars, underscore and dot allowed",
-                    capabilityName);
+            LOGGER.error("Capability name {} is invalid, Only alphanumeric chars, underscore and dot allowed", capabilityName);
             ResponseFormat errorResponse = responseFormatManager
                     .getResponseFormat(ActionStatus.INVALID_CAPABILITY_NAME, capabilityName);
             return Either.right(errorResponse);
index 30d006f..2e94139 100644 (file)
@@ -19,6 +19,7 @@ package org.openecomp.sdc.be.components.validation;
 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getOperationOutputName;
 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getOtherOperationOutputsOfComponent;
 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToComponentInput;
+import static org.openecomp.sdc.be.components.utils.PropertiesUtils.isCapabilityProperty;
 
 import com.google.common.collect.Sets;
 
@@ -523,7 +524,8 @@ public class InterfaceOperationValidation {
         List<OperationInputDefinition> inputListToscaDataDefinition =
                 operation.getInputs().getListToscaDataDefinition();
         for (OperationInputDefinition inputDefinition : inputListToscaDataDefinition) {
-            if (isOperationInputMappedToComponentInput(inputDefinition, component.getInputs())) {
+            if (isOperationInputMappedToComponentInput(inputDefinition, component.getInputs())
+                    || isCapabilityProperty(inputDefinition.getInputId(), component).isPresent()) {
                 isOperationInputToInputPropertyMappingValid = true;
             } else {
                 mappingName = inputDefinition.getInputId().contains(".")
@@ -553,7 +555,7 @@ public class InterfaceOperationValidation {
 
         if (!isOperationInputToOtherOperationOutputMappingValid) {
             LOGGER.error("Interface operation input parameter property {} not found in component input properties or"
-                    + " outputs of other operations.", mappingName);
+                   + "capability properties or  outputs of other operations.", mappingName);
             ResponseFormat inputResponse = responseFormatManager
                     .getResponseFormat(ActionStatus.INTERFACE_OPERATION_INPUT_PROPERTY_NOT_FOUND_IN_COMPONENT,
                             mappingName, component.getComponentType().getValue());
index 990e3bc..9ce5674 100644 (file)
@@ -16,6 +16,8 @@
 
 package org.openecomp.sdc.be.servlets;
 
+import static org.openecomp.sdc.be.tosca.utils.InterfacesOperationsToscaUtil.SELF;
+
 import com.google.gson.Gson;
 import com.google.gson.JsonParseException;
 import com.jcabi.aspects.Loggable;
@@ -26,6 +28,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.stream.Collectors;
 
 import fj.data.Either;
 import io.swagger.annotations.Api;
@@ -200,7 +203,11 @@ public class ServiceConsumptionServlet extends BeGenericServlet {
                                List<Object> toscaFunctionList = (List<Object>) consumptionValueName;
                                String consumptionInputValue = null;
                                if (ToscaFunctions.GET_PROPERTY.getFunctionName().equals(toscaFunction)) {
-                                       consumptionInputValue = String.valueOf(toscaFunctionList.get(1));
+                                       String propertyValue = toscaFunctionList.stream()
+                                                       .map(Object::toString)
+                                                       .filter(val -> !val.equals(SELF))
+                                                       .collect(Collectors.joining("_"));
+                                       consumptionInputValue = String.valueOf(propertyValue);
                                } else if (ToscaFunctions.GET_OPERATION_OUTPUT.getFunctionName().equals(toscaFunction)) {
                                        //Return full output name
                                        consumptionInputValue =
index 60503f8..b6c2adb 100644 (file)
@@ -1139,7 +1139,9 @@ public class ToscaExportHandler {
     }
 
     private boolean isRequirementBelongToOwner(RelationshipInfo reqAndRelationshipPair, RequirementDefinition requirement, String fromInstanceId, Component originComponent) {
-        return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId()) || (isCvfc(originComponent) && StringUtils.equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId()));
+        return StringUtils.equals(requirement.getOwnerId(), reqAndRelationshipPair.getRequirementOwnerId())
+                || (isCvfc(originComponent) && StringUtils.equals(fromInstanceId, reqAndRelationshipPair.getRequirementOwnerId())
+                || StringUtils.equals(requirement.getOwnerId(), originComponent.getUniqueId()));
     }
 
     private boolean isCvfc(Component component) {
index fe11531..adc467c 100644 (file)
@@ -2137,7 +2137,7 @@ errors:
 # %1 - Interface Operation input property name, component type
     INTERFACE_OPERATION_INPUT_PROPERTY_NOT_FOUND_IN_COMPONENT: {
         code: 404,
-        message: "Error: Interface operation input parameter property '%1' not found in '%2' input properties or outputs of other operations.",
+        message: "Error: Interface operation input parameter property '%1' not found in '%2' input properties, capability properties or outputs of other operations.",
         messageId: "SVC4708"
     }
 #---------SVC4709-----------------------------
@@ -2274,4 +2274,19 @@ errors:
         code: 400,
         message: "Error: Property name contains invalid characters. It should have only letters, numbers and underscores.",
         messageId: "SVC4727"
+    }
+
+#---------SVC4728------------------------------
+    FAILED_TO_CREATE_OR_UPDATE_CAPABILITY_PROPERTIES: {
+        code: 500,
+        message: "Error: Failed to create or update capabilities properties",
+        messageId: "SVC4728"
+    }
+
+#---------SVC4729------------------------------
+     # %1 - resource Id
+    CAPABILITY_PROPERTIES_NOT_FOUND: {
+        code: 400,
+        message: "Error: Capability properties not found in the resource '%1'.",
+        messageId: "SVC4729"
     }
\ No newline at end of file
index 393ef58..55b87f4 100644 (file)
@@ -30,11 +30,14 @@ import org.openecomp.sdc.be.config.ConfigurationManager;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.impl.ComponentsUtils;
 import org.openecomp.sdc.be.model.CapabilityDefinition;
 import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
 import org.openecomp.sdc.be.model.ComponentParametersView;
 import org.openecomp.sdc.be.model.LifecycleStateEnum;
 import org.openecomp.sdc.be.model.RelationshipInfo;
@@ -111,17 +114,17 @@ public class CapabilitiesBusinessLogicTest {
                 .thenReturn(StorageOperationStatus.OK);
 
         //CapabilityOperation
-        when(capabilitiesValidation.validateCapabilities(anyCollection(), anyObject(), anyBoolean())
-        ).thenReturn(Either.left(true));
+        when(capabilitiesValidation.validateCapabilities(anyCollection(), anyObject(), anyBoolean()))
+                .thenReturn(Either.left(true));
         when(capabilitiesOperation.addCapabilities(anyString(), anyObject()))
                 .thenReturn(Either.left(createMockCapabilityListToReturn(
                         createCapability("capName", "capDesc", "capType", "source1",
-                "0", "10"))));
+                                "0", "10"))));
 
         when(capabilitiesOperation.updateCapabilities(anyString(), anyObject()))
                 .thenReturn(Either.left(createMockCapabilityListToReturn(
                         createCapability("capName", "capDesc", "capType", "source1",
-                "0", "10"))));
+                                "0", "10"))));
         when(capabilitiesOperation.deleteCapabilities( anyObject(), anyString()))
                 .thenReturn(StorageOperationStatus.OK);
         when(mockTitanDao.commit()).thenReturn(TitanOperationStatus.OK);
@@ -141,7 +144,7 @@ public class CapabilitiesBusinessLogicTest {
     public void shouldPassCreateCapabilitiesFirstTimeInComponentForHappyScenario(){
         List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
                 createCapability("capName", "capDesc", "capType", "source1",
-                "0", "10"));
+                        "0", "10"));
         Resource resource = createComponent(false);
         resource.setComponentType(ComponentTypeEnum.RESOURCE);
         validateUserRoles(Role.ADMIN, Role.DESIGNER);
@@ -149,7 +152,7 @@ public class CapabilitiesBusinessLogicTest {
                 .thenReturn(Either.left(resource));
         Either<List<CapabilityDefinition>, ResponseFormat> capabilities = capabilitiesBusinessLogicMock
                 .createCapabilities(componentId, capabilityDefinitions, user,
-                         "createCapabilities", true);
+                        "createCapabilities", true);
         Assert.assertTrue(capabilities.isLeft());
         Assert.assertTrue(capabilities.left().value().stream().anyMatch(capabilityDefinition ->
                 capabilityDefinition.getName().equals("capName")));
@@ -159,7 +162,7 @@ public class CapabilitiesBusinessLogicTest {
     public void shouldPassCreateCapabilitiesForHappyScenario(){
         List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
                 createCapability("capName2", "capDesc", "capType", "source1",
-                "0", "10"));
+                        "0", "10"));
         Resource resource = createComponent(true);
         resource.setComponentType(ComponentTypeEnum.RESOURCE);
         validateUserRoles(Role.ADMIN, Role.DESIGNER);
@@ -178,7 +181,7 @@ public class CapabilitiesBusinessLogicTest {
     public void shouldFailCreateCapabilitiesWhenOperationFailedInTitan(){
         List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
                 createCapability("capName2", "capDesc", "capType", "source1",
-                "0", "10"));
+                        "0", "10"));
         Resource resource = createComponent(true);
         resource.setComponentType(ComponentTypeEnum.RESOURCE);
         validateUserRoles(Role.ADMIN, Role.DESIGNER);
@@ -190,7 +193,7 @@ public class CapabilitiesBusinessLogicTest {
                 .thenReturn(Either.left(resource));
         Either<List<CapabilityDefinition>, ResponseFormat> capabilities = capabilitiesBusinessLogicMock
                 .createCapabilities(componentId, capabilityDefinitions, user,
-                         "createCapabilities", true);
+                        "createCapabilities", true);
 
         Assert.assertTrue(capabilities.isRight());
     }
@@ -199,7 +202,7 @@ public class CapabilitiesBusinessLogicTest {
 
         List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
                 createCapability("capName", "capDesc updated", "capType", "source1",
-                "6", "11"));
+                        "6", "11"));
         Resource resource = createComponent(true);
         resource.setComponentType(ComponentTypeEnum.RESOURCE);
         validateUserRoles(Role.ADMIN, Role.DESIGNER);
@@ -220,7 +223,7 @@ public class CapabilitiesBusinessLogicTest {
 
         List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
                 createCapability("capName", "capDesc updated", "capTypeUpdate", "source1",
-                "6", "11"));
+                        "6", "11"));
         Resource resource = createComponent(true);
         resource.setComponentType(ComponentTypeEnum.RESOURCE);
         validateUserRoles(Role.ADMIN, Role.DESIGNER);
@@ -228,6 +231,8 @@ public class CapabilitiesBusinessLogicTest {
                 .thenReturn(Either.left(resource));
         when(toscaOperationFacade.getParentComponents(anyString()))
                 .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+        when((capabilitiesOperation.deleteCapabilityProperties(any(Component.class), anyString())))
+                .thenReturn(StorageOperationStatus.OK);
         Either<List<CapabilityDefinition>, ResponseFormat> capabilities = capabilitiesBusinessLogicMock
                 .updateCapabilities(componentId, capabilityDefinitions, user,
                         "updateCapabilities",true);
@@ -241,7 +246,7 @@ public class CapabilitiesBusinessLogicTest {
 
         List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
                 createCapability("capName", "capDesc updated", "capTypeUpdate1", "source1",
-                "6", "11"));
+                        "6", "11"));
         Resource resource = createComponent(true);
         resource.setComponentType(ComponentTypeEnum.RESOURCE);
 
@@ -258,6 +263,8 @@ public class CapabilitiesBusinessLogicTest {
                 .thenReturn(Either.left(resource));
         when(toscaOperationFacade.getParentComponents(anyString()))
                 .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+        when((capabilitiesOperation.deleteCapabilityProperties(any(Component.class), anyString())))
+                .thenReturn(StorageOperationStatus.OK);
         Either<List<CapabilityDefinition>, ResponseFormat> capabilities = capabilitiesBusinessLogicMock
                 .updateCapabilities(componentId, capabilityDefinitions, user,
                         "updateCapabilities",true);
@@ -267,10 +274,10 @@ public class CapabilitiesBusinessLogicTest {
     }
 
     @Test
-    public void shouldFailUpdateCapabilitiesWhenOperaitonFailedInTitan(){
+    public void shouldFailUpdateCapabilitiesWhenOperationFailedInTitan(){
         List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
                 createCapability("capName2", "capDesc", "capType", "source1",
-                "0", "10"));
+                        "0", "10"));
         Resource resource = createComponent(true);
         resource.setComponentType(ComponentTypeEnum.RESOURCE);
         validateUserRoles(Role.ADMIN, Role.DESIGNER);
@@ -296,6 +303,8 @@ public class CapabilitiesBusinessLogicTest {
                 .thenReturn(Either.left(resource));
         when(toscaOperationFacade.getParentComponents(anyString()))
                 .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+        when((capabilitiesOperation.deleteCapabilityProperties(any(Component.class), anyString())))
+                .thenReturn(StorageOperationStatus.OK);
         Either<CapabilityDefinition, ResponseFormat> deleteCapabilityEither =
                 capabilitiesBusinessLogicMock.deleteCapability(componentId, capabilityId, user, true);
         Assert.assertTrue(deleteCapabilityEither.isLeft());
@@ -362,6 +371,38 @@ public class CapabilitiesBusinessLogicTest {
 
     }
 
+    private ComponentInstanceProperty createCIP(String type, String name) {
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setType(type);
+        instanceProperty.setName(name);
+        instanceProperty.setDescription("prop_description");
+        instanceProperty.setParentUniqueId(capabilityId);
+        instanceProperty.setSchema(new SchemaDefinition());
+        return instanceProperty;
+    }
+
+    @Test
+    public void shouldPassCreateCapabilitiesWithPropertiesForHappyScenario(){
+        CapabilityDefinition capability = createCapability("capName", "capDesc", "capType", "source1",
+                "0", "10");
+        capability.setProperties(Collections.singletonList(createCIP("name", "type")));
+        List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(capability);
+        Resource resource = createComponent(false);
+        resource.setComponentType(ComponentTypeEnum.RESOURCE);
+        validateUserRoles(Role.ADMIN, Role.DESIGNER);
+        when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+                .thenReturn(Either.left(resource));
+        when(capabilitiesOperation.createOrUpdateCapabilityProperties(anyString(), any())).thenReturn(StorageOperationStatus.OK);
+        Either<List<CapabilityDefinition>, ResponseFormat> capabilities = capabilitiesBusinessLogicMock
+                .createCapabilities(componentId, capabilityDefinitions, user,
+                        "createCapabilities", true);
+        Assert.assertTrue(capabilities.isLeft());
+        Assert.assertTrue(capabilities.left().value().stream().anyMatch(capabilityDefinition ->
+                capabilityDefinition.getName().equals("capName")));
+        Assert.assertTrue(capabilities.left().value().stream().anyMatch(capabilityDefinition ->
+                capabilityDefinition.getProperties().size() == 1));
+    }
+
     private Resource createComponent(boolean needCapability) {
         Resource resource = new Resource();
         resource.setName("Resource1");
@@ -375,17 +416,17 @@ public class CapabilitiesBusinessLogicTest {
         if(needCapability) {
             List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
                     createCapability("capName", "capDesc", "capType", "source1",
-                    "0", "10"));
+                            "0", "10"));
             Map<String, List<CapabilityDefinition>> capabilityMap = new HashMap<>();
             capabilityMap.put("capType", capabilityDefinitions);
             resource.setCapabilities(capabilityMap);
         }
-            resource.setName(resource.getName());
-            resource.setVersion("0.1");
-            resource.setUniqueId(resource.getName().toLowerCase() + ":" + resource.getVersion());
-            resource.setCreatorUserId(user.getUserId());
-            resource.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
-            resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+        resource.setName(resource.getName());
+        resource.setVersion("0.1");
+        resource.setUniqueId(resource.getName().toLowerCase() + ":" + resource.getVersion());
+        resource.setCreatorUserId(user.getUserId());
+        resource.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
+        resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
         return resource;
     }
 
@@ -410,7 +451,6 @@ public class CapabilitiesBusinessLogicTest {
         capabilityDefinition.setMaxOccurrences(maxOccurrences);
         capabilityDefinition.setMinOccurrences(minOccurrences);
         capabilityDefinition.setUniqueId(capabilityId);
-
         return capabilityDefinition;
     }
 
index 963823c..d5b1f06 100644 (file)
@@ -23,6 +23,7 @@ import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.when;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
@@ -45,10 +46,13 @@ import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao;
 import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus;
 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.impl.ComponentsUtils;
 import org.openecomp.sdc.be.model.ArtifactDefinition;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
 import org.openecomp.sdc.be.model.InputDefinition;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.Resource;
@@ -145,6 +149,44 @@ public class InterfaceOperationBusinessLogicTest {
         Assert.assertTrue(interfaceOperationEither.isLeft());
     }
 
+    @Test
+    public void createInterfaceOperationTestOnExistingInterfaceInputsFromCapProp() {
+        when(interfaceLifecycleOperation.getAllInterfaceLifecycleTypes())
+                .thenReturn(Either.left(Collections.emptyMap()));
+        when(interfaceOperation.updateInterfaces(any(), any())).thenReturn(Either.left(
+                Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId, operationId, operationName))));
+
+        CapabilityDefinition capabilityDefinition = new CapabilityDefinition();
+        capabilityDefinition.setName("cap" + Math.random());
+        capabilityDefinition.setType("tosca.capabilities.network.Bindable");
+        capabilityDefinition.setOwnerId(resourceId);
+        capabilityDefinition.setUniqueId("capUniqueId");
+
+        List<ComponentInstanceProperty> properties = new ArrayList<>();
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setUniqueId("ComponentInput1_uniqueId");
+        instanceProperty.setType("Integer");
+        instanceProperty.setName("prop_name");
+        instanceProperty.setDescription("prop_description_prop_desc");
+        instanceProperty.setOwnerId("capUniqueId");
+        instanceProperty.setSchema(new SchemaDefinition());
+        properties.add(instanceProperty);
+        capabilityDefinition.setProperties(properties);
+        Map<String, List<CapabilityDefinition>> capabilityMap = new HashMap<>();
+        capabilityMap.put(capabilityDefinition.getType(), Collections.singletonList(capabilityDefinition));
+
+        resource.setCapabilities(capabilityMap);
+        when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource));
+
+        Either<List<InterfaceDefinition>, ResponseFormat> interfaceOperationEither =
+                interfaceOperationBusinessLogic.createInterfaceOperation(resourceId,
+                        Collections.singletonList(InterfaceOperationTestUtils.createMockInterface(interfaceId,
+                                operationId, operationName)),
+                        user, true);
+        Assert.assertTrue(interfaceOperationEither.isLeft());
+    }
+
+
     @Test
     public void createInterfaceOperationWithoutInterfaceTest() {
         resource.getInterfaces().clear();
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/PropertiesUtilsTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/utils/PropertiesUtilsTest.java
new file mode 100644 (file)
index 0000000..7e15eaa
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.openecomp.sdc.be.components.utils.PropertiesUtils;
+import org.openecomp.sdc.be.components.utils.ResourceBuilder;
+import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
+import org.openecomp.sdc.be.model.InputDefinition;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.Resource;
+import org.openecomp.sdc.be.model.Service;
+@RunWith(MockitoJUnitRunner.class)
+public class PropertiesUtilsTest {
+    @Mock
+    Service service;
+
+
+    @Test
+    public void testProxyServiceProperties(){
+        when(service.getProperties()).thenReturn(Arrays.asList(buildPropertyDefinition("a"),buildPropertyDefinition("b")));
+        when(service.getInputs()).thenReturn(Arrays.asList(buildInputDefiniton("a"),buildInputDefiniton("c")));
+
+        final List<PropertyDefinition> properties = PropertiesUtils.getProperties(service);
+        assertEquals(3, properties.size());
+    }
+
+    @Test
+    public void testProxyServiceNullInputs(){
+        when(service.getProperties()).thenReturn(Arrays.asList(buildPropertyDefinition("a"),buildPropertyDefinition("b")));
+        when(service.getInputs()).thenReturn(null);
+
+        final List<PropertyDefinition> properties = PropertiesUtils.getProperties(service);
+        assertEquals(2, properties.size());
+    }
+
+    @Test
+    public void testProxyServiceNullProperties(){
+        when(service.getProperties()).thenReturn(null);
+        when(service.getInputs()).thenReturn(Arrays.asList(buildInputDefiniton("a"),buildInputDefiniton("c")));
+
+        final List<PropertyDefinition> properties = PropertiesUtils.getProperties(service);
+        assertEquals(2, properties.size());
+    }
+
+    @Test
+    public void testGetCapabilityProperty() {
+
+        Assert.assertEquals(1, PropertiesUtils.getCapabilityProperty(createProperties(),
+                "inputId").size());
+    }
+
+    @Test
+    public void testGetPropertyCapabilityOfChildInstance() {
+        CapabilityDefinition capabilityDefinition = createCapabilityDefinition();
+        capabilityDefinition.setPath(Collections.singletonList("path"));
+        Map<String, List<CapabilityDefinition>> capMap = new HashMap<>();
+        capMap.put(capabilityDefinition.getType(), Collections.singletonList(capabilityDefinition));
+        Assert.assertTrue(PropertiesUtils.getPropertyCapabilityOfChildInstance("capUniqueId",
+                capMap).isPresent());
+    }
+
+    @Test
+    public void testGetPropertyCapabilityFromAllCapProps() {
+        CapabilityDefinition capabilityDefinition = createCapabilityDefinition();
+        Map<String, List<CapabilityDefinition>> capMap = new HashMap<>();
+        capMap.put(capabilityDefinition.getType(), Collections.singletonList(capabilityDefinition));
+        Assert.assertTrue(PropertiesUtils.getPropertyCapabilityOfChildInstance("capUniqueId",
+                capMap).isPresent());
+    }
+
+    @Test
+
+    public void testGetPropertyByInputId() {
+        Resource resource = new ResourceBuilder().setComponentType(ComponentTypeEnum.RESOURCE).setUniqueId("resourceId")
+                .setName("name").build();
+        CapabilityDefinition capabilityDefinition = createCapabilityDefinition();
+
+        List<ComponentInstanceProperty> properties = new ArrayList<>();
+        ComponentInstanceProperty instanceProperty = createProperties();
+
+        List<GetInputValueDataDefinition> valueDataDefinitionList = new ArrayList<>();
+        GetInputValueDataDefinition getInputValueDataDefinition = new GetInputValueDataDefinition();
+        getInputValueDataDefinition.setInputId("inputId");
+        getInputValueDataDefinition.setPropName("prop_name");
+        valueDataDefinitionList.add(getInputValueDataDefinition);
+
+        instanceProperty.setGetInputValues(valueDataDefinitionList);
+        properties.add(instanceProperty);
+        capabilityDefinition.setProperties(properties);
+        Map<String, List<CapabilityDefinition>> capabilityMap = new HashMap<>();
+        capabilityMap.put(capabilityDefinition.getType(), Collections.singletonList(capabilityDefinition));
+        resource.setCapabilities(capabilityMap);
+
+        InputDefinition inputDefinition = new InputDefinition();
+        inputDefinition.setUniqueId("inputId");
+        inputDefinition.setInputId("inputId");
+        inputDefinition.setPropertyId("inputId");
+        resource.setInputs(Collections.singletonList(inputDefinition));
+        Assert.assertTrue(PropertiesUtils.getPropertyByInputId(resource, "inputId").isPresent());
+    }
+
+    @Test
+    public void testIsNodeServiceProxy() {
+       Resource resource = new ResourceBuilder().setComponentType(ComponentTypeEnum.RESOURCE).setUniqueId("resourceId")
+                .setName("name").build();
+       resource.setResourceType(ResourceTypeEnum.ServiceProxy);
+        Assert.assertTrue( PropertiesUtils.isNodeServiceProxy(resource));
+    }
+
+    @Test
+    public void testProxyServiceAllNull(){
+        when(service.getProperties()).thenReturn(null);
+        when(service.getInputs()).thenReturn(null);
+
+        final List<PropertyDefinition> properties = PropertiesUtils.getProperties(service);
+        assertEquals(0, properties.size());
+    }
+
+    private PropertyDefinition buildPropertyDefinition(String name){
+        PropertyDefinition retVal = new PropertyDefinition();
+        retVal.setName(name);
+        return retVal;
+    }
+
+    private InputDefinition buildInputDefiniton(String name){
+        InputDefinition retVal = new InputDefinition();
+        retVal.setName(name);
+        return retVal;
+    }
+
+    private ComponentInstanceProperty createProperties() {
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setUniqueId("inputId");
+        instanceProperty.setType("Integer");
+        instanceProperty.setName("prop_name");
+        instanceProperty.setDescription("prop_description_prop_desc");
+        instanceProperty.setOwnerId("capUniqueId");
+        instanceProperty.setValue("{\"get_input\":\"extcp20_order\"}");
+        instanceProperty.setSchema(new SchemaDefinition());
+
+        List<GetInputValueDataDefinition> valueDataDefinitionList = new ArrayList<>();
+        GetInputValueDataDefinition getInputValueDataDefinition = new GetInputValueDataDefinition();
+        getInputValueDataDefinition.setInputId("inputId");
+        getInputValueDataDefinition.setPropName("prop_name");
+        valueDataDefinitionList.add(getInputValueDataDefinition);
+        instanceProperty.setGetInputValues(valueDataDefinitionList);
+        return instanceProperty;
+    }
+
+    private CapabilityDefinition createCapabilityDefinition() {
+        CapabilityDefinition capabilityDefinition = new CapabilityDefinition();
+        capabilityDefinition.setName("cap" + Math.random());
+        capabilityDefinition.setType("tosca.capabilities.network.Bindable");
+        capabilityDefinition.setOwnerId("resourceId");
+        capabilityDefinition.setUniqueId("capUniqueId");
+        List<String> path = new ArrayList<>();
+        path.add("path1");
+        capabilityDefinition.setPath(path);
+        return capabilityDefinition;
+    }
+
+}
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/CapabilityTestUtils.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/property/CapabilityTestUtils.java
new file mode 100644 (file)
index 0000000..fc0edd9
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright Â© 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.components.property;
+
+import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CapabilityTestUtils {
+
+    public static ComponentInstanceProperty createProperties() {
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setUniqueId("ComponentInput1_uniqueId");
+        instanceProperty.setType("Integer");
+        instanceProperty.setName("prop_name");
+        instanceProperty.setDescription("prop_description_prop_desc");
+        instanceProperty.setOwnerId("capUniqueId");
+        instanceProperty.setValue("{\"get_input\":\"extcp20_order\"}");
+        instanceProperty.setSchema(new SchemaDefinition());
+        return instanceProperty;
+    }
+
+    public static CapabilityDefinition createCapabilityDefinition() {
+        CapabilityDefinition capabilityDefinition = new CapabilityDefinition();
+        capabilityDefinition.setName("cap" + Math.random());
+        capabilityDefinition.setType("tosca.capabilities.network.Bindable");
+        capabilityDefinition.setOwnerId("resourceId");
+        capabilityDefinition.setUniqueId("capUniqueId");
+        List<String> path = new ArrayList<>();
+        path.add("path1");
+        capabilityDefinition.setPath(path);
+        return capabilityDefinition;
+    }
+}
index 5752ae2..fd61133 100644 (file)
@@ -1,6 +1,7 @@
 package org.openecomp.sdc.be.components.property;
 
 import fj.data.Either;
+import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -9,25 +10,32 @@ import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.openecomp.sdc.be.components.utils.PropertyDataDefinitionBuilder;
+import org.openecomp.sdc.be.components.utils.ResourceBuilder;
 import org.openecomp.sdc.be.dao.utils.MapUtil;
 import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
+import static org.openecomp.sdc.be.components.property.CapabilityTestUtils.createCapabilityDefinition;
+import static org.openecomp.sdc.be.components.property.CapabilityTestUtils.createProperties;
 
 
 @RunWith(MockitoJUnitRunner.class)
@@ -60,6 +68,64 @@ public class ComponentInstancePropertyDeclaratorTest extends PropertyDeclaratorT
         verifyUpdatedProperties(properties, capturedInstanceProperties, inputs);
     }
 
+    @Test
+    public void declareCapabilitiesPropertiesAsInputs() {
+        prop1.setParentUniqueId("capUniqueId");
+        List<PropertyDataDefinition> properties = Collections.singletonList(prop1);
+        List<ComponentInstancePropInput> propsToDeclare = createInstancePropInputList(properties);
+        when(toscaOperationFacade.addComponentInstancePropertiesToComponent(eq(resource), instancePropertiesCaptor
+                .capture())).thenReturn(Either.left(Collections.emptyMap()));
+
+        CapabilityDefinition capabilityDefinition = createCapabilityDefinition();
+
+        List<ComponentInstanceProperty> capPropList = new ArrayList<>();
+        ComponentInstanceProperty instanceProperty = createProperties();
+        capPropList.add(instanceProperty);
+        capabilityDefinition.setProperties(capPropList);
+
+        capabilityDefinition.setPath(Collections.singletonList("path"));
+        Map<String, List<CapabilityDefinition>> capabilityMap = new HashMap<>();
+        capabilityMap.put(capabilityDefinition.getType(), Collections.singletonList(capabilityDefinition));
+        resource.setCapabilities(capabilityMap);
+
+        Either<List<InputDefinition>, StorageOperationStatus> createdInputs = testInstance
+                .declarePropertiesAsInputs(resource, "inst1", propsToDeclare);
+        Assert.assertTrue(createdInputs.isLeft());
+    }
+
+    @Test
+    public void testUnDeclarePropertiesAsInputs() throws Exception {
+        Component component = new ResourceBuilder().setComponentType(ComponentTypeEnum.RESOURCE).setUniqueId("resourceId")
+                .setName("resourceName").build();
+        InputDefinition input = new InputDefinition();
+        input.setUniqueId("ComponentInput1_uniqueId");
+        input.setPropertyId("ComponentInput1_uniqueId");
+
+        CapabilityDefinition capabilityDefinition = createCapabilityDefinition();
+
+        List<ComponentInstanceProperty> properties = new ArrayList<>();
+        ComponentInstanceProperty instanceProperty = createProperties();
+
+        List<GetInputValueDataDefinition> valueDataDefinitionList = new ArrayList<>();
+        GetInputValueDataDefinition getInputValueDataDefinition = new GetInputValueDataDefinition();
+        getInputValueDataDefinition.setInputId("ComponentInput1_uniqueId");
+        getInputValueDataDefinition.setPropName("prop_name");
+        valueDataDefinitionList.add(getInputValueDataDefinition);
+
+        instanceProperty.setGetInputValues(valueDataDefinitionList);
+        properties.add(instanceProperty);
+        capabilityDefinition.setProperties(properties);
+        Map<String, List<CapabilityDefinition>> capabilityMap = new HashMap<>();
+        capabilityMap.put(capabilityDefinition.getType(), Collections.singletonList(capabilityDefinition));
+        component.setCapabilities(capabilityMap);
+        component.setInputs(Collections.singletonList(input));
+        when(toscaOperationFacade.updateInstanceCapabilityProperty(any(Resource.class), any(),
+                any(ComponentInstanceProperty.class), any(CapabilityDefinition.class))).thenReturn(StorageOperationStatus.OK);
+
+        StorageOperationStatus result = testInstance.unDeclarePropertiesAsInputs(component, input);
+        Assert.assertEquals(StorageOperationStatus.OK, result);
+    }
+
     @Test
     public void declarePropertiesAsInputs_multipleNonComplexProperty() {
         List<PropertyDataDefinition> properties = Arrays.asList(prop1, prop2);
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/ConsumptionUtilsTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/utils/ConsumptionUtilsTest.java
new file mode 100644 (file)
index 0000000..619c294
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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 fj.data.Either;
+import org.junit.Assert;
+import org.junit.Test;
+import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
+import org.openecomp.sdc.be.model.Operation;
+import org.openecomp.sdc.be.types.ServiceConsumptionData;
+import org.openecomp.sdc.exception.ResponseFormat;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.openecomp.sdc.be.components.property.CapabilityTestUtils.createCapabilityDefinition;
+import static org.openecomp.sdc.be.components.property.CapabilityTestUtils.createProperties;
+
+public class ConsumptionUtilsTest {
+
+    @Test
+    public void testHandleConsumptionInputMappedToCapabilityProperty() {
+
+        Operation operation = new Operation();
+        operation.setUniqueId("uniqueId");
+        OperationInputDefinition operationInputDefinition = new OperationInputDefinition();
+        operationInputDefinition.setUniqueId("uniqueId");
+        operationInputDefinition.setInputId("uniqueId");
+        operationInputDefinition.setType("Integer");
+
+        List<OperationInputDefinition> operationInputDefinitions = new ArrayList<>();
+        operationInputDefinitions.add(operationInputDefinition);
+        ListDataDefinition<OperationInputDefinition> listDataDefinition = new ListDataDefinition<>(operationInputDefinitions);
+        operation.setInputs(listDataDefinition);
+        CapabilityDefinition capabilityDefinition = createCapabilityDefinition();
+        ServiceConsumptionData serviceConsumptionData = new ServiceConsumptionData();
+        serviceConsumptionData.setInputId("uniqueId");
+        serviceConsumptionData.setValue(capabilityDefinition.getName() + "_prop_name" );
+
+        List<ComponentInstanceProperty> capPropList = new ArrayList<>();
+        ComponentInstanceProperty instanceProperty = createProperties();
+        capPropList.add(instanceProperty);
+        capabilityDefinition.setProperties(capPropList);
+
+        capabilityDefinition.setPath(Collections.singletonList("path"));
+        Map<String, List<CapabilityDefinition>> capabilityMap = new HashMap<>();
+        capabilityMap.put(capabilityDefinition.getType(), Collections.singletonList(capabilityDefinition));
+
+        Either<Operation, ResponseFormat> operationResponseFormatEither = ConsumptionUtils
+                .handleConsumptionInputMappedToCapabilityProperty(operation, operationInputDefinition,
+                        serviceConsumptionData, capabilityMap, "componentName");
+
+        Assert.assertTrue(operationResponseFormatEither.isLeft());
+    }
+}
\ No newline at end of file
index 1258bc0..74c7b8d 100644 (file)
@@ -129,4 +129,10 @@ public class InterfaceOperationUtilsTest {
         Assert.assertFalse(InterfaceOperationUtils.isArtifactInUse(resource, operationId1, "uniqId1"));
     }
 
+    @Test
+    public void testCreateMappedCapabilityPropertyDefaultValue() {
+        Assert.assertTrue(!InterfaceOperationUtils
+                .createMappedCapabilityPropertyDefaultValue("capName", "propName").isEmpty());
+    }
+
 }
\ No newline at end of file
index b4856b9..4c3ad32 100644 (file)
@@ -101,6 +101,36 @@ public class CapabilitiesValidationTest  {
         Assert.assertTrue(validateCapabilitiesResponseEither.isRight());
     }
 
+    @Test
+    public void shouldPassWhenCapabilityMaxOccurrencesIsUnbounded() {
+        List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
+        capabilityDefinitions.add(createCapability("capName1", "capDesc", "capType", "source1",
+                "111", "UNBOUNDED"));
+        Either<Boolean, ResponseFormat> validateCapabilitiesResponseEither = capabilitiesValidationUtilTest
+                .validateCapabilities(capabilityDefinitions, component, false);
+        Assert.assertTrue(validateCapabilitiesResponseEither.isLeft());
+    }
+
+    @Test
+    public void shouldFailWhenCapabilityMinOccurrencesIsNegative() {
+        List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
+        capabilityDefinitions.add(createCapability("capName1", "capDesc", "capType", "source1",
+                "-1", "3"));
+        Either<Boolean, ResponseFormat> validateCapabilitiesResponseEither = capabilitiesValidationUtilTest
+                .validateCapabilities(capabilityDefinitions, component, false);
+        Assert.assertTrue(validateCapabilitiesResponseEither.isRight());
+    }
+
+    @Test
+    public void shouldThrowExceptionWhenMin_MaxOccurrencesIsNotInteger() {
+        List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
+        capabilityDefinitions.add(createCapability("capName1", "capDesc", "capType", "source1",
+                "occur", "3"));
+        Either<Boolean, ResponseFormat> validateCapabilitiesResponseEither = capabilitiesValidationUtilTest
+                .validateCapabilities(capabilityDefinitions, component, false);
+        Assert.assertTrue(validateCapabilitiesResponseEither.isRight());
+    }
+
     @Test
     public void shouldFailWhenCapabilityNotFoundForUpdate() {
         List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
@@ -114,6 +144,47 @@ public class CapabilitiesValidationTest  {
         Assert.assertTrue(validateCapabilitiesResponseEither.isRight());
     }
 
+    @Test
+    public void shouldFailWhenCapabilityMapIsEmptyInComponentForUpdate() {
+        List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
+        CapabilityDefinition capabilityToUpdate = createCapability("capName1", "capDesc", "capType", "source1",
+                "1", "3");
+        capabilityToUpdate.setUniqueId("uniqueId2");
+        capabilityDefinitions.add(capabilityToUpdate);
+        Component resource = new Resource();
+        List<CapabilityDefinition> componentCap = new ArrayList<>();
+        Map<String, List<CapabilityDefinition>> capabilityMap = new HashMap<>();
+        capabilityMap.put("capTypeC", componentCap);
+
+        resource.setCapabilities(capabilityMap);
+        Either<Boolean, ResponseFormat> validateCapabilitiesResponseEither = capabilitiesValidationUtilTest
+                .validateCapabilities(capabilityDefinitions, resource, true);
+        Assert.assertTrue(validateCapabilitiesResponseEither.isRight());
+    }
+
+    @Test
+    public void shouldFailWhenCapabilityMapIsNullInComponentForUpdate() {
+        List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
+        CapabilityDefinition capabilityToUpdate = createCapability("capName1", "capDesc", "capType", "source1",
+                "1", "3");
+        capabilityToUpdate.setUniqueId("uniqueId2");
+
+        capabilityDefinitions.add(capabilityToUpdate);
+        Either<Boolean, ResponseFormat> validateCapabilitiesResponseEither = capabilitiesValidationUtilTest
+                .validateCapabilities(capabilityDefinitions, new Resource(), true);
+        Assert.assertTrue(validateCapabilitiesResponseEither.isRight());
+    }
+
+    @Test
+    public void shouldFailWhenCapabilityNameContainsSpecialSymbolExceptDot() {
+        List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
+        capabilityDefinitions.add(createCapability("cap@name", "capDesc", "capType", "source1",
+                "0", "10"));
+        Either<Boolean, ResponseFormat> validateCapabilitiesResponseEither = capabilitiesValidationUtilTest
+                .validateCapabilities(capabilityDefinitions, component, false);
+        Assert.assertTrue(validateCapabilitiesResponseEither.isRight());
+    }
+
     private CapabilityDefinition createCapability(String name, String description, String type,
                                                   String validSourceTypes, String minOccurrences,
                                                   String maxOccurrences) {
@@ -126,7 +197,6 @@ public class CapabilitiesValidationTest  {
         capabilityDefinition.setMinOccurrences(minOccurrences);
         capabilityDefinition.setUniqueId("uniqueId");
 
-
         return capabilityDefinition;
     }
 
@@ -143,9 +213,9 @@ public class CapabilitiesValidationTest  {
         List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
         capabilityDefinitions.add(createCapability("capNameC", "capDesc", "capType", "source1",
                 "0", "10"));
-            Map<String, List<CapabilityDefinition>> capabilityMap = new HashMap<>();
-            capabilityMap.put("capTypeC", capabilityDefinitions);
-            resource.setCapabilities(capabilityMap);
+        Map<String, List<CapabilityDefinition>> capabilityMap = new HashMap<>();
+        capabilityMap.put("capTypeC", capabilityDefinitions);
+        resource.setCapabilities(capabilityMap);
 
         return resource;
     }
index 6fd2eb2..dc4da54 100644 (file)
@@ -155,6 +155,7 @@ public enum ActionStatus {
     CAPABILITY_NOT_FOUND, CAPABILITY_NAME_MANDATORY, CAPABILITY_TYPE_MANDATORY,CAPABILITY_NAME_ALREADY_IN_USE,
     MAX_OCCURRENCES_SHOULD_BE_GREATER_THAN_MIN_OCCURRENCES, CAPABILITY_DELETION_NOT_ALLOWED_USED_IN_COMPOSITION,
     CAPABILITY_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION,INVALID_CAPABILITY_NAME,
+    FAILED_TO_CREATE_OR_UPDATE_CAPABILITY_PROPERTIES, CAPABILITY_PROPERTIES_NOT_FOUND,
 
     RELATIONSHIP_TYPE_ALREADY_EXIST, MISSING_RELATIONSHIP_TYPE, CAPABILITY_TYPE_CANNOT_BE_EMPTY,
 
index 05d9a57..a405f6e 100644 (file)
@@ -46,7 +46,7 @@ public class ComponentParametersView {
     private boolean ignoreComponentInstancesAttributesFrom = false;
     private boolean ignoreInputs = false;
     private boolean ignoreComponentInstancesInputs = false;
-    private boolean ignoreCapabiltyProperties = true;
+    private boolean ignoreCapabiltyProperties = false;
     private boolean ignoreServicePath = true;
     private boolean ignorePolicies = false;
     private boolean ignoreNodeFilterRequirements = false;
@@ -94,6 +94,7 @@ public class ComponentParametersView {
                     this.setIgnoreCapabilities(false);
                     this.setIgnoreRequirements(false);
                     this.setIgnoreNodeFilter(false);
+                    this.setIgnoreCapabiltyProperties(false);
                     break;
                 case COMPONENT_INSTANCES_PROPERTIES:
                     this.setIgnoreComponentInstances(false); //we need this in order to get the calculate capabilities requirements
@@ -102,6 +103,7 @@ public class ComponentParametersView {
                 case CAPABILITIES:
                     this.setIgnoreComponentInstances(false);//we need this in order to get the calculate capabilities requirements
                     this.setIgnoreCapabilities(false);
+                    this.setIgnoreCapabiltyProperties(false);
                     break;
                 case REQUIREMENTS:
                     this.setIgnoreComponentInstances(false);
index 6dfd1fc..d44865c 100644 (file)
@@ -1485,7 +1485,7 @@ public abstract class BaseOperation {
         return titanOperationStatus;
     }
 
-    private GraphVertex throwStorageException(TitanOperationStatus status) {
+    protected GraphVertex throwStorageException(TitanOperationStatus status) {
         throw new StorageException(status);
     }
 
index a8337b6..9d7f64c 100644 (file)
 package org.openecomp.sdc.be.model.jsontitan.operations;
 
 import fj.data.Either;
+import org.apache.commons.collections.MapUtils;
+import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
 import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
+import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
 import org.openecomp.sdc.be.model.CapabilityDefinition;
 import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.ComponentParametersView;
+import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
+import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
+import org.openecomp.sdc.be.model.operations.StorageException;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -31,20 +41,19 @@ import org.slf4j.LoggerFactory;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 @org.springframework.stereotype.Component("capabilities-operation")
 public class CapabilitiesOperation extends BaseOperation {
     private static final Logger LOGGER = LoggerFactory.getLogger(CapabilitiesOperation.class);
 
-    public Either<List<CapabilityDefinition>, StorageOperationStatus> addCapabilities(
-            String componentId,
-            List<CapabilityDefinition> capabilityDefinitions) {
+    public Either<List<CapabilityDefinition>, StorageOperationStatus> addCapabilities(String componentId,
+                                                                                      List<CapabilityDefinition> capabilityDefinitions) {
         return addOrUpdateCapabilities(componentId, capabilityDefinitions, false);
     }
 
-    public Either<List<CapabilityDefinition>, StorageOperationStatus> updateCapabilities(
-            String componentId,
-            List<CapabilityDefinition> capabilityDefinitions) {
+    public Either<List<CapabilityDefinition>, StorageOperationStatus> updateCapabilities(String componentId,
+                                                                                         List<CapabilityDefinition> capabilityDefinitions) {
         return addOrUpdateCapabilities(componentId, capabilityDefinitions, true);
     }
 
@@ -52,33 +61,31 @@ public class CapabilitiesOperation extends BaseOperation {
                                                                                                List<CapabilityDefinition> capabilityDefinitions,
                                                                                                boolean isUpdateAction) {
         StorageOperationStatus statusRes = performUpdateToscaAction(isUpdateAction,
-                componentId, Collections
-                        .singletonList(convertToListCapabilityDataDefinition(capabilityDefinitions)));
+                componentId, Collections.singletonList(convertToListCapabilityDataDefinition(capabilityDefinitions)));
         if (!statusRes.equals(StorageOperationStatus.OK)) {
-            titanDao.rollback();
-            LOGGER.error("Failed to find the parent capability of capability type {}."
-                    + " status is {}", componentId, statusRes);
+            LOGGER.error("Failed to find the parent capability of capability type {}." + " status is {}", componentId,
+                    statusRes);
             return Either.right(statusRes);
         }
-        titanDao.commit();
         return Either.left(capabilityDefinitions);
     }
 
-    public StorageOperationStatus deleteCapabilities(Component component,
-                                                     String capabilityIdToDelete) {
-        return deleteToscaDataElements(component.getUniqueId(),
-                EdgeLabelEnum.CAPABILITIES,
+    public StorageOperationStatus deleteCapabilities(Component component, String capabilityIdToDelete) {
+        return deleteToscaDataElements(component.getUniqueId(), EdgeLabelEnum.CAPABILITIES,
                 Collections.singletonList(capabilityIdToDelete));
     }
 
-    private static ListCapabilityDataDefinition convertToListCapabilityDataDefinition(
-            List<CapabilityDefinition> capabilities) {
+    public StorageOperationStatus deleteCapabilityProperties(Component component, String capabilityPropIdToDelete) {
+        return deleteToscaDataElements(component.getUniqueId(), EdgeLabelEnum.CAPABILITIES_PROPERTIES,
+                Collections.singletonList(capabilityPropIdToDelete));
+    }
+
+    private static ListCapabilityDataDefinition convertToListCapabilityDataDefinition(List<CapabilityDefinition> capabilities) {
         List<CapabilityDataDefinition> capabilityDefinitions = new ArrayList<>(capabilities);
         return new ListCapabilityDataDefinition(capabilityDefinitions);
     }
 
-    private StorageOperationStatus performUpdateToscaAction(boolean isUpdate,
-                                                            String componentId,
+    private StorageOperationStatus performUpdateToscaAction(boolean isUpdate, String componentId,
                                                             List<ListCapabilityDataDefinition> toscaDataList) {
         if (isUpdate) {
             return updateToscaDataOfToscaElement(componentId, EdgeLabelEnum.CAPABILITIES,
@@ -88,4 +95,61 @@ public class CapabilitiesOperation extends BaseOperation {
                     VertexTypeEnum.CAPABILITIES, toscaDataList, JsonPresentationFields.TYPE);
         }
     }
+
+    private StorageOperationStatus createOrUpdateCapabilityProperties(String componentId, TopologyTemplate toscaElement,
+                                                                      Map<String, MapPropertiesDataDefinition> propertiesMap) {
+        GraphVertex toscaElementV = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse)
+                .left().on(this::throwStorageException);
+        Map<String, MapPropertiesDataDefinition> capabilitiesProperties = toscaElement.getCapabilitiesProperties();
+        if(MapUtils.isNotEmpty(capabilitiesProperties)) {
+
+            capabilitiesProperties.forEach((key, val) -> {
+                Map<String, PropertyDataDefinition> mapToscaDataDefinition = val.getMapToscaDataDefinition();
+                mapToscaDataDefinition.forEach((key1, val1) -> {
+
+                    propertiesMap.forEach((propKey, propVal) -> {
+                        Map<String, PropertyDataDefinition> propValMapToscaDataDefinition = propVal.getMapToscaDataDefinition();
+                        propValMapToscaDataDefinition.forEach((propKey1, propVal1) -> {
+                            if(propKey1.equals(key1) && val1.getUniqueId().equals(propVal1.getUniqueId())) {
+                                ToscaDataDefinition.mergeDataMaps(mapToscaDataDefinition, propValMapToscaDataDefinition);
+                            }
+                        });
+                    });
+                });
+            });
+
+            ToscaDataDefinition.mergeDataMaps(propertiesMap, capabilitiesProperties);
+        }
+
+        return topologyTemplateOperation.updateFullToscaData(toscaElementV,
+                EdgeLabelEnum.CAPABILITIES_PROPERTIES, VertexTypeEnum.CAPABILITIES_PROPERTIES, propertiesMap);
+    }
+
+    public StorageOperationStatus createOrUpdateCapabilityProperties(String componentId,
+                                                                     Map<String, MapPropertiesDataDefinition> propertiesMap) {
+        StorageOperationStatus propertiesStatusRes = null;
+        if(MapUtils.isNotEmpty(propertiesMap)) {
+            propertiesStatusRes = createOrUpdateCapabilityProperties(componentId, getTopologyTemplate(componentId),
+                    propertiesMap);
+        }
+
+        return propertiesStatusRes;
+    }
+
+    private TopologyTemplate getTopologyTemplate(String componentId) {
+        return (TopologyTemplate)topologyTemplateOperation
+                .getToscaElement(componentId, getFilterComponentWithCapProperties())
+                .left()
+                .on(this::throwStorageException);
+    }
+    private ComponentParametersView getFilterComponentWithCapProperties() {
+        ComponentParametersView filter = new ComponentParametersView();
+        filter.setIgnoreCapabiltyProperties(false);
+        return filter;
+    }
+
+    private ToscaElement throwStorageException(StorageOperationStatus status) {
+        throw new StorageException(status);
+    }
+
 }
index 4175773..f0a5e2b 100644 (file)
@@ -251,11 +251,24 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
     }
 
     private StorageOperationStatus associateCapPropertiesToResource(GraphVertex topologyTemplateVertex, TopologyTemplate topologyTemplate) {
-        Map<String, MapCapabilityProperty> calculatedCapProperties = topologyTemplate.getCalculatedCapabilitiesProperties();
-        if (calculatedCapProperties != null && !calculatedCapProperties.isEmpty()) {
-            Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(topologyTemplateVertex, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, calculatedCapProperties);
-            if (assosiateElementToData.isRight()) {
-                return assosiateElementToData.right().value();
+        Map<String, MapCapabilityProperty> calculatedCapProperties = topologyTemplate
+                .getCalculatedCapabilitiesProperties();
+        if (MapUtils.isNotEmpty(calculatedCapProperties)) {
+            Either<GraphVertex, StorageOperationStatus> associateElementToData = associateElementToData
+                    (topologyTemplateVertex, VertexTypeEnum.CALCULATED_CAP_PROPERTIES,
+                            EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, calculatedCapProperties);
+            if (associateElementToData.isRight()) {
+                return associateElementToData.right().value();
+            }
+        }
+
+        Map<String, MapPropertiesDataDefinition> capabilitiesProperties = topologyTemplate.getCapabilitiesProperties();
+        if (MapUtils.isNotEmpty(capabilitiesProperties)) {
+            Either<GraphVertex, StorageOperationStatus> associateElementToData =
+                    associateElementToData(topologyTemplateVertex, VertexTypeEnum.CAPABILITIES_PROPERTIES,
+                            EdgeLabelEnum.CAPABILITIES_PROPERTIES, capabilitiesProperties);
+            if (associateElementToData.isRight()) {
+                return associateElementToData.right().value();
             }
         }
         return StorageOperationStatus.OK;
@@ -866,6 +879,16 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
                 return result.right().value();
             }
         }
+        Either<Map<String, MapPropertiesDataDefinition>, TitanOperationStatus> capPropResult =
+                getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
+        if (capPropResult.isLeft()) {
+            topologyTemplate.setCapabilitiesProperties(capPropResult.left().value());
+        } else {
+            if (capPropResult.right().value() != TitanOperationStatus.NOT_FOUND) {
+                return capPropResult.right().value();
+            }
+        }
+
         return TitanOperationStatus.OK;
     }
 
@@ -1151,6 +1174,11 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
             log.debug("Failed to disassociate instance inputs for {} error {}", toscaElementVertex.getUniqueId(), status);
             return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
         }
+        status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
+        if (status != TitanOperationStatus.OK) {
+            log.debug("Failed to disassociate capabilities properties for {} error {}", toscaElementVertex.getUniqueId(), status);
+            Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+        }
         status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CALCULATED_CAPABILITIES);
         if (status != TitanOperationStatus.OK) {
             log.debug("Failed to disassociate calculated capabiliites for {} error {}", toscaElementVertex.getUniqueId(), status);
@@ -1499,10 +1527,6 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
         }
     }
 
-    private GraphVertex throwStorageException(TitanOperationStatus status) {
-        throw new StorageException(status);
-    }
-
     private ToscaElement getOriginToscaElement(ComponentInstanceDataDefinition instance) {
         log.debug("#getOriginToscaElement - origin name: {}", instance.getComponentName());
         ToscaElementTypeEnum elementType = detectToscaType(instance.getOriginType());
@@ -1536,11 +1560,12 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
         filter.setIgnoreRequirements(false);
         return filter;
     }
-    public void updateCapReqOwnerId(String componentId, TopologyTemplate toscaElement) {
+    public void updateCapReqPropertiesOwnerId(String componentId, TopologyTemplate toscaElement) {
         GraphVertex toscaElementV = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse)
                 .left().on(this::throwStorageException);
         updateCapOwnerId(toscaElement, componentId);
         updateReqOwnerId(toscaElement, componentId);
+        updatePropertiesOwnerId(toscaElement, componentId);
         topologyTemplateOperation
 
                 .updateFullToscaData(toscaElementV, EdgeLabelEnum.CAPABILITIES,
@@ -1548,6 +1573,9 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
         topologyTemplateOperation
                 .updateFullToscaData(toscaElementV, EdgeLabelEnum.REQUIREMENTS,
                         VertexTypeEnum.REQUIREMENTS, toscaElement.getRequirements());
+        topologyTemplateOperation
+                .updateFullToscaData(toscaElementV, EdgeLabelEnum.PROPERTIES,
+                        VertexTypeEnum.PROPERTIES, toscaElement.getProperties());
     }
 
     private void updateCapOwnerId(ToscaElement toscaElement, String ownerId) {
@@ -1564,4 +1592,11 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
         }
     }
 
+    private void updatePropertiesOwnerId(ToscaElement toscaElement, String ownerId) {
+        Map<String, PropertyDataDefinition> properties = toscaElement.getProperties();
+        if(MapUtils.isNotEmpty(properties)) {
+            properties.values().forEach(propertyDataDefinition -> propertyDataDefinition.setParentUniqueId(ownerId));
+        }
+    }
+
 }
index 10dd919..228faeb 100644 (file)
@@ -1166,23 +1166,28 @@ public class ToscaOperationFacade {
 
     public Either<Map<String, List<ComponentInstanceProperty>>, StorageOperationStatus> addComponentInstancePropertiesToComponent(Component containerComponent, Map<String, List<ComponentInstanceProperty>> instProperties) {
         requireNonNull(instProperties);
-        StorageOperationStatus status;
+        StorageOperationStatus status = null;
         for (Entry<String, List<ComponentInstanceProperty>> entry : instProperties.entrySet()) {
             List<ComponentInstanceProperty> props = entry.getValue();
             String componentInstanceId = entry.getKey();
-            List<ComponentInstanceProperty> instanceProperties = containerComponent.getComponentInstancesProperties().get(componentInstanceId);
+
+            Map<String, List<CapabilityDefinition>> containerComponentCapabilities = containerComponent.getCapabilities();
+
             if (!isEmpty(props)) {
                 for (ComponentInstanceProperty property : props) {
-                    Optional<ComponentInstanceProperty> instanceProperty = instanceProperties.stream()
-                            .filter(p -> p.getUniqueId().equals(property.getUniqueId()))
-                            .findAny();
-                    if (instanceProperty.isPresent()) {
-                        status = updateComponentInstanceProperty(containerComponent, componentInstanceId, property);
-                    } else {
-                        status = addComponentInstanceProperty(containerComponent, componentInstanceId, property);
+                    String propertyParentUniqueId = property.getParentUniqueId();
+                    Optional<CapabilityDefinition>
+                            capPropDefinition = getPropertyCapability(propertyParentUniqueId, containerComponent);
+                    if(capPropDefinition.isPresent() && MapUtils.isNotEmpty(containerComponentCapabilities)) {
+                        status = populateAndUpdateInstanceCapProperty(containerComponent, componentInstanceId,
+                                containerComponentCapabilities, property, capPropDefinition.get());
                     }
-                    if (status != StorageOperationStatus.OK) {
-                        log.debug("Failed to update instance property {} for instance {} error {} ", property, componentInstanceId, status);
+                    if(status ==  null) {
+                        List<ComponentInstanceProperty> instanceProperties = containerComponent
+                                .getComponentInstancesProperties().get(componentInstanceId);
+                        status = updateInstanceProperty(containerComponent, componentInstanceId, instanceProperties, property);
+                    }
+                    if(status != StorageOperationStatus.OK) {
                         return Either.right(status);
                     }
                 }
@@ -1191,6 +1196,104 @@ public class ToscaOperationFacade {
         return Either.left(instProperties);
     }
 
+    private StorageOperationStatus populateAndUpdateInstanceCapProperty(Component containerComponent, String componentInstanceId,
+                                                                        Map<String, List<CapabilityDefinition>> containerComponentCapabilities,
+                                                                        ComponentInstanceProperty property,
+                                                                        CapabilityDefinition capabilityDefinition) {
+        List<CapabilityDefinition> capabilityDefinitions = containerComponentCapabilities.get(capabilityDefinition.getType());
+        if(CollectionUtils.isEmpty(capabilityDefinitions)) {
+            return null;
+        }
+        Optional<CapabilityDefinition> capDefToGetProp = capabilityDefinitions.stream()
+                .filter(cap -> cap.getUniqueId().equals(capabilityDefinition.getUniqueId()) && cap.getPath().size() == 1).findAny();
+        if(capDefToGetProp.isPresent()) {
+            return updateInstanceCapabilityProperty(containerComponent, componentInstanceId, property, capDefToGetProp.get());
+        }
+        return null;
+    }
+
+    private static Optional<CapabilityDefinition> getPropertyCapability(String propertyParentUniqueId,
+                                                                        Component containerComponent) {
+
+        Map<String, List<CapabilityDefinition>> componentCapabilities = containerComponent.getCapabilities();
+        if(MapUtils.isEmpty(componentCapabilities)){
+            return Optional.empty();
+        }
+        List<CapabilityDefinition> capabilityDefinitionList = componentCapabilities.values()
+                .stream().flatMap(Collection::stream).collect(Collectors.toList());
+        if(CollectionUtils.isEmpty(capabilityDefinitionList)){
+            return Optional.empty();
+        }
+        return capabilityDefinitionList.stream()
+                .filter(capabilityDefinition -> capabilityDefinition.getUniqueId().equals(propertyParentUniqueId))
+                .findAny();
+    }
+
+    private StorageOperationStatus updateInstanceProperty(Component containerComponent, String componentInstanceId,
+                                                          List<ComponentInstanceProperty> instanceProperties,
+                                                          ComponentInstanceProperty property) {
+        StorageOperationStatus status;
+        Optional<ComponentInstanceProperty> instanceProperty = instanceProperties.stream()
+                .filter(p -> p.getUniqueId().equals(property.getUniqueId()))
+                .findAny();
+        if (instanceProperty.isPresent()) {
+            status = updateComponentInstanceProperty(containerComponent, componentInstanceId, property);
+        } else {
+            status = addComponentInstanceProperty(containerComponent, componentInstanceId, property);
+        }
+        if (status != StorageOperationStatus.OK) {
+            log.debug("Failed to update instance property {} for instance {} error {} ", property, componentInstanceId, status);
+            return status;
+        }
+        return StorageOperationStatus.OK;
+    }
+
+    public StorageOperationStatus updateInstanceCapabilityProperty(Component containerComponent, String componentInstanceId,
+                                                                   ComponentInstanceProperty property,
+                                                                   CapabilityDefinition capabilityDefinition) {
+        Optional<ComponentInstance> fetchedCIOptional = containerComponent.getComponentInstanceById(componentInstanceId);
+        if(!fetchedCIOptional.isPresent()) {
+            return StorageOperationStatus.GENERAL_ERROR;
+        }
+        Either<Component, StorageOperationStatus> getComponentRes =
+                getToscaFullElement(fetchedCIOptional.get().getComponentUid());
+        if(getComponentRes.isRight()) {
+            return StorageOperationStatus.GENERAL_ERROR;
+        }
+        Optional<Component> componentOptional = isNodeServiceProxy(getComponentRes.left().value());
+        String propOwner;
+        if(!componentOptional.isPresent()) {
+            propOwner = componentInstanceId;
+        } else {
+            propOwner = fetchedCIOptional.get().getSourceModelUid();
+        }
+        StorageOperationStatus status;
+        StringBuffer sb = new StringBuffer(componentInstanceId);
+        sb.append(ModelConverter.CAP_PROP_DELIM).append(propOwner).append(ModelConverter.CAP_PROP_DELIM)
+                .append(capabilityDefinition.getType()).append(ModelConverter.CAP_PROP_DELIM).append(capabilityDefinition.getName());
+        String capKey = sb.toString();
+        status = updateComponentInstanceCapabiltyProperty(containerComponent, componentInstanceId, capKey, property);
+        if (status != StorageOperationStatus.OK) {
+            log.debug("Failed to update instance capability property {} for instance {} error {} ", property,
+                    componentInstanceId, status);
+            return status;
+        }
+        return StorageOperationStatus.OK;
+    }
+
+    private Optional<Component> isNodeServiceProxy(Component component) {
+        if (component.getComponentType().equals(ComponentTypeEnum.SERVICE)) {
+            return Optional.empty();
+        }
+        Resource resource = (Resource) component;
+        ResourceTypeEnum resType = resource.getResourceType();
+        if(resType.equals(ResourceTypeEnum.ServiceProxy))  {
+            return Optional.of(component);
+        }
+        return Optional.empty();
+    }
+
+
     public StorageOperationStatus associateDeploymentArtifactsToInstances(Map<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts, String componentId, User user) {
 
         Either<GraphVertex, TitanOperationStatus> getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse);
@@ -2554,8 +2657,8 @@ public class ToscaOperationFacade {
         }
         return Either.left(parentComponents);
     }
-    public void updateCapReqOwnerId(String componentId) {
+    public void updateCapReqPropertiesOwnerId(String componentId) {
         topologyTemplateOperation
-                .updateCapReqOwnerId(componentId, getTopologyTemplate(componentId));
+                .updateCapReqPropertiesOwnerId(componentId, getTopologyTemplate(componentId));
     }
 }
index 808fdbd..9514731 100644 (file)
@@ -459,7 +459,9 @@ public class ModelConverter {
             if (CollectionUtils.isNotEmpty(capPrps)) {
                 MapPropertiesDataDefinition dataToCreate = new MapPropertiesDataDefinition();
                 for (ComponentInstanceProperty cip : capPrps) {
-                    dataToCreate.put(cip.getName(), new PropertyDataDefinition(cip));
+                    PropertyDataDefinition propertyDataDefinition = new PropertyDataDefinition(cip);
+                    propertyDataDefinition.setParentUniqueId(cap.getUniqueId());
+                    dataToCreate.put(cip.getName(), propertyDataDefinition);
                 }
                 toscaCapPropMap.put(s + CAP_PROP_DELIM + cap.getName(), dataToCreate);
             }
@@ -1358,16 +1360,51 @@ public class ModelConverter {
 
     private static void setCapabilitiesToComponent(TopologyTemplate topologyTemplate, Component component) {
         Map<String, ListCapabilityDataDefinition> capabilities = topologyTemplate.getCapabilities();
-        Map<String, List<CapabilityDefinition>> componentCapabilities = component.getCapabilities();
+        Map<String, MapPropertiesDataDefinition> capabilitiesProperties = topologyTemplate.getCapabilitiesProperties();
+        Map<String, List<CapabilityDefinition>> allCapabilities = new HashMap<>();
+
         if(MapUtils.isNotEmpty(capabilities)) {
-            if(componentCapabilities == null) {
-                componentCapabilities = new HashMap<>();
-            }
-            componentCapabilities.putAll(groupCapabilityByType(capabilities));
-            component.setCapabilities(componentCapabilities);
+            allCapabilities.putAll(groupCapabilityByType(capabilities));
+        }
+
+        if(MapUtils.isNotEmpty(capabilitiesProperties)) {
+            capabilitiesProperties.forEach((s, capProp)-> {
+                        String[] result = s.split(CAP_PROP_DELIM);
+                        if (capProp != null) {
+                            Map<String, PropertyDataDefinition> capMap = capProp.getMapToscaDataDefinition();
+
+                            if (MapUtils.isNotEmpty(capMap)) {
+                                List<ComponentInstanceProperty> capPropsList = capMap.values().stream()
+                                        .map(ComponentInstanceProperty::new).collect(Collectors.toList());
+
+                                List<CapabilityDefinition> cap = allCapabilities.get(result[0]);
+                                if (cap !=null) {
+                                    Optional<CapabilityDefinition> op = cap.stream().filter(c -> c.getName()
+                                            .equals(result[1])).findFirst();
+                                    op.ifPresent(capabilityDefinition -> capabilityDefinition.setProperties(capPropsList));
+                                }
+                            }
+                        }
+                    }
+            );
+        }
+        Map<String, List<CapabilityDefinition>> componentCapabilities = component.getCapabilities();
+        if(MapUtils.isNotEmpty(componentCapabilities)) {
+            mergeCapabilityMap(allCapabilities, componentCapabilities);
         }
+        component.setCapabilities(allCapabilities);
+    }
 
+    private static void mergeCapabilityMap(Map<String, List<CapabilityDefinition>> map1,
+                                           Map<String, List<CapabilityDefinition>> map2) {
+        map1.forEach((key1, val1) -> map2.forEach((key2, val2) -> {
+            if(key1.equals(key2)) {
+                val2.addAll(val1);
+            }
+        }));
+        map1.putAll(map2);
     }
+
     private static Map<String, List<CapabilityDefinition>> groupCapabilityByType(Map<String,
             ListCapabilityDataDefinition> capabilities) {
         Map<String, List<CapabilityDefinition>>  groupedCapabilities = new HashMap<>();
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperationTest.java
new file mode 100644 (file)
index 0000000..0c9c35b
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright Â© 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.model.jsontitan.operations;
+
+import fj.data.Either;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
+import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
+import org.openecomp.sdc.be.model.jsontitan.utils.CapabilityTestUtils;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyMap;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
+
+public class CapabilitiesOperationTest {
+
+    @InjectMocks
+    CapabilitiesOperation operation = new CapabilitiesOperation();
+    @Mock
+    private  TitanDao mockTitanDao;
+    @Mock
+    private TopologyTemplateOperation topologyTemplateOperation;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        when(mockTitanDao.commit()).thenReturn(TitanOperationStatus.OK);
+        when(mockTitanDao.getVertexById(anyString(), any())).thenReturn(Either.left(new GraphVertex()));
+
+        when(topologyTemplateOperation.updateFullToscaData(any(), any(), any(), anyMap())).thenReturn(StorageOperationStatus.OK);
+        TopologyTemplate topologyTemplate = new TopologyTemplate();
+
+        Map<String, MapPropertiesDataDefinition> capPropsForTopologyTemplate = CapabilityTestUtils
+                .createCapPropsForTopologyTemplate(topologyTemplate);
+        topologyTemplate.setCapabilitiesProperties(capPropsForTopologyTemplate);
+
+        when(topologyTemplateOperation.getToscaElement(anyString(), any())).thenReturn(Either.left(topologyTemplate));
+    }
+
+    @Test
+    public void testCreateOrUpdateCapabilitiesProperties() {
+
+        Map<String, PropertyDataDefinition> mapToscaDataDefinition = new HashMap<>();
+        PropertyDataDefinition propertyDataDefinition = new PropertyDataDefinition();
+        propertyDataDefinition.setUniqueId("ComponentInput1_uniqueId");
+        propertyDataDefinition.setName("propName");
+        mapToscaDataDefinition.put(propertyDataDefinition.getUniqueId(), propertyDataDefinition);
+        MapPropertiesDataDefinition  mapPropertiesDataDefinition = new MapPropertiesDataDefinition(mapToscaDataDefinition);
+
+        Map<String, MapPropertiesDataDefinition> propertiesMap = new HashMap<>();
+        propertiesMap.put(propertyDataDefinition.getUniqueId(), mapPropertiesDataDefinition);
+
+        StorageOperationStatus operationStatus = operation.createOrUpdateCapabilityProperties("componentId",
+                propertiesMap);
+
+        Assert.assertEquals(StorageOperationStatus.OK, operationStatus);
+    }
+}
\ No newline at end of file
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/CapabilityTestUtils.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/CapabilityTestUtils.java
new file mode 100644 (file)
index 0000000..6f6b7ea
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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.model.jsontitan.utils;
+
+import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
+import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class CapabilityTestUtils {
+
+    public static Map<String, MapPropertiesDataDefinition> createCapPropsForTopologyTemplate(TopologyTemplate topologyTemplate) {
+        Map<String, ListCapabilityDataDefinition> capabilitiesMap = new HashMap<>();
+
+        List<CapabilityDataDefinition> capabilityDefinitions = new ArrayList<>();
+        CapabilityDefinition capabilityDefinition = createCapabilityDefinition();
+
+        capabilityDefinitions.add(capabilityDefinition);
+        ListCapabilityDataDefinition listCapabilityDataDefinition = new ListCapabilityDataDefinition(capabilityDefinitions);
+        capabilitiesMap.put(capabilityDefinition.getType(), listCapabilityDataDefinition);
+        topologyTemplate.setCapabilities(capabilitiesMap);
+
+        List<ComponentInstanceProperty> capPropList = new ArrayList<>();
+        ComponentInstanceProperty instanceProperty = createProperties();
+        capPropList.add(instanceProperty);
+
+        MapPropertiesDataDefinition dataToCreate = new MapPropertiesDataDefinition();
+        for (ComponentInstanceProperty cip : capPropList) {
+            PropertyDataDefinition propertyDataDefinition = new PropertyDataDefinition(cip);
+            dataToCreate.put(cip.getName(), propertyDataDefinition);
+        }
+
+        Map<String, MapPropertiesDataDefinition> capabilitiesProperties = new HashMap<>();
+        capabilitiesProperties.put(capabilityDefinition.getType() + ModelConverter.CAP_PROP_DELIM +
+                capabilityDefinition.getName(), dataToCreate);
+        return capabilitiesProperties;
+    }
+
+    private static CapabilityDefinition createCapabilityDefinition() {
+        CapabilityDefinition capabilityDefinition = new CapabilityDefinition();
+        capabilityDefinition.setName("cap" + Math.random());
+        capabilityDefinition.setType("tosca.capabilities.network.Bindable");
+        capabilityDefinition.setOwnerId("resourceId");
+        capabilityDefinition.setUniqueId("capUniqueId");
+        List<String> path = new ArrayList<>();
+        path.add("path1");
+        capabilityDefinition.setPath(path);
+        return capabilityDefinition;
+    }
+
+    private static ComponentInstanceProperty createProperties() {
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setUniqueId("ComponentInput1_uniqueId");
+        instanceProperty.setType("Integer");
+        instanceProperty.setName("prop_name");
+        instanceProperty.setDescription("prop_description_prop_desc");
+        instanceProperty.setOwnerId("capUniqueId");
+        instanceProperty.setValue("{\"get_input\":\"extcp20_order\"}");
+        instanceProperty.setSchema(new SchemaDefinition());
+        return instanceProperty;
+    }
+}
index f8713c6..a927f5a 100644 (file)
@@ -34,6 +34,7 @@ import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
+import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
 import org.openecomp.sdc.be.model.Resource;
@@ -42,6 +43,9 @@ import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
+
+import java.util.Map;
+
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
@@ -78,6 +82,21 @@ public class ModelConverterTest {
         assertThat(component.getToscaType()).isEqualTo(ToscaElementTypeEnum.TOPOLOGY_TEMPLATE.getValue());
     }
 
+    @Test
+    public void testConvertFromToscaElementServiceWithSelfCapabilities()
+    {
+        TopologyTemplate topologyTemplate = new TopologyTemplate();
+
+        Map<String, MapPropertiesDataDefinition> capabilitiesProperties = CapabilityTestUtils
+                .createCapPropsForTopologyTemplate(topologyTemplate);
+
+        topologyTemplate.setCapabilitiesProperties(capabilitiesProperties);
+
+        topologyTemplate.setComponentType(ComponentTypeEnum.SERVICE);
+        Component component = test.convertFromToscaElement(topologyTemplate);
+        assertThat(component.getToscaType()).isEqualTo(ToscaElementTypeEnum.TOPOLOGY_TEMPLATE.getValue());
+    }
+
     @Test
     public void testConvertFromToscaElementResource()
     {
index fc01f54..278d3d3 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 import {ToscaPresentationData} from "./tosca-presentation";
+import {PropertyModel} from "./properties";
 
 export class CapabilityTypesMap {
     capabilityTypesMap: CapabilityTypesMapData;
@@ -30,12 +31,14 @@ export class CapabilityTypesMapData {
 
 export class CapabilityTypeModel {
     derivedFrom: string;
+    properties: Array<PropertyModel>;
     toscaPresentation: ToscaPresentationData;
 
     constructor(capabilityType?: CapabilityTypeModel) {
         if (capabilityType) {
             this.derivedFrom = capabilityType.derivedFrom;
             this.toscaPresentation = capabilityType.toscaPresentation;
+            this.properties = capabilityType.properties;
         }
     }
 }
\ No newline at end of file
index caef2e8..4a4f821 100644 (file)
@@ -45,6 +45,13 @@ export class CapabilitiesGroup {
         });
         return this[key];
     }
+
+    public static getFlattenedCapabilities(capabilitiesGroup: CapabilitiesGroup): Array<Capability> {
+        return _.reduce(
+            _.toArray(capabilitiesGroup),
+            (allCaps, capArr) => allCaps.concat(capArr),
+            []);
+    }
 }
 
 export class Capability implements RequirementCapabilityModel{
index 15b9534..5d25142 100644 (file)
@@ -18,7 +18,7 @@
  * ============LICENSE_END=========================================================
  */
 
-import { PropertyInputDetail, SchemaPropertyGroupModel, SchemaProperty } from "app/models";
+import {PropertyInputDetail, SchemaPropertyGroupModel, SchemaProperty, ToscaPresentationData} from "app/models";
 import { PROPERTY_DATA, PROPERTY_TYPES } from 'app/utils';
 export enum DerivedPropertyType {
     SIMPLE,
@@ -47,6 +47,7 @@ export class PropertyBEModel {
     getInputValues: Array<PropertyInputDetail>;
     getPolicyValues: Array<PropertyPolicyDetail>;
     name: string;
+    origName: string;
     parentUniqueId: string;
     password: boolean;
     required: boolean;
@@ -58,6 +59,7 @@ export class PropertyBEModel {
     parentPropertyType: string;
     subPropertyInputPath: string;
     inputPath: string;
+    toscaPresentation: ToscaPresentationData;
 
     constructor(property?: PropertyBEModel) {
         if (property) {
@@ -66,6 +68,7 @@ export class PropertyBEModel {
             this.description = property.description;
             this.fromDerived = property.fromDerived;
             this.name = property.name;
+            this.origName = property.origName;
             this.parentUniqueId = property.parentUniqueId;
             this.password = property.password;
             this.required = property.required;
@@ -78,6 +81,7 @@ export class PropertyBEModel {
             this.getInputValues = property.getInputValues;
             this.parentPropertyType = property.parentPropertyType;
             this.subPropertyInputPath = property.subPropertyInputPath;
+            this.toscaPresentation = property.toscaPresentation;
             this.getPolicyValues = property.getPolicyValues;
             this.inputPath = property.inputPath;
         }
index c0af885..664d128 100644 (file)
@@ -40,6 +40,7 @@ export class PropertyFEModel extends PropertyBEModel {
     valueObjOrig: any; //this is valueObj representation as saved in server
     valueObjIsChanged: boolean;
     derivedDataType: DerivedPropertyType;
+    origName: string;
 
     constructor(property: PropertyBEModel){
         super(property);
@@ -52,6 +53,7 @@ export class PropertyFEModel extends PropertyBEModel {
         this.valueObj = null;
         this.updateValueObjOrig();
         this.resetValueObjValidation();
+        this.origName = this.name;
     }
 
 
index 3fdddde..7cdc5c6 100644 (file)
@@ -21,6 +21,7 @@ export class ToscaPresentationData {
     validTargetTypes: Array<string>;
     modificationTime: number;
     uniqueId: string;
+    ownerId: string;
 
     constructor(toscaPresentation?: ToscaPresentationData) {
         if (toscaPresentation) {
@@ -30,6 +31,7 @@ export class ToscaPresentationData {
             this.validTargetTypes = toscaPresentation.validTargetTypes;
             this.modificationTime = toscaPresentation.modificationTime;
             this.uniqueId = toscaPresentation.uniqueId;
+            this.ownerId = toscaPresentation.ownerId;
         }
     }
 }
index 126f99f..720d29f 100644 (file)
@@ -249,7 +249,7 @@ directiveModule.directive('ng2ServicePathSelector', downgradeComponent({
 
 directiveModule.directive('ng2ServiceConsumption', downgradeComponent({
     component: ServiceConsumptionComponent,
-    inputs: ['parentService', 'selectedService', 'selectedServiceInstanceId', 'instancesMappedList','parentServiceInputs', 'readonly'],
+    inputs: ['parentService', 'selectedService', 'selectedServiceInstanceId', 'instancesMappedList', 'parentServiceInputs', 'instancesCapabilitiesMap', 'readonly'],
     outputs: []
 }) as angular.IDirectiveFactory);
 
index ef8d63d..ebcf9eb 100644 (file)
@@ -29,7 +29,9 @@ import {
     PropertyFEModel,
     PropertyBEModel,
     InputBEModel,
-    InterfaceModel
+    InterfaceModel,
+    CapabilitiesGroup,
+    Capability
 } from 'app/models';
 import {ServiceConsumptionCreatorComponent} from 'app/ng2/pages/service-consumption-editor/service-consumption-editor.component';
 
@@ -59,6 +61,7 @@ export class ConsumptionInputDetails extends ConsumptionInput {
     assignValueLabel: string;
     associatedProps: Array<string>;
     associatedInterfaces: Array<any>;
+    associatedCapabilities: Array<Capability>;
     origVal: string;
     isValid: boolean;
 
@@ -70,6 +73,7 @@ export class ConsumptionInputDetails extends ConsumptionInput {
             this.assignValueLabel = input.assignValueLabel;
             this.associatedProps = input.associatedProps;
             this.associatedInterfaces = input.associatedInterfaces;
+            this.associatedCapabilities = input.associatedCapabilities;
             this.origVal = input.value || "";
             this.isValid = input.isValid;
         }
@@ -128,15 +132,18 @@ export class ServiceConsumptionComponent {
     @Input() selectedService: Service;
     @Input() selectedServiceInstanceId: string;
     @Input() instancesMappedList: Array<ServiceInstanceObject>;
+    @Input() instancesCapabilitiesMap: Map<string, Array<Capability>>;
     @Input() readonly: boolean;
 
     selectedInstanceSiblings: Array<ServiceInstanceObject>;
     selectedInstancePropertiesList: Array<PropertyBEModel> = [];
+    selectedInstanceCapabilitisList: Array<Capability> = [];
 
     constructor(private ModalServiceNg2: ModalService, private serviceServiceNg2: ServiceServiceNg2, private componentServiceNg2: ComponentServiceNg2, private componentInstanceServiceNg2:ComponentInstanceServiceNg2) {}
 
     ngOnInit() {
         this.updateSelectedInstancePropertiesAndSiblings();
+        this.updateSelectedServiceCapabilities();
     }
 
     ngOnChanges(changes) {
@@ -146,9 +153,11 @@ export class ServiceConsumptionComponent {
                 this.selectedService = changes.selectedService.currentValue;
             }
             this.updateSelectedInstancePropertiesAndSiblings();
+            this.updateSelectedServiceCapabilities();
         }
         if(changes.instancesMappedList && !_.isEqual(changes.instancesMappedList.currentValue, changes.instancesMappedList.previousValue)) {
             this.updateSelectedInstancePropertiesAndSiblings();
+            this.updateSelectedServiceCapabilities();
         }
     }
 
@@ -166,6 +175,13 @@ export class ServiceConsumptionComponent {
         this.selectedInstanceSiblings = _.filter(this.instancesMappedList, coInstance => coInstance.id !== this.selectedServiceInstanceId);
     }
 
+    updateSelectedServiceCapabilities() {
+        this.selectedInstanceCapabilitisList = _.filter(
+            CapabilitiesGroup.getFlattenedCapabilities(this.selectedService.capabilities),
+            cap => cap.properties && cap.ownerId === this.selectedService.uniqueId
+        );
+    }
+
     expandCollapseInterfaceGroup(currInterface) {
         currInterface.isExpanded = !currInterface.isExpanded;
     }
@@ -190,7 +206,9 @@ export class ServiceConsumptionComponent {
                     parentServiceInputs: this.parentServiceInputs,
                     selectedServiceProperties: this.selectedInstancePropertiesList,
                     selectedServiceInstanceId: this.selectedServiceInstanceId,
-                    selectedInstanceSiblings: this.selectedInstanceSiblings
+                    selectedInstanceSiblings: this.selectedInstanceSiblings,
+                    selectedInstanceCapabilitisList: this.selectedInstanceCapabilitisList,
+                    siblingsCapabilitiesList: this.instancesCapabilitiesMap
                 }
             );
             this.modalInstance.instance.open();
index 7c0f232..b30cf23 100644 (file)
@@ -9,14 +9,20 @@ import {Observable} from "rxjs/Observable";
 
 import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component';
 import {ModalService} from 'app/ng2/services/modal.service';
-import {ModalModel, ButtonModel, InputBEModel, OperationModel, InterfaceModel, WORKFLOW_ASSOCIATION_OPTIONS} from 'app/models';
+import {
+    InputBEModel,
+    OperationModel,
+    InterfaceModel,
+    WORKFLOW_ASSOCIATION_OPTIONS,
+    CapabilitiesGroup,
+    Capability
+} from 'app/models';
 
 import {IModalConfig, IModalButtonComponent} from "sdc-ui/lib/angular/modals/models/modal-config";
 import {SdcUiComponents} from "sdc-ui/lib/angular";
 import {ModalButtonComponent} from "sdc-ui/lib/angular/components";
 
 import {ComponentServiceNg2} from 'app/ng2/services/component-services/component.service';
-import {ComponentGenericResponse} from 'app/ng2/services/responses/component-generic-response';
 import {WorkflowServiceNg2} from 'app/ng2/services/workflow.service';
 import {PluginsService} from "app/ng2/services/plugins.service";
 
@@ -114,6 +120,7 @@ export class InterfaceOperationComponent {
     modalTranslation: ModalTranslation;
     workflowIsOnline: boolean;
     workflows: Array<any>;
+    capabilities: CapabilitiesGroup;
 
     @Input() component: IComponent;
     @Input() readonly: boolean;
@@ -141,7 +148,8 @@ export class InterfaceOperationComponent {
         Observable.forkJoin(
             this.ComponentServiceNg2.getInterfaces(this.component),
             this.ComponentServiceNg2.getComponentInputs(this.component),
-            this.ComponentServiceNg2.getInterfaceTypes(this.component)
+            this.ComponentServiceNg2.getInterfaceTypes(this.component),
+            this.ComponentServiceNg2.getCapabilitiesAndRequirements(this.component.componentType, this.component.uniqueId)
         ).subscribe((response: Array<any>) => {
             const callback = (workflows) => {
                 this.isLoading = false;
@@ -150,6 +158,7 @@ export class InterfaceOperationComponent {
                 this.inputs = response[1].inputs;
                 this.interfaceTypes = response[2];
                 this.workflows = workflows;
+                this.capabilities = response[3].capabilities;
             };
             if (this.enableWorkflowAssociation && this.workflowIsOnline) {
                 this.WorkflowServiceNg2.getWorkflows().subscribe(
@@ -267,7 +276,8 @@ export class InterfaceOperationComponent {
             readonly: this.readonly,
             interfaceTypes: this.interfaceTypes,
             validityChangedCallback: this.enableOrDisableSaveButton,
-            workflowIsOnline: this.workflowIsOnline
+            workflowIsOnline: this.workflowIsOnline,
+            capabilities: _.filter(CapabilitiesGroup.getFlattenedCapabilities(this.capabilities), (capability: Capability) => capability.ownerId === this.component.uniqueId)
         };
 
         const modalConfig: IModalConfig = {
index 5faddd8..6373094 100644 (file)
             </div>
 
             <param-row
-                *ngFor="let param of tableParameters"
-                class="data-row"
-                [isInputParam]="currentTab === TYPE_INPUT"
-                [isAssociateWorkflow]="isUsingExistingWF()"
-                [param]="param"
-                [inputProps]="inputProperties"
-                [operationOutputs]="operationOutputs"
-                [onRemoveParam]="onRemoveParam"
-                [readonly]="readonly"
-                [validityChanged]="validityChanged">
+                    *ngFor="let param of tableParameters"
+                    class="data-row"
+                    [isInputParam]="currentTab === TYPE_INPUT"
+                    [isAssociateWorkflow]="isUsingExistingWF()"
+                    [param]="param"
+                    [inputProps]="inputProperties"
+                    [capabilitiesProps]="componentCapabilities"
+                    [operationOutputs]="operationOutputs"
+                    [onRemoveParam]="onRemoveParam"
+                    [readonly]="readonly"
+                    [validityChanged]="validityChanged">
             </param-row>
         </div>
 
index 7b36062..a1dccce 100644 (file)
@@ -5,7 +5,15 @@ import {Subscription} from "rxjs/Subscription";
 
 import {TranslateService} from "app/ng2/shared/translator/translate.service";
 import {WorkflowServiceNg2} from 'app/ng2/services/workflow.service';
-import {InterfaceModel, OperationModel, OperationParameter, InputBEModel, RadioButtonModel, WORKFLOW_ASSOCIATION_OPTIONS} from 'app/models';
+import {
+    InterfaceModel,
+    OperationModel,
+    OperationParameter,
+    InputBEModel,
+    RadioButtonModel,
+    WORKFLOW_ASSOCIATION_OPTIONS,
+    Capability
+} from 'app/models';
 
 import {IDropDownOption} from "sdc-ui/lib/angular/form-elements/dropdown/dropdown-models";
 import {Tabs, Tab} from "app/ng2/components/ui/tabs/tabs.component";
@@ -39,7 +47,8 @@ export interface OperationCreatorInput {
     readonly: boolean,
     interfaceTypes: { [interfaceType: string]: Array<string> },
     validityChangedCallback: Function,
-    workflowIsOnline: boolean;
+    workflowIsOnline: boolean,
+    capabilities: Array<Capability>
 }
 
 @Component({
@@ -59,6 +68,7 @@ export class OperationCreatorComponent implements OperationCreatorInput {
     interfaceTypes: { [interfaceType: string]: Array<string> };
     operationNames: Array<TypedDropDownOption> = [];
     validityChangedCallback: Function;
+    capabilities: Array<Capability>;
 
     allWorkflows: Array<any>;
     workflows: Array<DropdownValue> = [];
@@ -73,6 +83,7 @@ export class OperationCreatorComponent implements OperationCreatorInput {
     outputParameters: Array<OperationParameter> = [];
     noAssignOutputParameters: Array<OperationParameter> = [];
     assignOutputParameters: { [key: string]: { [key: string]: Array<OperationParameter>; }; } = {};
+    componentCapabilities: Array<Capability> = [];
 
     tableParameters: Array<OperationParameter> = [];
     operationOutputs: Array<OperationModel> = [];
@@ -171,6 +182,7 @@ export class OperationCreatorComponent implements OperationCreatorInput {
             }
         }
         this.reconstructOperation();
+        this.filterCapabilities();
         this.validityChanged();
         this.updateTable();
     }
@@ -215,6 +227,10 @@ export class OperationCreatorComponent implements OperationCreatorInput {
 
     }
 
+    filterCapabilities() {
+        this.componentCapabilities = _.filter(this.capabilities, (cap: Capability) => cap.properties);
+    }
+
     buildParams = () => {
 
         if (this.inputOperation.outputs) {
index 3ac9328..4a4782e 100644 (file)
                 {{output.label}}
             </option>
         </optgroup>
+        <optgroup
+                *ngFor="let cap of filteredCapabilitiesProps"
+                label="{{cap.capabilityName}}">
+            <option
+                    *ngFor="let prop of cap.properties"
+                    [ngValue]="prop.value">
+                {{prop.label}}
+            </option>
+        </optgroup>
     </select>
     <span
         *ngIf="!filteredInputProps.length && !operationOutputCats.length && isAssociateWorkflow"
index bdf1003..c18fb82 100644 (file)
@@ -1,7 +1,6 @@
 import {Component, Input} from '@angular/core';
 import {DataTypeService} from "app/ng2/services/data-type.service";
-import {OperationModel, OperationParameter, InputBEModel, DataTypeModel} from 'app/models';
-import {DropDownOption} from "../operation-creator.component";
+import {OperationModel, OperationParameter, InputBEModel, DataTypeModel, Capability} from 'app/models';
 import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component";
 
 class DropdownValueType extends DropdownValue {
@@ -25,6 +24,7 @@ export class ParamRowComponent {
     @Input() param: OperationParameter;
     @Input() inputProps: Array<InputBEModel>;
     @Input() operationOutputs: Array<OperationModel>;
+    @Input() capabilitiesProps: Array<Capability>;
     @Input() onRemoveParam: Function;
     @Input() isAssociateWorkflow: boolean;
     @Input() readonly: boolean;
@@ -34,6 +34,7 @@ export class ParamRowComponent {
     propTypeEnum: Array<string> = [];
     operationOutputCats: Array<{ operationName: string, outputs: Array<DropdownValueType> }> = [];
     filteredInputProps: Array<DropdownValue> = [];
+    filteredCapabilitiesProps: Array<{capabilityName: string, properties: Array<DropdownValueType>}> = [];
 
     constructor(private dataTypeService: DataTypeService) {}
 
@@ -113,6 +114,26 @@ export class ParamRowComponent {
             category => category.outputs.length > 0
         );
 
+        this.filteredCapabilitiesProps = _.filter(
+            _.map(
+                this.capabilitiesProps,
+                cap => {
+                    return {
+                        capabilityName: cap.name,
+                        properties: _.map(
+                            _.filter(cap.properties, prop => !this.param.type || prop.type === this.param.type),
+                            prop => new DropdownValueType(
+                                prop.uniqueId,
+                                prop.name,
+                                prop.type
+                            )
+                        )
+                    };
+                }
+            ),
+            capability => capability.properties.length > 0
+        );
+
         if (this.param.inputId) {
             const selProp = this.getSelectedProp();
             if (selProp && selProp.type === this.param.type) {
@@ -181,6 +202,12 @@ export class ParamRowComponent {
                 (acc, cat) => [...acc, ...cat.outputs],
             []),
             (out: DropdownValueType) => this.param.inputId === out.value
+            ) || _.find(
+                _.reduce(
+                    this.filteredCapabilitiesProps,
+                    (acc, cap) => [...acc, ...cap.properties],
+                    []),
+                (prop: DropdownValueType) => this.param.inputId === prop.value
         );
     }
 
index 38278c9..4101503 100644 (file)
 import * as _ from "lodash";
 import {Component, ViewChild, Inject, TemplateRef} from "@angular/core";
 import { PropertiesService } from "../../services/properties.service";
-import { PropertyFEModel, InstanceFePropertiesMap, InstanceBePropertiesMap, InstancePropertiesAPIMap, Component as ComponentData, FilterPropertiesAssignmentData, ModalModel, ButtonModel } from "app/models";
+import {
+    PropertyFEModel,
+    InstanceFePropertiesMap,
+    InstanceBePropertiesMap,
+    InstancePropertiesAPIMap,
+    Component as ComponentData,
+    FilterPropertiesAssignmentData,
+    ModalModel,
+    ButtonModel,
+    Capability,
+    ToscaPresentationData
+} from "app/models";
 import { ResourceType } from "app/utils";
 import {ComponentServiceNg2} from "../../services/component-services/component.service";
 import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service"
-import { InputBEModel, InputFEModel, ComponentInstance, GroupInstance, PolicyInstance, PropertyBEModel, DerivedFEProperty, SimpleFlatProperty } from "app/models";
+import {
+    InputBEModel,
+    InputFEModel,
+    ComponentInstance,
+    GroupInstance,
+    PolicyInstance,
+    PropertyBEModel,
+    DerivedFEProperty,
+    SimpleFlatProperty,
+    CapabilitiesGroup
+} from "app/models";
 import { KeysPipe } from 'app/ng2/pipes/keys.pipe';
 import {WorkspaceMode, EVENTS} from "../../../utils/constants";
 import {EventListenerService} from "app/services/event-listener-service"
@@ -44,6 +65,7 @@ import { SdcUiComponents } from "sdc-ui/lib/angular";
 //import { ModalService as ModalServiceSdcUI} from "sdc-ui/lib/angular/modals/modal.service";
 import { IModalButtonComponent } from "sdc-ui/lib/angular/modals/models/modal-config";
 import { UnsavedChangesComponent } from "app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component";
+import {Observable} from "rxjs";
 
 const SERVICE_SELF_TITLE = "SELF";
 @Component({
@@ -90,6 +112,8 @@ export class PropertiesAssignmentComponent {
     savingChangedData:boolean;
     stateChangeStartUnregister:Function;
     serviceBePropertiesMap: InstanceBePropertiesMap;
+    serviceBeCapabilitiesPropertiesMap: InstanceBePropertiesMap;
+    selectedInstance_FlattenCapabilitiesList: Array<Capability>;
 
     @ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs;
     @ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
@@ -237,12 +261,14 @@ export class PropertiesAssignmentComponent {
         this.loadingProperties = true;
         if (instance instanceof ComponentInstance) {
             let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
+            this.selectedInstance_FlattenCapabilitiesList = instance.capabilities ? CapabilitiesGroup.getFlattenedCapabilities(instance.capabilities) : [];
             if (this.isInput(instance.originType)) {
                 this.componentInstanceServiceNg2
                     .getComponentInstanceInputs(this.component, instance)
                     .subscribe(response => {
                         instanceBePropertiesMap[instance.uniqueId] = response;
                         this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
+                        this.processInstanceCapabilitiesPropertiesResponse(false);
                         this.loadingProperties = false;
                     }, error => {
                     }); //ignore error
@@ -254,6 +280,7 @@ export class PropertiesAssignmentComponent {
                     .subscribe(response => {
                         instanceBePropertiesMap[instance.uniqueId] = response;
                         this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
+                        this.processInstanceCapabilitiesPropertiesResponse(false);
                         this.loadingProperties = false;
                     }, error => {
                     }); //ignore error
@@ -298,6 +325,40 @@ export class PropertiesAssignmentComponent {
         this.checkedPropertiesCount = 0;
     };
 
+    processInstanceCapabilitiesPropertiesResponse = (originTypeIsVF: boolean) => {
+        let selectedComponentInstanceData = <ComponentInstance>(this.selectedInstanceData);
+        let currentUniqueId = this.selectedInstanceData.uniqueId;
+        this.serviceBeCapabilitiesPropertiesMap = new InstanceBePropertiesMap();
+        let isCapabilityOwnedByInstance: boolean;
+        this.serviceBeCapabilitiesPropertiesMap[currentUniqueId] = _.reduce(
+            this.selectedInstance_FlattenCapabilitiesList,
+            (result, cap: Capability) => {
+                isCapabilityOwnedByInstance = cap.ownerId === currentUniqueId ||
+                    selectedComponentInstanceData.isServiceProxy() && cap.ownerId === selectedComponentInstanceData.sourceModelUid;
+                if (cap.properties && isCapabilityOwnedByInstance) {
+                    _.forEach(cap.properties, prop => {
+                        if (!prop.origName) {
+                            prop.origName = prop.name;
+                            prop.name = cap.name + '_' + prop.name;//for display. (before save - the name returns to its orig value: prop.name)
+                        }
+                    });
+                    return result.concat(cap.properties);
+                }
+                return result;
+            }, []);
+        let instanceFECapabilitiesPropertiesMap = this.propertiesUtils.convertPropertiesMapToFEAndCreateChildren(this.serviceBeCapabilitiesPropertiesMap, originTypeIsVF, this.inputs); //create flattened children, disable declared props, and init values
+        //update FECapabilitiesProperties with their origName according to BeCapabilitiesProperties
+        _.forEach(instanceFECapabilitiesPropertiesMap[currentUniqueId], prop => {
+            prop.origName = _.find(this.serviceBeCapabilitiesPropertiesMap[currentUniqueId], p => p.uniqueId === prop.uniqueId).origName;
+        });
+        //concatenate capabilitiesProps to all props list
+        this.instanceFePropertiesMap[currentUniqueId] = (this.instanceFePropertiesMap[currentUniqueId] || []).concat(instanceFECapabilitiesPropertiesMap[currentUniqueId]);
+        this.checkedPropertiesCount = 0;
+    };
+
+    isCapabilityProperty = (prop: PropertyBEModel) => {
+        return _.find(this.selectedInstance_FlattenCapabilitiesList, cap => cap.uniqueId === prop.parentUniqueId);
+    };
 
     /*** VALUE CHANGE EVENTS ***/
     dataChanged = (item:PropertyFEModel|InputFEModel) => {
@@ -431,6 +492,33 @@ export class PropertiesAssignmentComponent {
 
         let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
 
+        //move changed capabilities properties from componentInstanceInputsMap obj to componentInstanceProperties
+        inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] =
+            (inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId] || []).concat(
+                _.filter(
+                    inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
+                    (prop: PropertyBEModel) => this.isCapabilityProperty(prop)
+                )
+            );
+        inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId] = _.filter(
+            inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId],
+            prop => !this.isCapabilityProperty(prop)
+        );
+        if (inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId].length === 0) {
+            delete inputsToCreate.componentInstanceInputsMap[this.selectedInstanceData.uniqueId];
+        }
+
+        let isCapabilityPropertyChanged = false;
+        _.forEach(
+            inputsToCreate.componentInstanceProperties[this.selectedInstanceData.uniqueId],
+            (prop: PropertyBEModel) => {
+                prop.name = prop.origName || prop.name;
+                if (this.isCapabilityProperty(prop)) {
+                    isCapabilityPropertyChanged = true;
+                }
+            }
+        );
+
         this.componentServiceNg2
             .createInput(this.component, inputsToCreate, this.isSelf())
             .subscribe(response => {
@@ -442,6 +530,9 @@ export class PropertiesAssignmentComponent {
                     this.inputs.push(newInput);
                     this.updatePropertyValueAfterDeclare(newInput);
                 });
+                if (isCapabilityPropertyChanged) {
+                    this.reloadInstanceCapabilities();
+                }
             }, error => {}); //ignore error
     };
 
@@ -499,18 +590,37 @@ export class PropertiesAssignmentComponent {
             // make request and its handlers
             let request;
             let handleSuccess, handleError;
+            let changedInputsProperties = [], changedCapabilitiesProperties = [];
             if (this.isPropertiesTabSelected) {
                 const changedProperties: PropertyBEModel[] = this.changedData.map((changedProp) => {
                     changedProp = <PropertyFEModel>changedProp;
                     const propBE = new PropertyBEModel(changedProp);
+                    propBE.toscaPresentation = new ToscaPresentationData();
+                    propBE.toscaPresentation.ownerId = changedProp.parentUniqueId;
                     propBE.value = changedProp.getJSONValue();
+                    propBE.name = changedProp.origName || changedProp.name;
+                    delete propBE.origName;
                     return propBE;
                 });
+                changedCapabilitiesProperties = _.filter(changedProperties, prop => this.isCapabilityProperty(prop));
 
                 if (this.selectedInstanceData instanceof ComponentInstance) {
                     if (this.isInput(this.selectedInstanceData.originType)) {
-                        request = this.componentInstanceServiceNg2
-                            .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedProperties);
+                        changedInputsProperties = _.filter(changedProperties, prop => !this.isCapabilityProperty(prop));
+                        if (changedInputsProperties.length && changedCapabilitiesProperties.length) {
+                            request = Observable.forkJoin(
+                                this.componentInstanceServiceNg2.updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties),
+                                this.componentInstanceServiceNg2.updateInstanceProperties(this.component, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties)
+                            );
+                        }
+                        else if (changedInputsProperties.length) {
+                            request = this.componentInstanceServiceNg2
+                                .updateInstanceInputs(this.component, this.selectedInstanceData.uniqueId, changedInputsProperties);
+                        }
+                        else if (changedCapabilitiesProperties.length) {
+                            request = this.componentInstanceServiceNg2
+                                .updateInstanceProperties(this.component, this.selectedInstanceData.uniqueId, changedCapabilitiesProperties);
+                        }
                         handleSuccess = (response) => {
                             // reset each changed property with new value and remove it from changed properties list
                             response.forEach((resInput) => {
@@ -588,6 +698,9 @@ export class PropertiesAssignmentComponent {
             request.subscribe(
                 (response) => {
                     this.savingChangedData = false;
+                    if (changedCapabilitiesProperties.length) {
+                        this.reloadInstanceCapabilities();
+                    }
                     handleSuccess && handleSuccess(response);
                     this.updateHasChangedData();
                     resolve(response);
@@ -602,6 +715,19 @@ export class PropertiesAssignmentComponent {
         });
     };
 
+    reloadInstanceCapabilities = (): void => {
+        let currentInstanceIndex = _.findIndex(this.instances, instance => instance.uniqueId == this.selectedInstanceData.uniqueId);
+        this.componentServiceNg2.getComponentResourceInstances(this.component).subscribe(result => {
+            let instanceCapabilitiesData: CapabilitiesGroup = _.reduce(result.componentInstances, (res, instance) => {
+                if (instance.uniqueId === this.selectedInstanceData.uniqueId) {
+                    return instance.capabilities;
+                }
+                return res;
+            }, new CapabilitiesGroup());
+            (<ComponentInstance>this.instances[currentInstanceIndex]).capabilities = instanceCapabilitiesData;
+        });
+    };
+
     reverseChangedData = ():void => {
         // make reverse item handler
         let handleReverseItem;
@@ -682,8 +808,10 @@ export class PropertiesAssignmentComponent {
 
     updatePropertyValueAfterDeclare = (input: InputFEModel) => {
         if (this.instanceFePropertiesMap[input.instanceUniqueId]) {
+            let instanceName = input.instanceUniqueId.slice(input.instanceUniqueId.lastIndexOf('.') + 1);
             let propertyForUpdatindVal = _.find(this.instanceFePropertiesMap[input.instanceUniqueId], (feProperty: PropertyFEModel) => {
-                return feProperty.name == input.relatedPropertyName;
+                return feProperty.uniqueId === input.propertyId &&
+                    (feProperty.name == input.relatedPropertyName || input.name === instanceName.concat('_').concat(feProperty.name.replace(/[.]/g, '_')));
             });
             let inputPath = (input.inputPath && input.inputPath != propertyForUpdatindVal.name) ? input.inputPath : undefined;
             propertyForUpdatindVal.setAsDeclared(inputPath); //set prop as declared before assigning value
index 82e2e46..32a73ef 100644 (file)
@@ -62,6 +62,10 @@ export class CapabilitiesEditorComponent {
             let selectedCapabilityTypeObj: CapabilityTypeModel = this.input.capabilityTypesList.find(capType => capType.toscaPresentation.type === selectedCapType.value);
             this.capabilityData.description = selectedCapabilityTypeObj.toscaPresentation.description;
             this.capabilityData.validSourceTypes = selectedCapabilityTypeObj.toscaPresentation.validTargetTypes;
+            this.capabilityData.properties = _.forEach(
+                _.toArray(selectedCapabilityTypeObj.properties),
+                prop => prop.uniqueId = null //a requirement for the BE
+            );
         }
         this.validityChanged();
     }
index e77d880..2c4e288 100644 (file)
                                     {{output.name}}
                                 </option>
                             </optgroup>
+                            <optgroup
+                                    *ngFor="let cap of consumptionInput.associatedCapabilities"
+                                    label="{{cap.name}}">
+                                <option
+                                        *ngFor="let prop of cap.properties"
+                                        [ngValue]="cap.name + '_' + prop.name">
+                                    {{prop.name}}
+                                </option>
+                            </optgroup>
                         </select>
                     </div>
                 </div>
index 25f4126..2c86cc5 100644 (file)
 import * as _ from "lodash";
 import { Component } from '@angular/core';
 import {ServiceServiceNg2} from "app/ng2/services/component-services/service.service";
-import {Service, ServiceInstanceObject, InstanceFePropertiesMap, InstanceBePropertiesMap, PropertyBEModel, InputBEModel, OperationModel, InterfaceModel} from 'app/models';
+import {
+    Service,
+    ServiceInstanceObject,
+    InstanceFePropertiesMap,
+    InstanceBePropertiesMap,
+    PropertyBEModel,
+    InputBEModel,
+    OperationModel,
+    InterfaceModel,
+    Capability
+} from 'app/models';
 import {ConsumptionInput, ConsumptionInputDetails, ServiceOperation} from 'app/ng2/components/logic/service-consumption/service-consumption.component';
 import {PropertiesUtils} from "app/ng2/pages/properties-assignment/services/properties.utils";
 import { PROPERTY_DATA } from 'app/utils';
@@ -33,7 +43,7 @@ import { PROPERTY_DATA } from 'app/utils';
 export class ServiceConsumptionCreatorComponent {
 
     input: {
-        interfaceId: string;
+        interfaceId: string,
         serviceOperationIndex: number,
         serviceOperations: Array<ServiceOperation>,
         parentService: Service,
@@ -41,7 +51,9 @@ export class ServiceConsumptionCreatorComponent {
         parentServiceInputs: Array<InputBEModel>,
         selectedServiceProperties: Array<PropertyBEModel>,
         selectedServiceInstanceId: String,
-        selectedInstanceSiblings: Array<ServiceInstanceObject>
+        selectedInstanceSiblings: Array<ServiceInstanceObject>,
+        selectedInstanceCapabilitisList: Array<Capability>,
+        siblingsCapabilitiesList: Map<string, Array<Capability>>
     };
     sourceTypes: Array<any> = [];
     serviceOperationsList: Array<ServiceOperation>;
@@ -80,16 +92,24 @@ export class ServiceConsumptionCreatorComponent {
 
     initSourceTypes() {
         this.sourceTypes = [
-            { label: this.SOURCE_TYPES.STATIC, value: this.SOURCE_TYPES.STATIC, options: [], interfaces: []},
+            {
+                label: this.SOURCE_TYPES.STATIC,
+                value: this.SOURCE_TYPES.STATIC,
+                options: [],
+                interfaces: [],
+                capabilities: []
+            },
             { label: this.SOURCE_TYPES.SELF + ' (' + this.selectedService.name + ')',
                 value: this.selectedServiceInstanceId,
                 options: this.selectedServiceProperties,
-                interfaces: this.selectedService.interfaces
+                interfaces: this.selectedService.interfaces,
+                capabilities: this.input.selectedInstanceCapabilitisList
             },
             { label: this.parentService.name,
                 value: this.parentService.uniqueId,
                 options: this.parentServiceInputs,
-                interfaces: []
+                interfaces: [],
+                capabilities: []
     }
         ];
         _.forEach(this.input.selectedInstanceSiblings, sib =>
@@ -97,7 +117,8 @@ export class ServiceConsumptionCreatorComponent {
                 label: sib.name,
                 value: sib.id,
                 options: _.unionBy(sib.inputs, sib.properties, 'uniqueId'),
-                interfaces: sib.interfaces
+                interfaces: sib.interfaces,
+                capabilities: this.input.siblingsCapabilitiesList[sib.id]
             })
         );
     }
@@ -160,6 +181,7 @@ export class ServiceConsumptionCreatorComponent {
                 consumptionInputDetails.assignValueLabel = this.getAssignValueLabel(sourceVal);
                 consumptionInputDetails.associatedProps = filteredListsObj.associatedPropsList;
                 consumptionInputDetails.associatedInterfaces = filteredListsObj.associatedInterfacesList;
+                consumptionInputDetails.associatedCapabilities = filteredListsObj.associatedCapabilitiesList;
                 return new ConsumptionInputDetails(consumptionInputDetails);
             });
         }
@@ -171,6 +193,7 @@ export class ServiceConsumptionCreatorComponent {
         let filteredListsObj = this.getFilteredProps(consumptionInput.source, consumptionInput.type);
         consumptionInput.associatedProps = filteredListsObj.associatedPropsList;
         consumptionInput.associatedInterfaces = filteredListsObj.associatedInterfacesList;
+        consumptionInput.associatedCapabilities = filteredListsObj.associatedCapabilitiesList;
         if(consumptionInput.source === this.SOURCE_TYPES.STATIC) {
             if(PROPERTY_DATA.SIMPLE_TYPES.indexOf(consumptionInput.type) !== -1) {
                 consumptionInput.value = consumptionInput.defaultValue || "";
@@ -184,7 +207,7 @@ export class ServiceConsumptionCreatorComponent {
 
     private getFilteredProps(sourceVal, inputType) {
         let currentSourceObj = this.sourceTypes.find(s => s.value === sourceVal);
-        let associatedInterfacesList = [], associatedPropsList = [];
+        let associatedInterfacesList = [], associatedPropsList = [], associatedCapabilitiesPropsList: Array<Capability> = [];
         if(currentSourceObj) {
             if (currentSourceObj.interfaces) {
                 associatedInterfacesList = this.getFilteredInterfaceOutputs(currentSourceObj, inputType);
@@ -195,10 +218,22 @@ export class ServiceConsumptionCreatorComponent {
                 }
                 return result;
             }, []);
+            associatedCapabilitiesPropsList =
+                _.reduce(currentSourceObj.capabilities,
+                    (filteredCapsList, capability: Capability) => {
+                        let filteredProps = _.filter(capability.properties, prop => prop.type === inputType);
+                        if (filteredProps.length) {
+                            let cap = new Capability(capability);
+                            cap.properties = filteredProps;
+                            filteredCapsList.push(cap);
+                        }
+                        return filteredCapsList
+                    }, []);
         }
         return {
             associatedPropsList: associatedPropsList,
-            associatedInterfacesList: associatedInterfacesList
+            associatedInterfacesList: associatedInterfacesList,
+            associatedCapabilitiesList: associatedCapabilitiesPropsList
         }
     }
 
index 406ac77..dce4e81 100644 (file)
@@ -115,7 +115,9 @@ export class ServiceServiceNg2 extends ComponentServiceNg2 {
             COMPONENT_FIELDS.COMPONENT_INSTANCES_INTERFACES,
             COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES,
             COMPONENT_FIELDS.COMPONENT_INSTANCES_INPUTS,
-            COMPONENT_FIELDS.COMPONENT_INPUTS
+            COMPONENT_FIELDS.COMPONENT_INPUTS,
+            COMPONENT_FIELDS.COMPONENT_INSTANCES,
+            COMPONENT_FIELDS.COMPONENT_CAPABILITIES
         ]);
     }
 
index 20e99b0..7370023 100644 (file)
 
 
 import {ICompositionViewModelScope} from "../../composition-view-model";
-import {Service, PropertiesGroup, InputsGroup, ServiceInstanceObject, InterfaceModel, InputBEModel} from 'app/models';
+import {
+    Service,
+    PropertiesGroup,
+    InputsGroup,
+    ServiceInstanceObject,
+    InterfaceModel,
+    InputBEModel,
+    CapabilitiesGroup,
+    Capability,
+    ComponentInstance
+} from 'app/models';
 import {ComponentGenericResponse} from "app/ng2/services/responses/component-generic-response";
 import {ServiceServiceNg2} from "app/ng2/services/component-services/service.service";
 
@@ -27,6 +37,8 @@ interface IServiceConsumptionViewModelScope extends ICompositionViewModelScope {
     componentInstancesInputs: InputsGroup;
     componentInstancesInterfaces: Map<string, Array<InterfaceModel>>;
     componentInputs: Array<InputBEModel>;
+    componentCapabilities: Array<Capability>;
+    instancesCapabilitiesMap: Map<string, Array<Capability>>;
 }
 
 
@@ -49,10 +61,20 @@ export class ServiceConsumptionViewModel {
             this.$scope.componentInstancesInputs = genericResponse.componentInstancesInputs;
             this.$scope.componentInstancesInterfaces = genericResponse.componentInstancesInterfaces;
             this.$scope.componentInputs = genericResponse.inputs;
+            this.buildInstancesCapabilitiesMap(genericResponse.componentInstances);
             this.updateInstanceAttributes();
         });
     }
 
+    buildInstancesCapabilitiesMap = (componentInstances: Array<ComponentInstance>): void => {
+        this.$scope.instancesCapabilitiesMap = new Map();
+        let flattenCapabilities = [];
+        _.forEach(componentInstances, componentInstance => {
+            flattenCapabilities = CapabilitiesGroup.getFlattenedCapabilities(componentInstance.capabilities);
+            this.$scope.instancesCapabilitiesMap[componentInstance.uniqueId] = _.filter(flattenCapabilities, cap => cap.properties && cap.ownerId === componentInstance.uniqueId);
+        });
+    }
+
     private updateInstanceAttributes = ():void => {
         if (this.$scope.isComponentInstanceSelected() && this.$scope.componentInstancesProperties) {
             this.$scope.instancesMappedList = this.$scope.service.componentInstances.map(coInstance => new ServiceInstanceObject({
index 835ded3..8404a7f 100644 (file)
@@ -14,6 +14,7 @@
                         [selected-service-instance-id]="currentComponent.selectedInstance.uniqueId"
                         [instances-mapped-list]="instancesMappedList"
                         [parent-service-inputs]="componentInputs"
+                        [instances-capabilities-map]="instancesCapabilitiesMap"
                         [readonly]="isViewMode() || !isDesigner()">
                 </ng2-service-consumption>
             </div>
index 14bc49e..8e18221 100644 (file)
@@ -96,8 +96,8 @@
                         <div class="flex-container data-row" data-ng-class="{'editable-row': req.isCreatedManually}"
                              data-ng-click="req.isCreatedManually && onEditRequirement(req)">
                             <div class="table-col-general flex-item text ellipsis-text" tooltips
-                                 tooltip-content="{{req.name}}">
-                                <span data-tests-id="{{req.name}}">{{req.name}}</span>
+                                 tooltip-content="{{(!req.isCreatedManually ? req.ownerName + '.' : '') + req.name}}">
+                                <span data-tests-id="{{(!req.isCreatedManually ? req.ownerName + '.' : '') + req.name}}">{{(!req.isCreatedManually ? req.ownerName + '.' : '') + req.name}}</span>
                             </div>
                             <div class="table-col-general flex-item text ellipsis-text" tooltips
                                  tooltip-content="{{req.capability}}">
                     <div data-ng-if="filteredCapabilitiesList.length === 0" class="no-row-text"
                          data-tests-id="no-rows-in-table">
                         There are no capabilities to display
-
                     </div>
-                    <div data-ng-repeat="capability in filteredCapabilitiesList | orderBy:capabilitiesSortTableDefined.sortByField:capabilitiesSortTableDefined.reverse  track by $index"
+                    <div data-ng-repeat-start="capability in filteredCapabilitiesList | orderBy:capabilitiesSortTableDefined.sortByField:capabilitiesSortTableDefined.reverse  track by $index"
                          class="flex-container data-row"
                          data-ng-class="{'selected': capability.selected, 'editable-row': capability.isCreatedManually}"
                          data-ng-click="capability.isCreatedManually && onEditCapability(capability)"
                          data-tests-id="capabilities-table-row">
 
                         <div class="table-col-general flex-item text ellipsis-text" tooltips
-                             tooltip-content="{{capability.name}}">
-                            <span data-tests-id="{{capability.name}}">{{capability.name}}</span>
+                             tooltip-content="{{(!capability.isCreatedManually ? capability.ownerName + '.' : '') + capability.name}}">
+                            <span class="sprite-new arrow-up-small hand"
+                                  data-ng-class="{'hideme': !capability.properties.length, 'opened': capability.selected}"
+                                  data-ng-click="capability.selected = !capability.selected; $event.stopPropagation();"></span>
+                            <span data-tests-id="{{(!capability.isCreatedManually ? capability.ownerName + '.' : '') + capability.name}}"
+                                  class="name-col" data-ng-class="{'opened': capability.selected}">
+                                {{(!capability.isCreatedManually ? capability.ownerName + '.' : '') + capability.name}}
+                            </span>
                         </div>
                         <div class="table-col-general flex-item text ellipsis-text" tooltips
                              tooltip-content="{{capability.type}}">
                                       data-ng-click="onDeleteCap($event, capability)"></svg-icon>
                         </div>
                     </div>
+                    <div data-ng-repeat-end data-ng-if="capability.selected" class="item-opened properties-section">
+                        <p class="properties-title">Properties</p>
+                        <div class="table-container-flex properties-table">
+                            <div class="table" data-ng-class="{'view-mode': true}">
+                                <div class="head flex-container">
+                                    <div class="table-header head-row hand flex-item"
+                                         data-ng-repeat="header in capabilityPropertiesTableHeadersList track by $index"
+                                         data-ng-click="sort(header.property, propertiesSortTableDefined)">
+                                        {{header.title}}
+                                        <span data-ng-if="propertiesSortTableDefined.sortByField === header.property"
+                                              class="table-header-sort-arrow"
+                                              data-ng-class="{'down': propertiesSortTableDefined.reverse, 'up':!propertiesSortTableDefined.reverse}"> </span>
+                                    </div>
+                                </div>
+
+                                <div class="body">
+                                    <div data-ng-repeat="property in capability.properties | orderBy:propertiesSortTableDefined.sortByField:propertiesSortTableDefined.reverse track by $index"
+                                         data-tests-id="propertyRow"
+                                         class="flex-container data-row">
+                                        <div class="table-col-general flex-item text"
+                                             data-tests-id="{{property.name}}"
+                                             tooltips tooltip-content="{{property.name}}">
+                                            {{property.name}}
+                                        </div>
+                                        <div class="table-col-general flex-item text"
+                                             data-tests-id="{{property.type}}"
+                                             tooltips tooltip-content="{{property.type}}">
+                                            {{property.type}}
+                                        </div>
+                                        <div class="table-col-general flex-item text"
+                                             data-tests-id="{{property.schema.property.type}}"
+                                             tooltips tooltip-content="{{property.schema.property.type}}">
+                                            {{property.schema.property.type}}
+                                        </div>
+                                        <div class="table-col-general flex-item text"
+                                             tooltips tooltip-content="{{property.description}}"
+                                             data-tests-id="{{property.description}}">
+                                            {{property.description}}
+                                        </div>
+                                    </div>
+                                </div>
+
+                            </div>
+                        </div>
+                    </div>
                 </perfect-scrollbar>
             </div>
 
index fa6623f..928f671 100644 (file)
       }
     }
   }
-  .table-container-flex .table .head .head-row {
-    text-align: left;
-    &.description {
-      flex: 2;
-    }
-    &.other {
-      flex: 0.25;
-      text-align: center;
-    }
-    &.occurrences {
-      flex: 0.75;
-    }
-  }
-  .data-row {
-    .ellipsis-text {
-      overflow: hidden;
-      text-overflow: ellipsis;
-    }
-    &:not(.editable-row) {
-      background: @tlv_color_t;
-      cursor: default;
-      color: @main_color_n;
-    }
-    &.editable-row {
-      cursor: pointer;
-      .table-col-general:hover {
-        color: @main_color_b;
+  .table-container-flex .table {
+    .head .head-row {
+      text-align: left;
+      &.description {
+        flex: 2;
       }
-    }
-    .description-col {
-      flex: 2;
-    }
-    .occurrences-col {
-      flex: 0.75;
-    }
-    .other-col {
-      display: flex;
-      justify-content: center;
-      align-items: center;
-      flex: 0.25;
-      .trash-icon {
-        visibility: hidden;
+      &.other {
+        flex: 0.25;
+        text-align: center;
+      }
+      &.occurrences {
+        flex: 0.75;
       }
     }
-    &:hover {
-      .trash-icon {
-        visibility: visible;
+    .body .data-row {
+      border-bottom: none;
+      border-top: @main_color_o solid 1px;
+      .ellipsis-text {
+        overflow: hidden;
+        text-overflow: ellipsis;
+      }
+      &:not(.editable-row) {
+        background-color: @tlv_color_t;
+        cursor: default;
+        color: @main_color_n;
+      }
+      &.editable-row {
+        cursor: pointer;
+        .table-col-general:hover {
+          color: @main_color_b;
+        }
+      }
+      &.selected {
+        background-color: @tlv_color_v;
+        .name-col {
+          color: @main_color_a;
+        }
+        .sprite-new.arrow-up-small {
+          background-position: -858px -137px;
+          margin-bottom: 2px;
+        }
       }
+      .description-col {
+        flex: 2;
+      }
+      .occurrences-col {
+        flex: 0.75;
+      }
+      .other-col {
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        flex: 0.25;
+        .trash-icon {
+          visibility: hidden;
+        }
+      }
+      &:hover {
+        .trash-icon {
+          visibility: visible;
+        }
+      }
+      .multiline-ellipsis {
+        line-height: 1.5em;
+        padding: 1px 0 1px 0;
+        /deep/ .ellipsis-directive-more-less {
+          float: none;
+          margin-left: 5px;
+          color: @main_color_a;
+        }
+      }
+    }
+  }
+
+  .item-opened.properties-section {
+    border: 4px solid @tlv_color_v !important;
+    max-height: 263px;
+    overflow: auto;
+    .properties-title {
+      .s_10;
+      margin-top: 10px;
     }
-    .multiline-ellipsis {
-      line-height: 1.5em;
-      padding: 1px 0 1px 0;
-      /deep/ .ellipsis-directive-more-less {
-        float: none;
-        margin-left: 5px;
-        color: @main_color_a;
+    .properties-table {
+      &.table-container-flex {
+        margin-top: 18px;
+      }
+      .table {
+        .head {
+          border-bottom: 1px solid @main_color_o;
+        }
+        .head, .table-col-general {
+          background-color: @main_color_p;
+        }
       }
     }
   }
-}
+}
\ No newline at end of file
index 7deed22..0e32684 100644 (file)
 
 /* Added by ikram - */
 .s_1 {.font-color > .s; .font-type > ._1;}
+
+.s_10 {
+  .font-color > .s;
+  .font-type > ._10;
+}
 .s_12 {.font-color > .s; .font-type > ._12;}
 
 .z_9  {.font-color > .z; .font-type > ._9;}
index ecdb486..18e3997 100644 (file)
 
 package org.openecomp.sdc.ci.tests.capability;
 
+import fj.data.Either;
 import org.junit.Rule;
 import org.junit.rules.TestName;
+import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
+import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
+import org.openecomp.sdc.be.model.Resource;
 import org.openecomp.sdc.be.model.Service;
 import org.openecomp.sdc.be.model.User;
 import org.openecomp.sdc.ci.tests.api.ComponentBaseTest;
 import org.openecomp.sdc.ci.tests.datatypes.CapabilityDetails;
-import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails;
 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.AtomicOperationUtils;
 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.CapabilityRestUtils;
-import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils;
 import org.testng.Assert;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 
+import static org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils.getResourceObject;
 import static org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils.getServiceObject;
+import static org.testng.AssertJUnit.fail;
 
 public class CapabilitiesTest extends ComponentBaseTest {
     @Rule
-    public static final TestName name = new TestName();
+    public static TestName name = new TestName();
 
-    private  ServiceReqDetails component;
-    private  User user = null;
+    private static User user = null;
+    private static Service service;
+    private static Resource resource;
+    private static Resource pnfResource;
 
     public CapabilitiesTest() {
         super(name, CapabilitiesTest.class.getName());
@@ -54,63 +63,297 @@ public class CapabilitiesTest extends ComponentBaseTest {
     @BeforeTest
     public void init() throws Exception {
         user = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER);
-        component = ElementFactory.getDefaultService();
-        component.setName("comp_cap" + Math.random());
-        ServiceRestUtils.createService(component, user);
+
+        // Create default service
+        Either<Service, RestResponse> createDefaultServiceEither =
+                AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true);
+        if (createDefaultServiceEither.isRight()) {
+            fail("Error creating default service");
+        }
+        service = createDefaultServiceEither.left().value();
+
+        // Create default resource
+        Either<Resource, RestResponse> createDefaultResourceEither =
+                AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true);
+        if (createDefaultResourceEither.isRight()) {
+            fail("Error creating default resource");
+        }
+        resource = createDefaultResourceEither.left().value();
+
+        // Create default PNF resource
+        Either<Resource, RestResponse> createDefaultPNFResourceEither =
+                AtomicOperationUtils.createResourceByType(ResourceTypeEnum.PNF, UserRoleEnum.DESIGNER, true);
+        if (createDefaultPNFResourceEither.isRight()) {
+            fail("Error creating default pnf resource");
+        }
+        pnfResource = createDefaultPNFResourceEither.left().value();
     }
 
     @Test
-    public void createCapabilityTest() throws Exception {
+    public void createCapabilityOnServiceTest() throws Exception {
 
         CapabilityDetails capability = createCapability();
-        RestResponse restResponse = CapabilityRestUtils.createCapability(component.getUniqueId(),
-                Collections.singletonList(capability), user);
-        logger.info("createCapability Response Code:" + restResponse.getErrorCode());
+        RestResponse restResponse = CapabilityRestUtils.createCapability(service, Collections.singletonList(capability),
+                user);
+        logger.info("createCapability On Service Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+
+    @Test(dependsOnMethods = "createCapabilityOnServiceTest")
+    public void updateCapabilityOnServiceTest() throws Exception {
+
+        CapabilityDetails capability = createCapability();
+        capability.setMaxOccurrences("10");
+        capability.setMinOccurrences("4");
+        RestResponse restResponse = CapabilityRestUtils.updateCapability(service, Collections.singletonList(capability),
+                user);
+        logger.info("updateCapability On Service Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+
+    @Test(dependsOnMethods = "updateCapabilityOnServiceTest")
+    public void getCapabilityFromServiceTest() throws Exception {
+        Service serviceObject = getServiceObject(service.getUniqueId());
+
+        List<org.openecomp.sdc.be.model.CapabilityDefinition> capabilityDefinitionList = serviceObject.getCapabilities()
+                .values().stream().flatMap(Collection::stream).collect(Collectors.toList());
+
+        RestResponse restResponse = CapabilityRestUtils.getCapability(service,
+                capabilityDefinitionList.get(0).getUniqueId(), user);
+        logger.info("getCapabilityTest from Service Response Code:" + restResponse.getErrorCode());
         Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
     }
 
+    @Test(dependsOnMethods = "getCapabilityFromServiceTest")
+    public void deleteCapabilityFromServiceTest() throws Exception {
+        Service serviceObject = getServiceObject(service.getUniqueId());
+
+        List<org.openecomp.sdc.be.model.CapabilityDefinition> capabilityDefinitionList = serviceObject.getCapabilities()
+                .values().stream().flatMap(Collection::stream).collect(Collectors.toList());
 
+        RestResponse restResponse = CapabilityRestUtils.deleteCapability(service,
+                capabilityDefinitionList.get(0).getUniqueId(), user);
+        logger.info("deleteCapabilityTest from Service Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
 
-    @Test(dependsOnMethods = "createCapabilityTest")
-    public void updateCapabilityTest() throws Exception {
+    @Test
+    public void createCapabilityWithPropertiesOnServiceTest() throws Exception {
+
+        CapabilityDetails capability = createCapability();
+        List<ComponentInstanceProperty> properties = new ArrayList<>();
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setType("prop_type");
+        instanceProperty.setName("prop_name");
+        instanceProperty.setDescription("prop_description");
+        instanceProperty.setSchema(new SchemaDefinition());
+        properties.add(instanceProperty);
+        capability.setProperties(properties);
+        RestResponse restResponse = CapabilityRestUtils.createCapability(service, Collections.singletonList(capability),
+                user);
+        logger.info("createCapability On Service Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+
+    @Test(dependsOnMethods = "createCapabilityWithPropertiesOnServiceTest")
+    public void updateCapabilityWithPropertiesOnServiceTest() throws Exception {
 
         CapabilityDetails capability = createCapability();
         capability.setMaxOccurrences("10");
         capability.setMinOccurrences("4");
-        RestResponse restResponse = CapabilityRestUtils.updateCapability(component.getUniqueId(),
-                Collections.singletonList(capability), user);
-        logger.info("updateCapability Response Code:" + restResponse.getErrorCode());
+
+        List<ComponentInstanceProperty> properties = new ArrayList<>();
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setType("prop_type_updated");
+        instanceProperty.setName("prop_name_updated");
+        instanceProperty.setDescription("prop_description_prop_desc");
+        instanceProperty.setSchema(new SchemaDefinition());
+        properties.add(instanceProperty);
+        capability.setProperties(properties);
+        RestResponse restResponse = CapabilityRestUtils.updateCapability(service, Collections.singletonList(capability),
+                user);
+        logger.info("updateCapability On Service Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+
+    @Test
+    public void createCapabilityOnVfTest() throws Exception {
+
+        CapabilityDetails capability = createCapability();
+        RestResponse restResponse = CapabilityRestUtils.createCapability(resource, Collections.singletonList(capability),
+                user);
+        logger.info("createCapability On Vf Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+
+    @Test(dependsOnMethods = "createCapabilityOnVfTest")
+    public void updateCapabilityOnVfTest() throws Exception {
+
+        CapabilityDetails capability = createCapability();
+        capability.setMaxOccurrences("10");
+        capability.setMinOccurrences("4");
+        RestResponse restResponse = CapabilityRestUtils.updateCapability(resource, Collections.singletonList(capability),
+                user);
+        logger.info("updateCapability On Vf Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+
+    @Test(dependsOnMethods = "updateCapabilityOnVfTest")
+    public void getCapabilityFromVfTest() throws Exception {
+        Resource resourceObject = getResourceObject(resource.getUniqueId());
+
+        List<org.openecomp.sdc.be.model.CapabilityDefinition> capabilityDefinitionList = resourceObject.getCapabilities()
+                .values().stream().flatMap(Collection::stream).collect(Collectors.toList());
+
+        RestResponse restResponse = CapabilityRestUtils.getCapability(resource,
+                capabilityDefinitionList.get(0).getUniqueId(), user);
+        logger.info("getCapabilityTest from Vf Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+
+    @Test(dependsOnMethods = "getCapabilityFromVfTest")
+    public void deleteCapabilityFromVfTest() throws Exception {
+        Resource resourceObject = getResourceObject(resource.getUniqueId());
+
+        List<org.openecomp.sdc.be.model.CapabilityDefinition> capabilityDefinitionList = resourceObject.getCapabilities()
+                .values().stream().flatMap(Collection::stream).collect(Collectors.toList());
+
+        RestResponse restResponse = CapabilityRestUtils.deleteCapability(resource,
+                capabilityDefinitionList.get(0).getUniqueId(), user);
+        logger.info("deleteCapabilityTest from Vf Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+
+    @Test
+    public void createCapabilityWithPropertiesOnVfTest() throws Exception {
+
+        CapabilityDetails capability = createCapability();
+        List<ComponentInstanceProperty> properties = new ArrayList<>();
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setType("prop_type");
+        instanceProperty.setName("prop_name");
+        instanceProperty.setDescription("prop_description");
+        instanceProperty.setSchema(new SchemaDefinition());
+        properties.add(instanceProperty);
+        capability.setProperties(properties);
+        RestResponse restResponse = CapabilityRestUtils.createCapability(resource, Collections.singletonList(capability),
+                user);
+        logger.info("createCapability On Vf Response Code:" + restResponse.getErrorCode());
         Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
     }
 
-    @Test(dependsOnMethods = "updateCapabilityTest")
-    public void getCapabilityTest() throws Exception {
-        Service service = getServiceObject(component.getUniqueId());
+    @Test(dependsOnMethods = "createCapabilityWithPropertiesOnVfTest")
+    public void updateCapabilityWithPropertiesOnVfTest() throws Exception {
 
-        List<org.openecomp.sdc.be.model.CapabilityDefinition> capabilityDefinitionList = service.getCapabilities().values()
-                .stream().flatMap(Collection::stream).collect(Collectors.toList());
+        CapabilityDetails capability = createCapability();
+        capability.setMaxOccurrences("10");
+        capability.setMinOccurrences("4");
 
-        RestResponse restResponse = CapabilityRestUtils.getCapability(component.getUniqueId(),
-                capabilityDefinitionList.get(0).getUniqueId(),  user);
-        logger.info("getCapabilityTest Response Code:" + restResponse.getErrorCode());
+        List<ComponentInstanceProperty> properties = new ArrayList<>();
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setType("prop_type_updated");
+        instanceProperty.setName("prop_name_updated");
+        instanceProperty.setDescription("prop_description_prop_desc");
+        instanceProperty.setSchema(new SchemaDefinition());
+        properties.add(instanceProperty);
+        capability.setProperties(properties);
+        RestResponse restResponse = CapabilityRestUtils.updateCapability(resource, Collections.singletonList(capability),
+                user);
+        logger.info("updateCapability On Vf Response Code:" + restResponse.getErrorCode());
         Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
     }
 
-    @Test(dependsOnMethods = "getCapabilityTest")
-    public void deleteCapabilityTest() throws Exception {
-        Service service = getServiceObject(component.getUniqueId());
 
-        List<org.openecomp.sdc.be.model.CapabilityDefinition> capabilityDefinitionList = service.getCapabilities().values()
-                .stream().flatMap(Collection::stream).collect(Collectors.toList());
+    @Test
+    public void createCapabilityOnPnfTest() throws Exception {
+
+        CapabilityDetails capability = createCapability();
+        RestResponse restResponse = CapabilityRestUtils.createCapability(pnfResource, Collections.singletonList(capability),
+                user);
+        logger.info("createCapability On Pnf Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+
+    @Test(dependsOnMethods = "createCapabilityOnPnfTest")
+    public void updateCapabilityOnPnfTest() throws Exception {
 
-        RestResponse restResponse = CapabilityRestUtils.deleteCapability(component.getUniqueId(),
-                capabilityDefinitionList.get(0).getUniqueId(),  user);
-        logger.info("deleteCapabilityTest Response Code:" + restResponse.getErrorCode());
+        CapabilityDetails capability = createCapability();
+        capability.setMaxOccurrences("10");
+        capability.setMinOccurrences("4");
+        RestResponse restResponse = CapabilityRestUtils.updateCapability(pnfResource, Collections.singletonList(capability),
+                user);
+        logger.info("updateCapability On Pnf Response Code:" + restResponse.getErrorCode());
         Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
     }
 
-    private  CapabilityDetails createCapability() {
-        CapabilityDetails  capabilityDetails = new CapabilityDetails();
+    @Test(dependsOnMethods = "updateCapabilityOnPnfTest")
+    public void getCapabilityFromPnfTest() throws Exception {
+        Resource pnfResourceObject = getResourceObject(pnfResource.getUniqueId());
+
+        List<org.openecomp.sdc.be.model.CapabilityDefinition> capabilityDefinitionList = pnfResourceObject.getCapabilities()
+                .values().stream().flatMap(Collection::stream).collect(Collectors.toList());
+
+        RestResponse restResponse = CapabilityRestUtils.getCapability(pnfResource,
+                capabilityDefinitionList.get(0).getUniqueId(), user);
+        logger.info("getCapabilityTest from Pnf Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+
+    @Test(dependsOnMethods = "getCapabilityFromPnfTest")
+    public void deleteCapabilityFromPnfTest() throws Exception {
+        Resource pnfResourceObject = getResourceObject(pnfResource.getUniqueId());
+
+        List<org.openecomp.sdc.be.model.CapabilityDefinition> capabilityDefinitionList = pnfResourceObject.getCapabilities()
+                .values().stream().flatMap(Collection::stream).collect(Collectors.toList());
+
+        RestResponse restResponse = CapabilityRestUtils.deleteCapability(pnfResource,
+                capabilityDefinitionList.get(0).getUniqueId(), user);
+        logger.info("deleteCapabilityTest from Pnf Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+
+    @Test
+    public void createCapabilityWithPropertiesOnPnfTest() throws Exception {
+
+        CapabilityDetails capability = createCapability();
+        List<ComponentInstanceProperty> properties = new ArrayList<>();
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setType("prop_type");
+        instanceProperty.setName("prop_name");
+        instanceProperty.setDescription("prop_description");
+        instanceProperty.setSchema(new SchemaDefinition());
+        properties.add(instanceProperty);
+        capability.setProperties(properties);
+        RestResponse restResponse = CapabilityRestUtils.createCapability(pnfResource, Collections.singletonList(capability),
+                user);
+        logger.info("createCapability On Pnf Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+
+    @Test(dependsOnMethods = "createCapabilityWithPropertiesOnPnfTest")
+    public void updateCapabilityWithPropertiesOnPnfTest() throws Exception {
+
+        CapabilityDetails capability = createCapability();
+        capability.setMaxOccurrences("10");
+        capability.setMinOccurrences("4");
+
+        List<ComponentInstanceProperty> properties = new ArrayList<>();
+        ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty();
+        instanceProperty.setType("prop_type_updated");
+        instanceProperty.setName("prop_name_updated");
+        instanceProperty.setDescription("prop_description_prop_desc");
+        instanceProperty.setSchema(new SchemaDefinition());
+        properties.add(instanceProperty);
+        capability.setProperties(properties);
+        RestResponse restResponse = CapabilityRestUtils.updateCapability(pnfResource,
+                Collections.singletonList(capability), user);
+        logger.info("updateCapability On Pnf Response Code:" + restResponse.getErrorCode());
+        Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+    }
+
+
+    private CapabilityDetails createCapability() {
+        CapabilityDetails capabilityDetails = new CapabilityDetails();
         capabilityDetails.setName("cap" + Math.random());
         capabilityDetails.setType("tosca.capabilities.network.Bindable");
 
index 954a16a..bbed28b 100644 (file)
 
 package org.openecomp.sdc.ci.tests.datatypes;
 
+import org.openecomp.sdc.be.model.ComponentInstanceProperty;
+
+import java.util.List;
+
 public class CapabilityDetails {
     private String name;
     private String type;
     private String maxOccurrences;
     private String minOccurrences;
+    private List<ComponentInstanceProperty> properties;
 
     public String getName() {
         return name;
@@ -53,4 +58,12 @@ public class CapabilityDetails {
     public void setMinOccurrences(String minOccurrences) {
         this.minOccurrences = minOccurrences;
     }
+
+    public List<ComponentInstanceProperty> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(List<ComponentInstanceProperty> properties) {
+        this.properties = properties;
+    }
 }
index 1959aa8..488ed24 100644 (file)
@@ -17,6 +17,8 @@
 package org.openecomp.sdc.ci.tests.utils.rest;
 
 import com.google.gson.Gson;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.User;
 import org.openecomp.sdc.ci.tests.api.Urls;
 import org.openecomp.sdc.ci.tests.config.Config;
@@ -27,14 +29,13 @@ import java.util.List;
 
 public class CapabilityRestUtils extends BaseRestUtils {
     private static Gson gson = new Gson();
-    private static final String COMPONENT_TYPE = "services";
 
-    public static RestResponse createCapability(String componentId,
+    public static RestResponse createCapability(Component component,
                                                  List<CapabilityDetails> capabilityDetailsList,
                                                  User user) throws Exception{
         Config config = Config.instance();
         String url = String.format(Urls.CREATE_CAPABILITY, config.getCatalogBeHost(), config.getCatalogBePort(),
-                COMPONENT_TYPE, componentId);
+                ComponentTypeEnum.findParamByType(component.getComponentType()), component.getUniqueId());
 
         String data = "{ \"capabilities\" : {" + "\"" +capabilityDetailsList.get(0).getType()+ "\"" +" : "
                 + gson.toJson(capabilityDetailsList) + "  } }";
@@ -42,12 +43,12 @@ public class CapabilityRestUtils extends BaseRestUtils {
         return sendPost(url, data , user.getUserId(), acceptHeaderData);
     }
 
-    public static RestResponse updateCapability(String componentId,
+    public static RestResponse updateCapability(Component component,
                                                  List<CapabilityDetails> capabilityDetailsList,
                                                  User user) throws Exception{
         Config config = Config.instance();
         String url = String.format(Urls.UPDATE_CAPABILITY, config.getCatalogBeHost(), config.getCatalogBePort(),
-                COMPONENT_TYPE, componentId);
+                ComponentTypeEnum.findParamByType(component.getComponentType()), component.getUniqueId());
 
         String data = "{ \"capabilities\" : {" + "\"" +capabilityDetailsList.get(0).getType()+ "\"" +" : "
                 + gson.toJson(capabilityDetailsList) + "  } }";
@@ -55,21 +56,21 @@ public class CapabilityRestUtils extends BaseRestUtils {
         return sendPost(url, data , user.getUserId(), acceptHeaderData);
     }
 
-    public static RestResponse deleteCapability(String componentId,
+    public static RestResponse deleteCapability(Component component,
                                                  String requirementId,
                                                  User user) throws Exception{
         Config config = Config.instance();
         String url = String.format(Urls.DELETE_CAPABILITY, config.getCatalogBeHost(), config.getCatalogBePort(),
-                COMPONENT_TYPE, componentId, requirementId);
+                ComponentTypeEnum.findParamByType(component.getComponentType()), component.getUniqueId(), requirementId);
         return sendDelete(url, user.getUserId());
     }
 
-    public static RestResponse getCapability(String componentId,
+    public static RestResponse getCapability(Component component,
                                               String requirementId,
                                               User user) throws Exception{
         Config config = Config.instance();
         String url = String.format(Urls.GET_CAPABILITY, config.getCatalogBeHost(), config.getCatalogBePort(),
-                COMPONENT_TYPE, componentId, requirementId);
+                ComponentTypeEnum.findParamByType(component.getComponentType()), component.getUniqueId(), requirementId);
         return sendDelete(url, user.getUserId());
     }