diff options
author | Mojahidul Islam <mojahidul.islam@amdocs.com> | 2019-05-14 12:49:31 +0530 |
---|---|---|
committer | Mojahidul Islam <mojahidul.islam@amdocs.com> | 2019-05-14 12:50:27 +0530 |
commit | 82e531a1ee8ffa30e80b27d9097a2272ae18cdee (patch) | |
tree | 900964c5f61e15437e0568f3a5bec3c7083ca5a2 /catalog-be/src/main | |
parent | 3d5b80b9035b9832f86326858b4c6c2cecd952a3 (diff) |
Support Capability Properties
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: Ieb4fa5705007c8bed3d82eb4fe4604572aa202d7
Issue-ID: SDC-2294
Signed-off-by: Mojahidul Islam <mojahidul.islam@amdocs.com>
Diffstat (limited to 'catalog-be/src/main')
17 files changed, 949 insertions, 471 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CapabilitiesBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CapabilitiesBusinessLogic.java index 75d5836df6..f2fd37704d 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CapabilitiesBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CapabilitiesBusinessLogic.java @@ -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(); + } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java index 3bae240a67..71b125737e 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java @@ -20,26 +20,7 @@ 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); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java index de2839f653..5cdaa6a590 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java @@ -17,12 +17,15 @@ 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()); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java index d1bfcc8bba..a586e23da7 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java @@ -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) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CertificationChangeTransition.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CertificationChangeTransition.java index 2ca6ca41cb..e9289de839 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CertificationChangeTransition.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CertificationChangeTransition.java @@ -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()); } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTransition.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTransition.java index 0c4464239e..33b625002f 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTransition.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTransition.java @@ -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) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentInstancePropertyDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentInstancePropertyDeclarator.java index 973e5985f9..14ea9300fe 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentInstancePropertyDeclarator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/ComponentInstancePropertyDeclarator.java @@ -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); } @Override diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/DefaultPropertyDeclarator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/DefaultPropertyDeclarator.java index 46c1c009bc..bdb79c71bb 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/DefaultPropertyDeclarator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/property/DefaultPropertyDeclarator.java @@ -20,12 +20,14 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.StringUtils; 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; @@ -44,6 +46,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; @@ -108,7 +111,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()); @@ -201,17 +204,17 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties .left().map(x -> input); } - 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); @@ -220,16 +223,28 @@ 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); log.debug("createInput: propOwner.uniqueId={}, propInput.parentUniqueId={}", propertiesOwner.getUniqueId(), propInput.getParentUniqueId()); - return createInputFromProperty(componentId, propertiesOwner, generatedInputName, propInput, prop); + return createInputFromProperty(component.getUniqueId(), propertiesOwner, generatedInputName, propInput, prop); } private String generateInputName(String inputName, ComponentInstancePropInput propInput) { @@ -259,7 +274,7 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties } while(startingIndex < parsedPropNames.length){ - prefix.append("_"); + prefix.append(UNDERSCORE); prefix.append(parsedPropNames[startingIndex]); startingIndex ++; } @@ -449,6 +464,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); @@ -456,36 +496,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 index 0000000000..e90bcfb567 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/ConsumptionUtils.java @@ -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(); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java index 0ee6264f4d..38cdeb8d40 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java @@ -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 index 0000000000..7bea8356a7 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/PropertiesUtils.java @@ -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 index b9b7ab690f..0000000000 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/ProxyServicePropertiesUtils.java +++ /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)); - } -} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/CapabilitiesValidation.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/CapabilitiesValidation.java index 726e9dff82..2c69ee5b38 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/CapabilitiesValidation.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/CapabilitiesValidation.java @@ -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); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java index 30d006f501..2e94139b2b 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java @@ -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()); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceConsumptionServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceConsumptionServlet.java index 990e3bc356..9ce5674cc3 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceConsumptionServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceConsumptionServlet.java @@ -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 = diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java index 127d6f67af..5cafec2bda 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java @@ -1177,7 +1177,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) { diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml index fe1153139f..adc467c913 100644 --- a/catalog-be/src/main/resources/config/error-configuration.yaml +++ b/catalog-be/src/main/resources/config/error-configuration.yaml @@ -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 |