summaryrefslogtreecommitdiffstats
path: root/catalog-be/src/main/java
diff options
context:
space:
mode:
authormojahidi <mojahidul.islam@amdocs.com>2019-03-01 17:50:15 +0530
committerOren Kleks <orenkle@amdocs.com>2019-03-04 10:57:03 +0000
commit1f7c57414533b9886962ede7b19a29669fe7a59a (patch)
tree77bbf8f4f339a8f6a61f96e70ca701e2007a6ee3 /catalog-be/src/main/java
parente0c98681f9fcbae59eab32822784ae95c4768d40 (diff)
Requirement and capabilities feature
1. Enhance Service/VF/PNF to support Req & Cap 2. Added Type fetch APIs to fetch types from global types Change-Id: I2b749ec9da34e488421b8ebe311ccf03c4b7c0fd Issue-ID: SDC-2142 Signed-off-by: mojahidi <mojahidul.islam@amdocs.com>
Diffstat (limited to 'catalog-be/src/main/java')
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CapabilitiesBusinessLogic.java573
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CommonImportManager.java5
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RelationshipTypeBusinessLogic.java62
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RelationshipTypeImportManager.java109
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RequirementBusinessLogic.java518
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CertificationChangeTransition.java8
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTransition.java6
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/utils/MergeInstanceUtils.java8
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/CapabilitiesValidation.java266
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/RequirementValidation.java272
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java27
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java10
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/CapabilityServlet.java320
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementServlet.java325
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java207
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java30
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java63
17 files changed, 2764 insertions, 45 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
new file mode 100644
index 0000000000..75d5836df6
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CapabilitiesBusinessLogic.java
@@ -0,0 +1,573 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.components.impl;
+
+import fj.data.Either;
+import org.apache.commons.collections.CollectionUtils;
+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.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
+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.operations.api.ICapabilityTypeOperation;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+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.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+@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 DELETE_CAPABILITIES = "deleteCapability";
+ private static final String GET_CAPABILITIES = "getCapabilities";
+ private static final String EXCEPTION_OCCURRED_DURING_CAPABILITIES
+ = "Exception occurred during {}. Response is {}";
+
+ @Autowired
+ private CapabilitiesOperation capabilitiesOperation;
+ @Autowired
+ private CapabilitiesValidation capabilitiesValidation;
+ @Autowired
+ private ICapabilityTypeOperation capabilityTypeOperation;
+
+
+ public void setCapabilitiesValidation(CapabilitiesValidation capabilitiesValidation) {
+ this.capabilitiesValidation = capabilitiesValidation;
+ }
+
+ public void setCapabilitiesOperation(CapabilitiesOperation capabilitiesOperation) {
+ 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());
+ }
+
+ 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);
+ } catch (Exception e) {
+ titanDao.rollback();
+ LOGGER.error(EXCEPTION_OCCURRED_DURING_CAPABILITIES, "addOrUpdate", e);
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+ } finally {
+ if (lockResult.isLeft() && lockResult.left().value()) {
+ graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
+ NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
+ }
+ }
+ }
+
+ 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);
+ 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, true);
+ if (capabilitiesValidationEither.isRight()) {
+ return Either.right(capabilitiesValidationEither.right().value());
+ }
+
+ 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> capabilitiesDefListToUpdate = new ArrayList<>();
+ List<CapabilityDefinition> capabilitiesToReturn = null;
+ 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));
+ }
+ for (CapabilityDefinition capabilityDefinitionToUpdate : capabilityDefinitions) {
+ 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()));
+ if (CollectionUtils.isNotEmpty(capabilitiesToReturn)) {
+ capabilitiesListStoredInComponent.addAll(capabilitiesToReturn);
+ capabilitiesDefListToUpdate.addAll(capabilitiesListStoredInComponent);
+ } else {
+ Either<List<CapabilityDefinition>, ResponseFormat> capTypeUpdateEither
+ = handleCapabilityTypeUpdateWhenNewTypeExist(storedComponent,
+ storedComponent.getCapabilities(), capabilitiesToReturn, capabilityDefinitionToUpdate);
+ if (capTypeUpdateEither.isRight()) {
+ return Either.right(capTypeUpdateEither.right().value());
+ }
+ capabilitiesDefListToUpdate = capTypeUpdateEither.left().value();
+ }
+ }
+ result = capabilitiesOperation.updateCapabilities(componentId,
+ capabilitiesDefListToUpdate);
+ } else {
+ Either<List<CapabilityDefinition>, ResponseFormat> capabilityDefinitionToDelete
+ = handleCapabilityTypeUpdateWhenNewTypeNotExist(capabilityDefinitions,
+ storedComponent, storedComponentCapabilities);
+ if (capabilityDefinitionToDelete != null) {
+ return capabilityDefinitionToDelete;
+ }
+ 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);
+ } catch (Exception e) {
+ titanDao.rollback();
+ LOGGER.error(EXCEPTION_OCCURRED_DURING_CAPABILITIES, "addOrUpdate", e);
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+ } finally {
+ if (lockResult.isLeft() && lockResult.left().value()) {
+ graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
+ NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
+ }
+ }
+ }
+
+ private Either<List<CapabilityDefinition>, ResponseFormat> handleCapabilityTypeUpdateWhenNewTypeExist(
+ org.openecomp.sdc.be.model.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()
+ .equals(capabilityDefinitionToUpdate.getUniqueId())).findAny();
+ if (!definitionOptional.isPresent()) {
+ return Either.right(componentsUtils.getResponseFormat(
+ ActionStatus.CAPABILITY_NOT_FOUND, storedComponent.getUniqueId()));
+ }
+ CapabilityDefinition capabilityDefinitionToDelete = definitionOptional.get();
+
+ 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()));
+ }
+ capabilitiesToReturn.add(initiateNewCapability(storedComponent, capabilityDefinitionToUpdate));
+
+ capabilitiesDefsToCreateOrUpdate.addAll(capabilitiesToReturn);
+ capabilitiesDefsToCreateOrUpdate.addAll(capabilitiesListStoredInComponent);
+ return Either.left(capabilitiesDefsToCreateOrUpdate);
+ }
+
+ private Either<List<CapabilityDefinition>, ResponseFormat> handleCapabilityTypeUpdateWhenNewTypeNotExist(
+ List<CapabilityDefinition> capabilityDefinitions,
+ org.openecomp.sdc.be.model.Component storedComponent,
+ Map<String, List<CapabilityDefinition>> storedComponentCapabilities) {
+ for (CapabilityDefinition capabilityDefinitionToUpdate : capabilityDefinitions) {
+
+ 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()));
+ }
+ CapabilityDefinition capabilityDefinitionToDelete = definitionOptional.get();
+ Boolean isCapabilityUsedInServiceComposition = isCapabilityUsedInServiceComposition(
+ capabilityDefinitionToDelete, storedComponent);
+ if (isCapabilityUsedInServiceComposition) {
+ LOGGER.error("Capability {} can't be edited, since it is used in service composition",
+ capabilityDefinitionToDelete.getUniqueId());
+ return Either.right(componentsUtils.getResponseFormat(
+ ActionStatus.CAPABILITY_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION,
+ capabilityDefinitionToDelete.getName()));
+ }
+ Either<List<CapabilityDefinition>, StorageOperationStatus> deleteCapabilityEither
+ = deleteCapability(storedComponent, storedComponentCapabilities,
+ capabilityDefinitionToDelete);
+ if (deleteCapabilityEither.isRight()) {
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(deleteCapabilityEither.right().value()));
+ }
+ }
+ return null;
+ }
+
+ 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);
+ if (componentEither.isRight()) {
+ return Either.right(componentEither.right().value());
+ }
+ org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
+
+ 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));
+ }
+
+ 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);
+ } catch (Exception e) {
+ LOGGER.error(EXCEPTION_OCCURRED_DURING_CAPABILITIES, "get", e);
+ 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()));
+ }
+ }
+ }
+
+ 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);
+ if (componentEither.isRight()) {
+ return Either.right(componentEither.right().value());
+ }
+ org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value();
+
+ 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);
+ } catch (Exception e) {
+ LOGGER.error(EXCEPTION_OCCURRED_DURING_CAPABILITIES, "delete", e);
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND));
+ } finally {
+ if (lockResult.isLeft() && lockResult.left().value()) {
+ graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
+ NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
+ }
+ }
+ }
+
+ 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);
+ }
+ capabilitiesListStoredInComponent.removeIf(capabilityDefinition ->
+ capabilityDefinition.getUniqueId().equals(capabilityDefinitionToDelete.getUniqueId()));
+ Either<List<CapabilityDefinition>, StorageOperationStatus> result;
+ if (capabilitiesListStoredInComponent.isEmpty()) {
+ StorageOperationStatus operationStatus = capabilitiesOperation.deleteCapabilities(storedComponent,
+ capabilityDefinitionToDelete.getType());
+ if (StorageOperationStatus.OK.equals(operationStatus)) {
+ result = Either.left(Collections.singletonList(capabilityDefinitionToDelete));
+ } else {
+ result = Either.right(operationStatus);
+ }
+ } else {
+ result = capabilitiesOperation.updateCapabilities(storedComponent.getUniqueId(),
+ capabilitiesListStoredInComponent);
+ }
+ return result;
+ }
+
+
+ private Either<org.openecomp.sdc.be.model.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);
+ 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.left(componentStorageOperationStatusEither.left().value());
+ }
+
+ private Either<Boolean, ResponseFormat> lockComponentResult(
+ boolean lock, org.openecomp.sdc.be.model.Component component,
+ String action) {
+ if (lock) {
+ 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());
+ titanDao.rollback();
+ return Either.right(lockResult.right().value());
+ }
+ }
+ return Either.left(true);
+ }
+
+ 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);
+
+ }
+
+ private CapabilityDefinition initiateNewCapability(
+ org.openecomp.sdc.be.model.Component component,
+ CapabilityDefinition capabilityDefinition) {
+ if (StringUtils.isEmpty(capabilityDefinition.getUniqueId()))
+ capabilityDefinition.setUniqueId(UUID.randomUUID().toString());
+ if (StringUtils.isEmpty(capabilityDefinition.getOwnerId()))
+ capabilityDefinition.setOwnerId(component.getUniqueId());
+ if (StringUtils.isEmpty(capabilityDefinition.getOwnerName()))
+ capabilityDefinition.setOwnerName(component.getName());
+ capabilityDefinition.setLeftOccurrences(capabilityDefinition.getMaxOccurrences());
+ return capabilityDefinition;
+ }
+
+ private CapabilityDefinition updateCapability(CapabilityDefinition storedCapability,
+ CapabilityDefinition capabilityToUpdate) {
+ storedCapability.setName(capabilityToUpdate.getName());
+ storedCapability.setDescription(capabilityToUpdate.getDescription());
+ storedCapability.setType(capabilityToUpdate.getType());
+ storedCapability.setValidSourceTypes(capabilityToUpdate.getValidSourceTypes());
+ storedCapability.setMinOccurrences(capabilityToUpdate.getMinOccurrences());
+ storedCapability.setMaxOccurrences(capabilityToUpdate.getMaxOccurrences());
+
+ 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
+ .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()));
+ }
+
+ public Either<Map<String, CapabilityTypeDefinition>, ResponseFormat> getAllCapabilityTypes() {
+ Either<Map<String, CapabilityTypeDefinition>, TitanOperationStatus> capabilityTypeCacheAll =
+ capabilityTypeOperation.getAllCapabilityTypes();
+ 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);
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.DATA_TYPE_CANNOT_BE_EMPTY));
+ } else {
+ 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());
+ }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CommonImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CommonImportManager.java
index b60b5c7e09..773dc639a9 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CommonImportManager.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CommonImportManager.java
@@ -173,7 +173,7 @@ public class CommonImportManager {
}
public enum ElementTypeEnum {
- POLICY_TYPE, GROUP_TYPE, DATA_TYPE, CAPABILITY_TYPE, INTERFACE_LIFECYCLE_TYPE
+ POLICY_TYPE, GROUP_TYPE, DATA_TYPE, CAPABILITY_TYPE, INTERFACE_LIFECYCLE_TYPE, RELATIONSHIP_TYPE
}
private ActionStatus convertFromStorageResponseForElementType(StorageOperationStatus status, ElementTypeEnum elementTypeEnum) {
@@ -191,6 +191,9 @@ public class CommonImportManager {
case INTERFACE_LIFECYCLE_TYPE:
ret = componentsUtils.convertFromStorageResponseForLifecycleType(status);
break;
+ case RELATIONSHIP_TYPE:
+ ret = componentsUtils.convertFromStorageResponseForRelationshipType(status);
+ break;
default:
ret = componentsUtils.convertFromStorageResponse(status);
break;
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RelationshipTypeBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RelationshipTypeBusinessLogic.java
new file mode 100644
index 0000000000..4a909785b2
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RelationshipTypeBusinessLogic.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.components.impl;
+
+import java.util.Map;
+
+import fj.data.Either;
+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.impl.ComponentsUtils;
+import org.openecomp.sdc.be.model.RelationshipTypeDefinition;
+import org.openecomp.sdc.be.model.operations.impl.RelationshipTypeOperation;
+import org.openecomp.sdc.exception.ResponseFormat;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component("relationshipTypeBusinessLogic")
+public class RelationshipTypeBusinessLogic {
+
+ @Autowired
+ private RelationshipTypeOperation relationshipTypeOperation;
+
+ @Autowired
+ protected ComponentsUtils componentsUtils;
+
+ public Either<Map<String, RelationshipTypeDefinition>, ResponseFormat> getAllRelationshipTypes() {
+ Either<Map<String, RelationshipTypeDefinition>, TitanOperationStatus> allRelationshipTypes =
+ relationshipTypeOperation.getAllRelationshipTypes();
+ if (allRelationshipTypes.isRight()) {
+ TitanOperationStatus operationStatus = allRelationshipTypes.right().value();
+ if (TitanOperationStatus.NOT_FOUND == operationStatus) {
+ BeEcompErrorManager.getInstance().logInternalDataError("FetchRelationshipTypes", "Relationship types "
+ + "are "
+ + "not loaded",
+ BeEcompErrorManager.ErrorSeverity.ERROR);
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.DATA_TYPE_CANNOT_BE_EMPTY));
+ } else {
+ BeEcompErrorManager.getInstance().logInternalFlowError("FetchRelationshipTypes", "Failed to fetch "
+ + "relationship types",
+ BeEcompErrorManager.ErrorSeverity.ERROR);
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+ }
+ }
+ return Either.left(allRelationshipTypes.left().value());
+ }
+
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RelationshipTypeImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RelationshipTypeImportManager.java
new file mode 100644
index 0000000000..18671f8caf
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RelationshipTypeImportManager.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.components.impl;
+
+import java.util.List;
+import java.util.Map;
+
+import fj.data.Either;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.openecomp.sdc.be.components.impl.CommonImportManager.ElementTypeEnum;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.impl.ComponentsUtils;
+import org.openecomp.sdc.be.model.RelationshipTypeDefinition;
+import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
+import org.openecomp.sdc.be.model.operations.impl.RelationshipTypeOperation;
+import org.openecomp.sdc.be.utils.TypeUtils;
+import org.openecomp.sdc.exception.ResponseFormat;
+import org.springframework.stereotype.Component;
+
+@Component("relationshipTypeImportManager")
+public class RelationshipTypeImportManager {
+
+ private final RelationshipTypeOperation relationshipTypeOperation;
+ private final CommonImportManager commonImportManager;
+ private ComponentsUtils componentsUtils;
+
+ public RelationshipTypeImportManager(RelationshipTypeOperation relationshipTypeOperation,
+ CommonImportManager commonImportManager) {
+ this.relationshipTypeOperation = relationshipTypeOperation;
+ this.commonImportManager = commonImportManager;
+ }
+
+ public Either<List<ImmutablePair<RelationshipTypeDefinition, Boolean>>, ResponseFormat> createRelationshipTypes(
+ String relationshipYml) {
+ return createRelationshipTypes(relationshipYml, false);
+ }
+
+ private Either<List<ImmutablePair<RelationshipTypeDefinition, Boolean>>, ResponseFormat> createRelationshipTypes(
+ String relationshipTypeYml, boolean inTransaction) {
+ return commonImportManager.createElementTypes(relationshipTypeYml,
+ relationshipTypesFromYml -> createRelationshipTypesFromYml(relationshipTypeYml),
+ relationshipTypesToCreate -> createRelationshipTypesByDao(relationshipTypesToCreate,
+ inTransaction), ElementTypeEnum.RELATIONSHIP_TYPE);
+ }
+
+ private Either<List<RelationshipTypeDefinition>, ActionStatus> createRelationshipTypesFromYml(
+ String relationshipTypeYml) {
+ return commonImportManager.createElementTypesFromYml(relationshipTypeYml,
+ this::createRelationshipType);
+ }
+
+ private Either<List<ImmutablePair<RelationshipTypeDefinition, Boolean>>, ResponseFormat> createRelationshipTypesByDao(
+ List<RelationshipTypeDefinition> relationshipTypesToCreate, boolean inTransaction) {
+ return commonImportManager.createElementTypesByDao(relationshipTypesToCreate, this::validateRelationshipType,
+ relationshipType -> new ImmutablePair<>(ElementTypeEnum.RELATIONSHIP_TYPE, relationshipType.getType()),
+ relationshipTypeName -> relationshipTypeOperation.getRelationshipTypeByName(relationshipTypeName)
+ .right().map(DaoStatusConverter::convertTitanStatusToStorageStatus),
+ relationshipType -> relationshipTypeOperation.addRelationshipType(relationshipType, inTransaction),
+ (newRelationshipType, oldRelationshipType) -> relationshipTypeOperation
+ .updateRelationshipType(newRelationshipType, oldRelationshipType, inTransaction));
+ }
+
+
+ private Either<ActionStatus, ResponseFormat> validateRelationshipType(RelationshipTypeDefinition relationshipType) {
+ Either<ActionStatus, ResponseFormat> result = Either.left(ActionStatus.OK);
+ if (relationshipType.getType() == null) {
+ ResponseFormat responseFormat =
+ componentsUtils.getResponseFormat(ActionStatus.MISSING_RELATIONSHIP_TYPE, relationshipType.getType());
+ result = Either.right(responseFormat);
+ }
+ return result;
+ }
+
+ private RelationshipTypeDefinition createRelationshipType(String relationshipTypeName,
+ Map<String, Object> toscaJson) {
+ RelationshipTypeDefinition relationshipType = new RelationshipTypeDefinition();
+
+ relationshipType.setType(relationshipTypeName);
+
+ // Description
+ commonImportManager.setField(toscaJson, TypeUtils.ToscaTagNamesEnum.DESCRIPTION.getElementName(),
+ relationshipType::setDescription);
+ // Derived From
+ commonImportManager.setField(toscaJson, TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName(),
+ relationshipType::setDerivedFrom);
+ // Properties
+ commonImportManager.setPropertiesMap(toscaJson, relationshipType::setProperties);
+ //valid-target-types
+ if(toscaJson.get("valid_target_types") instanceof List)
+ relationshipType.setValidTargetTypes((List<String>) toscaJson.get("valid_target_types"));
+
+ return relationshipType;
+ }
+
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RequirementBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RequirementBusinessLogic.java
new file mode 100644
index 0000000000..c07a9fc09f
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RequirementBusinessLogic.java
@@ -0,0 +1,518 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.components.impl;
+
+import fj.data.Either;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.openecomp.sdc.be.components.validation.RequirementValidation;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.model.ComponentParametersView;
+import org.openecomp.sdc.be.model.RequirementDefinition;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.model.jsontitan.operations.RequirementOperation;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+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.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+@Component("requirementBusinessLogic")
+public class RequirementBusinessLogic extends BaseBusinessLogic {
+ private static final Logger LOGGER = LoggerFactory.getLogger(RequirementBusinessLogic.class);
+ private static final String FAILED_TO_LOCK_COMPONENT_RESPONSE_IS
+ = "Failed to lock component {}. Response is {}";
+ private static final String DELETE_REQUIREMENTS = "deleteRequirement";
+ private static final String GET_REQUIREMENTS = "getRequirements";
+ private static final String EXCEPTION_OCCURRED_DURING_REQUIREMENTS
+ = "Exception occurred during {}. Response is {}";
+
+ @Autowired
+ private RequirementOperation requirementOperation;
+ @Autowired
+ private RequirementValidation requirementValidation;
+
+
+ public void setRequirementOperation(RequirementOperation requirementOperation) {
+ this.requirementOperation = requirementOperation;
+ }
+
+ public void setRequirementValidation(RequirementValidation requirementValidation) {
+ this.requirementValidation = requirementValidation;
+ }
+
+ public Either<List<RequirementDefinition>, ResponseFormat> createRequirements(
+ String componentId, List<RequirementDefinition> requirementDefinitions,
+ 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> requirementsValidationEither = requirementValidation
+ .validateRequirements(requirementDefinitions, storedComponent, false);
+ if (requirementsValidationEither.isRight()) {
+ return Either.right(requirementsValidationEither.right().value());
+ }
+
+ Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock,
+ storedComponent, errorContext);
+ if (lockResult.isRight()) {
+ return Either.right(lockResult.right().value());
+ }
+
+ try {
+ Either<List<RequirementDefinition>, StorageOperationStatus> result;
+ List<RequirementDefinition> requirementsListStoredInComponent = null;
+ Map<String, List<RequirementDefinition>> storedComponentRequirements
+ = storedComponent.getRequirements();
+ if (org.apache.commons.collections.MapUtils.isNotEmpty(storedComponentRequirements)) {
+ RequirementDefinition requirementDefinitionToGetType = requirementDefinitions.get(0);
+ if(Objects.isNull(requirementDefinitionToGetType)) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
+ }
+ requirementsListStoredInComponent
+ = getRequirementStoredInComponentByType(requirementDefinitionToGetType
+ .getCapability(), storedComponentRequirements);
+ }
+ List<RequirementDefinition> requirementsToReturn;
+ if (org.apache.commons.collections.CollectionUtils
+ .isNotEmpty(requirementsListStoredInComponent)) {
+ List<RequirementDefinition> requirementDefToCreate = requirementDefinitions.stream()
+ .map(requirementDefinition -> initiateNewRequirement(storedComponent, requirementDefinition))
+ .collect(Collectors.toList());
+ requirementsToReturn = requirementDefToCreate;
+ requirementDefToCreate.addAll(requirementsListStoredInComponent);
+ result = requirementOperation.updateRequirement(componentId, requirementDefToCreate);
+ } else {
+ requirementsToReturn = requirementDefinitions.stream().map(requirementDefinition ->
+ initiateNewRequirement(storedComponent, requirementDefinition))
+ .collect(Collectors.toList());
+ result = requirementOperation.addRequirement(componentId, requirementsToReturn);
+ }
+ if (result.isRight()) {
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(
+ componentsUtils.convertFromStorageResponse(result.right().value(),
+ storedComponent.getComponentType()), ""));
+ }
+ titanDao.commit();
+ return Either.left(requirementsToReturn);
+ } catch (Exception e) {
+ titanDao.rollback();
+ LOGGER.error(EXCEPTION_OCCURRED_DURING_REQUIREMENTS, "addOrUpdate", e);
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+ } finally {
+ if (lockResult.isLeft() && lockResult.left().value()) {
+ graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
+ NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
+ }
+ }
+ }
+
+ public Either<List<RequirementDefinition>, ResponseFormat> updateRequirements(
+ String componentId, List<RequirementDefinition> requirementDefinitions,
+ 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> requirementsValidationEither = requirementValidation
+ .validateRequirements(requirementDefinitions, storedComponent, true);
+ if (requirementsValidationEither.isRight()) {
+ return Either.right(requirementsValidationEither.right().value());
+ }
+
+ Either<Boolean, ResponseFormat> lockResult = lockComponentResult(lock,
+ storedComponent, errorContext);
+ if (lockResult.isRight()) {
+ return Either.right(lockResult.right().value());
+ }
+ try {
+ Either<List<RequirementDefinition>, StorageOperationStatus> result;
+ List<RequirementDefinition> requirementsListStoredInComponent = null;
+ Map<String, List<RequirementDefinition>> storedComponentRequirements
+ = storedComponent.getRequirements();
+ if (org.apache.commons.collections.MapUtils.isNotEmpty(storedComponentRequirements)) {
+ RequirementDefinition requirementDefinitionToGetType = requirementDefinitions.get(0);
+ if(Objects.isNull(requirementDefinitionToGetType)) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
+ }
+ requirementsListStoredInComponent
+ = getRequirementStoredInComponentByType(requirementDefinitionToGetType
+ .getCapability(), storedComponentRequirements);
+ }
+ List<RequirementDefinition> requirementsToReturn = null;
+ if (org.apache.commons.collections.CollectionUtils
+ .isNotEmpty(requirementsListStoredInComponent)) {
+ List<RequirementDefinition> requirementDefToUpdate = new ArrayList<>();
+ if (requirementDefinitions.stream().anyMatch(requirementDefinition ->
+ isRequirementUsedInServiceComposition(requirementDefinition, storedComponent))) {
+ LOGGER.error("Requirement can't be edited, since it is used in service composition");
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus
+ .REQUIREMENT_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION));
+ }
+ for (RequirementDefinition requirementDefinitionToUpdate : requirementDefinitions) {
+ requirementsToReturn = requirementsListStoredInComponent.stream()
+ .filter(reqToUpdate -> reqToUpdate.getUniqueId()
+ .equals(requirementDefinitionToUpdate.getUniqueId()))
+ .map(requirementDefinition -> updateRequirement(requirementDefinition,
+ requirementDefinitionToUpdate)).collect(Collectors.toList());
+ requirementsListStoredInComponent.removeIf(reqToUpdate ->
+ reqToUpdate.getUniqueId().equals(requirementDefinitionToUpdate.getUniqueId()));
+
+ if (CollectionUtils.isNotEmpty(requirementsToReturn)) {
+ requirementsListStoredInComponent.addAll(requirementsToReturn);
+ requirementDefToUpdate.addAll(requirementsListStoredInComponent);
+ } else {
+ Either<List<RequirementDefinition>, ResponseFormat> updateCapTypeEither
+ = handleUpdateRequirementCapabilityWhenNewCapabilityExist(storedComponent,
+ storedComponentRequirements,
+ requirementsToReturn, requirementDefinitionToUpdate);
+ if (updateCapTypeEither.isRight()) {
+ return Either.right(updateCapTypeEither.right().value());
+ }
+ requirementDefToUpdate = updateCapTypeEither.left().value();
+ }
+ }
+ result = requirementOperation.updateRequirement(componentId, requirementDefToUpdate);
+ } else {
+ Either<List<RequirementDefinition>, ResponseFormat> requirementDefinitionToDelete
+ = handleRequirementCapabilityUpdateWhenNewCapabilityNotExist(requirementDefinitions,
+ storedComponent, storedComponentRequirements);
+ if (requirementDefinitionToDelete != null) {
+ return requirementDefinitionToDelete;
+ }
+ requirementsToReturn = requirementDefinitions.stream().map(requirementDefinition ->
+ initiateNewRequirement(storedComponent, requirementDefinition))
+ .collect(Collectors.toList());
+ result = requirementOperation.addRequirement(componentId, requirementsToReturn);
+ }
+ if (result.isRight()) {
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(
+ componentsUtils.convertFromStorageResponse(result.right().value(),
+ storedComponent.getComponentType()), ""));
+ }
+ titanDao.commit();
+ return Either.left(requirementsToReturn);
+ } catch (Exception e) {
+ titanDao.rollback();
+ LOGGER.error(EXCEPTION_OCCURRED_DURING_REQUIREMENTS, "addOrUpdate", e);
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+ } finally {
+ if (lockResult.isLeft() && lockResult.left().value()) {
+ graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
+ NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
+ }
+ }
+ }
+
+ private Either<List<RequirementDefinition>, ResponseFormat> handleUpdateRequirementCapabilityWhenNewCapabilityExist(
+ org.openecomp.sdc.be.model.Component storedComponent,
+ Map<String, List<RequirementDefinition>> storedComponentRequirements,
+ List<RequirementDefinition> requirementsToReturn,
+ RequirementDefinition requirementDefinitionToUpdate) {
+ List<RequirementDefinition> requirementsListStoredInComponent;
+ List<RequirementDefinition> requirementDefsToCreateOrUpdate = new ArrayList<>();
+ Optional<RequirementDefinition> definitionOptional = storedComponentRequirements
+ .values().stream().flatMap(Collection::stream)
+ .filter(requirementDefinition -> requirementDefinition.getUniqueId()
+ .equals(requirementDefinitionToUpdate.getUniqueId())).findAny();
+ if (!definitionOptional.isPresent()) {
+ return Either.right(componentsUtils.getResponseFormat(
+ ActionStatus.REQUIREMENT_NOT_FOUND, storedComponent.getUniqueId()));
+ }
+ RequirementDefinition requirementDefinitionToDelete = definitionOptional.get();
+
+ requirementsListStoredInComponent = getRequirementStoredInComponentByType(
+ requirementDefinitionToUpdate.getCapability(), storedComponentRequirements);
+ Either<List<RequirementDefinition>, StorageOperationStatus> deleteRequirementEither
+ = deleteRequirement(storedComponent, storedComponentRequirements, requirementDefinitionToDelete);
+ if (deleteRequirementEither.isRight()) {
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(deleteRequirementEither.right().value()));
+ }
+ requirementsToReturn.add(initiateNewRequirement(storedComponent, requirementDefinitionToUpdate));
+
+ requirementDefsToCreateOrUpdate.addAll(requirementsToReturn);
+ requirementDefsToCreateOrUpdate.addAll(requirementsListStoredInComponent);
+ return Either.left(requirementDefsToCreateOrUpdate);
+ }
+
+ private Either<List<RequirementDefinition>, ResponseFormat> handleRequirementCapabilityUpdateWhenNewCapabilityNotExist(
+ List<RequirementDefinition> requirementDefinitions,
+ org.openecomp.sdc.be.model.Component storedComponent,
+ Map<String, List<RequirementDefinition>> storedComponentRequirements) {
+ for (RequirementDefinition requirementDefinitionToUpdate : requirementDefinitions) {
+
+ Optional<RequirementDefinition> definitionOptional = storedComponentRequirements
+ .values().stream().flatMap(Collection::stream)
+ .filter(requirementDefinition -> requirementDefinition.getUniqueId()
+ .equals(requirementDefinitionToUpdate.getUniqueId())).findAny();
+ if (!definitionOptional.isPresent()) {
+ return Either.right(componentsUtils.getResponseFormat(
+ ActionStatus.REQUIREMENT_NOT_FOUND, storedComponent.getUniqueId()));
+ }
+ RequirementDefinition requirementDefinitionToDelete = definitionOptional.get();
+ Boolean isRequirementUsedInServiceComposition
+ = isRequirementUsedInServiceComposition(requirementDefinitionToDelete, storedComponent);
+ if (isRequirementUsedInServiceComposition) {
+ LOGGER.error("Requirement {} can't be edited, since it is used in service composition",
+ requirementDefinitionToDelete.getUniqueId());
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus
+ .REQUIREMENT_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION,
+ requirementDefinitionToDelete.getName()));
+ }
+ Either<List<RequirementDefinition>, StorageOperationStatus> deleteRequirementEither
+ = deleteRequirement(storedComponent, storedComponentRequirements, requirementDefinitionToDelete);
+ if (deleteRequirementEither.isRight()) {
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(deleteRequirementEither.right().value()));
+ }
+ }
+ return null;
+ }
+
+ public Either<RequirementDefinition, ResponseFormat> getRequirement(String componentId,
+ String requirementIdToGet, User user, boolean lock) {
+ validateUserExists(user.getUserId(), GET_REQUIREMENTS, 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> lockResult = lockComponentResult(lock, storedComponent, GET_REQUIREMENTS);
+ if (lockResult.isRight()) {
+ return Either.right(lockResult.right().value());
+ }
+ try {
+
+ List<RequirementDefinition> requirementDefinitions = storedComponent.getRequirements().values().stream()
+ .flatMap(Collection::stream).collect(Collectors.toList());
+ if (requirementDefinitions.isEmpty()) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.REQUIREMENT_NOT_FOUND, componentId));
+ }
+
+ RequirementDefinition requirementDefinitionToReturn;
+ Optional<RequirementDefinition> requirementDefinitionOptional = requirementDefinitions.stream()
+ .filter(requirementDefinition -> requirementDefinition.getUniqueId().equals(requirementIdToGet)).findAny();
+ if (requirementDefinitionOptional.isPresent()) {
+ requirementDefinitionToReturn = requirementDefinitionOptional.get();
+ } else {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.REQUIREMENT_NOT_FOUND, componentId));
+ }
+ return Either.left(requirementDefinitionToReturn);
+ } catch (Exception e) {
+ LOGGER.error(EXCEPTION_OCCURRED_DURING_REQUIREMENTS, "get", e);
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.REQUIREMENT_NOT_FOUND, componentId));
+ } finally {
+ if (lockResult.isLeft() && lockResult.left().value()) {
+ graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
+ NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
+ }
+ }
+ }
+
+ public Either<RequirementDefinition, ResponseFormat> deleteRequirement(String componentId,
+ String requirementIdToDelete,
+ User user, boolean lock) {
+ validateUserExists(user.getUserId(), DELETE_REQUIREMENTS, 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> lockResult = lockComponentResult(lock, storedComponent, DELETE_REQUIREMENTS);
+ if (lockResult.isRight()) {
+ return Either.right(lockResult.right().value());
+ }
+
+ try {
+ Map<String, List<RequirementDefinition>> storedComponentRequirements = storedComponent.getRequirements();
+ if (storedComponentRequirements.isEmpty()) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.REQUIREMENT_NOT_FOUND, componentId));
+ }
+
+ Optional<RequirementDefinition> definitionOptional = storedComponentRequirements
+ .values().stream().flatMap(Collection::stream)
+ .filter(requirementDefinition -> requirementDefinition.getUniqueId()
+ .equals(requirementIdToDelete)).findAny();
+ if (!definitionOptional.isPresent()) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.REQUIREMENT_NOT_FOUND, componentId));
+ }
+ RequirementDefinition requirementDefinitionToDelete = definitionOptional.get();
+
+ Boolean isRequirementUsedInServiceComposition
+ = isRequirementUsedInServiceComposition(requirementDefinitionToDelete, storedComponent);
+ if (isRequirementUsedInServiceComposition) {
+ LOGGER.error("Requirement {} can't be deleted, since it is used in service composition",
+ requirementDefinitionToDelete.getUniqueId());
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus
+ .CAPABILITY_DELETION_NOT_ALLOWED_USED_IN_COMPOSITION,
+ requirementDefinitionToDelete.getName()));
+ }
+
+ Either<List<RequirementDefinition>, StorageOperationStatus> result
+ = deleteRequirement(storedComponent, storedComponentRequirements, requirementDefinitionToDelete);
+ if (result.isRight()) {
+ titanDao.rollback();
+ LOGGER.error("Failed to delete requirement 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(requirementDefinitionToDelete);
+ } catch (Exception e) {
+ LOGGER.error(EXCEPTION_OCCURRED_DURING_REQUIREMENTS, "delete", e);
+ titanDao.rollback();
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.REQUIREMENT_NOT_FOUND));
+ } finally {
+ if (lockResult.isLeft() && lockResult.left().value()) {
+ graphLockOperation.unlockComponent(storedComponent.getUniqueId(),
+ NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue()));
+ }
+ }
+ }
+
+ private Either<List<RequirementDefinition>, StorageOperationStatus> deleteRequirement(
+ org.openecomp.sdc.be.model.Component storedComponent, Map<String,
+ List<RequirementDefinition>> storedComponentRequirements,
+ RequirementDefinition requirementDefinitionToDelete) {
+ List<RequirementDefinition> requirementStoredInComponentByType =
+ getRequirementStoredInComponentByType(requirementDefinitionToDelete.getCapability(),
+ storedComponentRequirements);
+ if(requirementStoredInComponentByType == null) {
+ return Either.right(StorageOperationStatus.BAD_REQUEST);
+ }
+ requirementStoredInComponentByType.removeIf(requirementDefinition ->
+ requirementDefinition.getUniqueId().equals(requirementDefinitionToDelete.getUniqueId()));
+ Either<List<RequirementDefinition>, StorageOperationStatus> result;
+ if (requirementStoredInComponentByType.isEmpty()) {
+
+ StorageOperationStatus operationStatus = requirementOperation.deleteRequirements(storedComponent,
+ requirementDefinitionToDelete.getCapability());
+ if (operationStatus.equals(StorageOperationStatus.OK)) {
+ result = Either.left(Collections.singletonList(requirementDefinitionToDelete));
+ } else {
+ result = Either.right(operationStatus);
+ }
+ } else {
+ result = requirementOperation.updateRequirement(storedComponent.getUniqueId(),
+ requirementStoredInComponentByType);
+ }
+ return result;
+ }
+
+ private Either<org.openecomp.sdc.be.model.Component, ResponseFormat> getComponentDetails(String componentId) {
+ ComponentParametersView filter = new ComponentParametersView(true);
+ filter.setIgnoreRequirements(false);
+ Either<org.openecomp.sdc.be.model.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.left(componentStorageOperationStatusEither.left().value());
+ }
+
+ private Either<Boolean, ResponseFormat> lockComponentResult(boolean lock,
+ org.openecomp.sdc.be.model.Component component,
+ String action) {
+ if (lock) {
+ 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());
+ titanDao.rollback();
+ return Either.right(lockResult.right().value());
+ }
+ }
+ return Either.left(true);
+ }
+
+ private List<RequirementDefinition> getRequirementStoredInComponentByType(
+ String capabilityType, Map<String,
+ List<RequirementDefinition>> requirements) {
+
+ Optional<Map.Entry<String, List<RequirementDefinition>>> entryOptional
+ = requirements.entrySet().stream().filter(map -> map.getKey().equals(capabilityType)).findFirst();
+ return entryOptional.map(Map.Entry::getValue).orElse(null);
+
+ }
+
+ private RequirementDefinition initiateNewRequirement(org.openecomp.sdc.be.model.Component component,
+ RequirementDefinition requirementDefinition) {
+ if (StringUtils.isEmpty(requirementDefinition.getUniqueId()))
+ requirementDefinition.setUniqueId(UUID.randomUUID().toString());
+ if (StringUtils.isEmpty(requirementDefinition.getOwnerId()))
+ requirementDefinition.setOwnerId(component.getUniqueId());
+ if (StringUtils.isEmpty(requirementDefinition.getOwnerName()))
+ requirementDefinition.setOwnerName(component.getName());
+ requirementDefinition.setLeftOccurrences(requirementDefinition.getMaxOccurrences());
+ return requirementDefinition;
+ }
+
+ private RequirementDefinition updateRequirement(RequirementDefinition storedRequirement,
+ RequirementDefinition requirementToUpdate) {
+ storedRequirement.setName(requirementToUpdate.getName());
+ storedRequirement.setCapability(requirementToUpdate.getCapability());
+ storedRequirement.setNode(requirementToUpdate.getNode());
+ storedRequirement.setRelationship(requirementToUpdate.getRelationship());
+ storedRequirement.setMinOccurrences(requirementToUpdate.getMinOccurrences());
+ storedRequirement.setMaxOccurrences(requirementToUpdate.getMaxOccurrences());
+ return storedRequirement;
+ }
+
+ private Boolean isRequirementUsedInServiceComposition(RequirementDefinition requirementDefinition,
+ org.openecomp.sdc.be.model.Component component) {
+ Either<List<org.openecomp.sdc.be.model.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()
+ .getRequirementUid().equals(requirementDefinition.getUniqueId()));
+ }
+}
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 e6a6491aed..2ca6ca41cb 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
@@ -37,6 +37,7 @@ import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter;
import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
+import org.openecomp.sdc.be.tosca.ToscaUtils;
import org.openecomp.sdc.be.user.Role;
import org.openecomp.sdc.common.log.wrappers.Logger;
import org.openecomp.sdc.exception.ResponseFormat;
@@ -193,6 +194,7 @@ public class CertificationChangeTransition extends LifeCycleTransition {
}
}
updateCalculatedCapabilitiesRequirements(componentAfterCertification);
+ updateCapReqOwnerId(componentAfterCertification);
result = Either.left(componentAfterCertification);
return result;
} finally {
@@ -212,6 +214,12 @@ public class CertificationChangeTransition extends LifeCycleTransition {
}
+ private void updateCapReqOwnerId(Component component) {
+ if(component.isTopologyTemplate() && ToscaUtils.isNotComplexVfc(component)) {
+ toscaOperationFacade.updateCapReqOwnerId(component.getUniqueId());
+ }
+ }
+
private void updateCalculatedCapabilitiesRequirements(Component certifiedComponent) {
if(certifiedComponent.getComponentType() == ComponentTypeEnum.SERVICE){
toscaOperationFacade.updateNamesOfCalculatedCapabilitiesRequirements(certifiedComponent.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 525df14ef8..0c4464239e 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,6 +123,7 @@ public class CheckoutTransition extends LifeCycleTransition {
}
}
handleCalculatedCapabilitiesRequirements(clonedComponent);
+ updateCapReqOwnerId(clonedComponent);
}
} finally {
@@ -148,6 +149,11 @@ public class CheckoutTransition extends LifeCycleTransition {
}
}
+ private void updateCapReqOwnerId(Component component) {
+ if(component.isTopologyTemplate() && ToscaUtils.isNotComplexVfc(component)) {
+ toscaOperationFacade.updateCapReqOwnerId(component.getUniqueId());
+ }
+ }
private StorageOperationStatus upgradeToLatestGenericData(Component clonedComponent) {
StorageOperationStatus updateStatus = StorageOperationStatus.OK;
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/utils/MergeInstanceUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/utils/MergeInstanceUtils.java
index 06da9ecd98..55cf75b769 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/utils/MergeInstanceUtils.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/merge/utils/MergeInstanceUtils.java
@@ -122,11 +122,17 @@ public class MergeInstanceUtils {
else {
instanceBuildingBlocks = ComponentInstanceBuildingBlocks.of(new ArrayList<>(), singletonList(componentInstance));
}
+ return instanceBuildingBlocks;
}
else {
instanceBuildingBlocks = recursiveScanForAtomicBuildingBlocks(component);
+ if(org.apache.commons.collections.MapUtils.isNotEmpty(component.getCapabilities()) || org.apache.commons.collections.MapUtils.isNotEmpty(component.getRequirements())) {
+ ComponentInstanceBuildingBlocks nonAtomicBlocks = ComponentInstanceBuildingBlocks.of(new ArrayList<>(), singletonList(componentInstance));
+ return ComponentInstanceBuildingBlocks.merge(instanceBuildingBlocks, nonAtomicBlocks);
+ }
+ return instanceBuildingBlocks;
+
}
- return instanceBuildingBlocks;
}
public RelationMergeInfo mapRelationCapability(RequirementCapabilityRelDef relDef, List<CapabilityOwner> capsOwners) {
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
new file mode 100644
index 0000000000..9590ec97d9
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/CapabilitiesValidation.java
@@ -0,0 +1,266 @@
+/*
+ * 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.validation;
+
+import fj.data.Either;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
+import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.exception.ResponseFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+@Component("capabilitiesValidation")
+public class CapabilitiesValidation {
+ private static final Logger LOGGER = LoggerFactory.getLogger(CapabilitiesValidation.class);
+ private static final String CAPABILITY_NOT_FOUND_IN_COMPONENT = "Capability not found in component {} ";
+ private static final Pattern NAME_VALIDATION_REGEX_PATTERN = Pattern.compile("^[a-zA-Z0-9_.]*$");
+
+ public Either<Boolean, ResponseFormat> validateCapabilities(
+ Collection<CapabilityDefinition> capabilities,
+ org.openecomp.sdc.be.model.Component component, boolean isUpdate) {
+
+ for(CapabilityDefinition capabilityDefinition : capabilities) {
+ Either<Boolean, ResponseFormat> validateCapabilityResponse = validateCapability(
+ capabilityDefinition, component, isUpdate);
+ if (validateCapabilityResponse.isRight()) {
+ return validateCapabilityResponse;
+ }
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ private Either<Boolean, ResponseFormat> validateCapability(CapabilityDefinition capabilityDefinition,
+ org.openecomp.sdc.be.model.Component component,
+ boolean isUpdate) {
+ ResponseFormatManager responseFormatManager = getResponseFormatManager();
+
+ if(isUpdate) {
+ Either<Boolean, ResponseFormat> capabilityExistValidationEither
+ = isCapabilityExist(capabilityDefinition, responseFormatManager, component);
+ if (capabilityExistValidationEither.isRight()) {
+ return Either.right(capabilityExistValidationEither.right().value());
+ }
+ }
+ Either<Boolean, ResponseFormat> capabilityNameValidationResponse
+ = validateCapabilityName(capabilityDefinition, responseFormatManager, component, isUpdate);
+ if (capabilityNameValidationResponse.isRight()) {
+ return Either.right(capabilityNameValidationResponse.right().value());
+ }
+ Either<Boolean, ResponseFormat> capabilityTypeEmptyEither =
+ isCapabilityTypeEmpty(responseFormatManager, capabilityDefinition.getType());
+ 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);
+ }
+
+ private Either<Boolean, ResponseFormat> validateOccurrences(CapabilityDefinition capabilityDefinition,
+ ResponseFormatManager responseFormatManager) {
+ String maxOccurrences = capabilityDefinition.getMaxOccurrences();
+ String minOccurrences = capabilityDefinition.getMinOccurrences();
+ if(StringUtils.isNotEmpty(maxOccurrences) && StringUtils.isNotEmpty(minOccurrences)) {
+ Either<Boolean, ResponseFormat> capabilityOccurrencesValidationEither =
+ validateOccurrences(responseFormatManager, minOccurrences,
+ maxOccurrences);
+ if (capabilityOccurrencesValidationEither.isRight()) {
+ return Either.right(capabilityOccurrencesValidationEither.right().value());
+ }
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ private Either<Boolean, ResponseFormat> isCapabilityExist(CapabilityDefinition definition,
+ ResponseFormatManager responseFormatManager,
+ org.openecomp.sdc.be.model.Component component) {
+ Map<String, List<CapabilityDefinition>> componentCapabilities = component.getCapabilities();
+ if(MapUtils.isEmpty(componentCapabilities)){
+ LOGGER.error(CAPABILITY_NOT_FOUND_IN_COMPONENT, component.getUniqueId());
+ ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
+ .CAPABILITY_NOT_FOUND, component.getUniqueId());
+ return Either.right(errorResponse);
+ }
+
+ List<CapabilityDefinition> capabilityDefinitionList = componentCapabilities.values()
+ .stream().flatMap(Collection::stream).collect(Collectors.toList());
+ if(CollectionUtils.isEmpty(capabilityDefinitionList)){
+ LOGGER.error(CAPABILITY_NOT_FOUND_IN_COMPONENT, component.getUniqueId());
+ ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
+ .CAPABILITY_NOT_FOUND, component.getUniqueId());
+ return Either.right(errorResponse);
+ }
+ boolean isCapabilityExist = capabilityDefinitionList.stream().anyMatch(capabilityDefinition ->
+ capabilityDefinition.getUniqueId().equalsIgnoreCase(definition.getUniqueId()));
+
+ if(!isCapabilityExist) {
+ LOGGER.error(CAPABILITY_NOT_FOUND_IN_COMPONENT, component.getUniqueId());
+ ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
+ .CAPABILITY_NOT_FOUND, component.getUniqueId());
+ return Either.right(errorResponse);
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ private Either<Boolean, ResponseFormat> validateCapabilityName(CapabilityDefinition capabilityDefinition,
+ ResponseFormatManager responseFormatManager,
+ org.openecomp.sdc.be.model.Component component,
+ boolean isUpdate) {
+ Either<Boolean, ResponseFormat> capabilityNameEmptyEither =
+ isCapabilityNameEmpty(responseFormatManager, capabilityDefinition.getName());
+ if (capabilityNameEmptyEither.isRight()) {
+ return Either.right(capabilityNameEmptyEither.right().value());
+ }
+
+ Either<Boolean, ResponseFormat> capabilityNameRegexValidationResponse =
+ isCapabilityNameRegexValid(responseFormatManager, capabilityDefinition.getName());
+ if (capabilityNameRegexValidationResponse.isRight()) {
+ return Either.right(capabilityNameRegexValidationResponse.right().value());
+ }
+
+ Either<Boolean, ResponseFormat> operationTypeUniqueResponse
+ = validateCapabilityNameUnique(capabilityDefinition, component, isUpdate );
+ if(operationTypeUniqueResponse.isRight()) {
+ return Either.right(operationTypeUniqueResponse.right().value());
+ }
+ if (!operationTypeUniqueResponse.left().value()) {
+ LOGGER.error("Capability name {} already in use ", capabilityDefinition.getName());
+ ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
+ .CAPABILITY_NAME_ALREADY_IN_USE, capabilityDefinition.getName());
+ return Either.right(errorResponse);
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ 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);
+ return Either.right(errorResponse);
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ 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);
+ return Either.right(errorResponse);
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+
+ private Either<Boolean, ResponseFormat> validateOccurrences (
+ ResponseFormatManager responseFormatManager,
+ String minOccurrences, String maxOccurrences ) {
+ if(StringUtils.isNotEmpty(maxOccurrences)&& "UNBOUNDED".equalsIgnoreCase(maxOccurrences)
+ && Integer.parseInt(minOccurrences) >= 0) {
+ return Either.left(Boolean.TRUE);
+ } else if(Integer.parseInt(minOccurrences) < 0) {
+ LOGGER.debug("Invalid occurrences format.low_bound occurrence negative {}", minOccurrences);
+ ResponseFormat responseFormat = responseFormatManager.getResponseFormat(ActionStatus.INVALID_OCCURRENCES);
+ return Either.right(responseFormat);
+ } else if(Integer.parseInt(maxOccurrences) < Integer.parseInt(minOccurrences)){
+ LOGGER.error("Capability maxOccurrences should be greater than minOccurrences");
+ ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
+ .MAX_OCCURRENCES_SHOULD_BE_GREATER_THAN_MIN_OCCURRENCES);
+ return Either.right(errorResponse);
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ 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()));
+
+ 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())) {
+ isCapabilityNameUnique = true;
+ }
+ }
+ return Either.left(isCapabilityNameUnique);
+ }
+
+ 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);
+ ResponseFormat errorResponse = responseFormatManager
+ .getResponseFormat(ActionStatus.INVALID_CAPABILITY_NAME, capabilityName);
+ return Either.right(errorResponse);
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ private boolean isValidCapabilityName(String capabilityName) {
+ return NAME_VALIDATION_REGEX_PATTERN.matcher(capabilityName).matches();
+ }
+
+ protected ResponseFormatManager getResponseFormatManager() {
+ return ResponseFormatManager.getInstance();
+ }
+
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/RequirementValidation.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/RequirementValidation.java
new file mode 100644
index 0000000000..0c6a29415a
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/RequirementValidation.java
@@ -0,0 +1,272 @@
+/*
+ * 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.validation;
+
+import fj.data.Either;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
+import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.model.RequirementDefinition;
+import org.openecomp.sdc.exception.ResponseFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+@Component("requirementValidation")
+public class RequirementValidation {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(RequirementValidation.class);
+ private static final String REQUIREMENT_NOT_FOUND_IN_COMPONENT = "Requirement not found in component {} ";
+ private static final Pattern NAME_VALIDATION_REGEX_PATTERN = Pattern.compile("^[a-zA-Z0-9_.]*$");
+
+ public Either<Boolean, ResponseFormat> validateRequirements(
+ Collection<RequirementDefinition> requirements,
+ org.openecomp.sdc.be.model.Component component, boolean isUpdate) {
+
+ for(RequirementDefinition requirementDefinition : requirements) {
+ Either<Boolean, ResponseFormat> requirementValidationResponse
+ = validateRequirement(requirementDefinition, component, isUpdate);
+ if (requirementValidationResponse.isRight()) {
+ return requirementValidationResponse;
+ }
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ private Either<Boolean, ResponseFormat> validateRequirement(
+ RequirementDefinition requirementDefinition,
+ org.openecomp.sdc.be.model.Component component,
+ boolean isUpdate) {
+ ResponseFormatManager responseFormatManager = getResponseFormatManager();
+ if(isUpdate) {
+ Either<Boolean, ResponseFormat> requirementExistValidationEither
+ = isRequirementExist(requirementDefinition, responseFormatManager, component);
+ if (requirementExistValidationEither.isRight()) {
+ return Either.right(requirementExistValidationEither.right().value());
+ }
+ }
+
+ Either<Boolean, ResponseFormat> requirementNameValidationResponse
+ = isRequirementNameValid(requirementDefinition, responseFormatManager,
+ component, isUpdate);
+ if (requirementNameValidationResponse.isRight()) {
+ return Either.right(requirementNameValidationResponse.right().value());
+ }
+
+ Either<Boolean, ResponseFormat> requirementTypeEmptyEither =
+ isRequirementCapabilityEmpty(responseFormatManager,
+ requirementDefinition.getCapability());
+ if (requirementTypeEmptyEither.isRight()) {
+ return Either.right(requirementTypeEmptyEither.right().value());
+ }
+ Either<Boolean, ResponseFormat> requirementOccurrencesValidationEither =
+ validateOccurrences(requirementDefinition, responseFormatManager);
+ if (requirementOccurrencesValidationEither.isRight()) {
+ return Either.right(requirementOccurrencesValidationEither.right().value());
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ private Either<Boolean, ResponseFormat> validateOccurrences(RequirementDefinition requirementDefinition,
+ ResponseFormatManager responseFormatManager) {
+ String maxOccurrences = requirementDefinition.getMaxOccurrences();
+ String minOccurrences = requirementDefinition.getMinOccurrences();
+ if(StringUtils.isNotEmpty(maxOccurrences) && StringUtils.isNotEmpty(minOccurrences)) {
+ Either<Boolean, ResponseFormat> requirementOccurrencesValidationEither =
+ validateOccurrences(responseFormatManager, minOccurrences,
+ maxOccurrences);
+ if (requirementOccurrencesValidationEither.isRight()) {
+ return Either.right(requirementOccurrencesValidationEither.right().value());
+ }
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ private Either<Boolean, ResponseFormat> isRequirementNameValid(
+ RequirementDefinition requirementDefinition,
+ ResponseFormatManager responseFormatManager,
+ org.openecomp.sdc.be.model.Component component, boolean isUpdate) {
+ Either<Boolean, ResponseFormat> requirementNameEmptyEither =
+ isRequirementNameEmpty(responseFormatManager, requirementDefinition.getName());
+ if (requirementNameEmptyEither.isRight()) {
+ return Either.right(requirementNameEmptyEither.right().value());
+ }
+
+ Either<Boolean, ResponseFormat> requirementNameRegexValidationResponse =
+ isRequirementNameRegexValid(responseFormatManager, requirementDefinition.getName());
+ if (requirementNameRegexValidationResponse.isRight()) {
+ return Either.right(requirementNameRegexValidationResponse.right().value());
+ }
+
+ Either<Boolean, ResponseFormat> requirementNameUniqueResponse
+ = validateRequirementNameUnique(requirementDefinition,
+ component, isUpdate );
+ if(requirementNameUniqueResponse.isRight()) {
+ return Either.right(requirementNameUniqueResponse.right().value());
+ }
+ if (!requirementNameUniqueResponse.left().value()) {
+ LOGGER.error("Requirement name {} already in use ", requirementDefinition.getName());
+ ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
+ .REQUIREMENT_NAME_ALREADY_IN_USE, requirementDefinition.getName());
+ return Either.right(errorResponse);
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ private Either<Boolean, ResponseFormat> isRequirementNameEmpty(
+ ResponseFormatManager responseFormatManager,
+ String requirementName) {
+ if (StringUtils.isEmpty(requirementName)) {
+ LOGGER.error("Requirement Name is mandatory");
+ ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
+ .REQUIREMENT_NAME_MANDATORY);
+ return Either.right(errorResponse);
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ private Either<Boolean, ResponseFormat> validateOccurrences (
+ ResponseFormatManager responseFormatManager,
+ String minOccurrences, String maxOccurrences ) {
+ if(StringUtils.isNotEmpty(maxOccurrences)&& "UNBOUNDED".equalsIgnoreCase(maxOccurrences)
+ && Integer.parseInt(minOccurrences) >= 0) {
+ return Either.left(Boolean.TRUE);
+ } else if(Integer.parseInt(minOccurrences) < 0) {
+ LOGGER.debug("Invalid occurrences format.low_bound occurrence negative {}", minOccurrences);
+ ResponseFormat responseFormat = responseFormatManager.getResponseFormat(ActionStatus.INVALID_OCCURRENCES);
+ return Either.right(responseFormat);
+ }
+ else if(Integer.parseInt(maxOccurrences) < Integer.parseInt(minOccurrences)){
+ LOGGER.error("Requirement maxOccurrences should be greater than minOccurrences");
+ ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
+ .MAX_OCCURRENCES_SHOULD_BE_GREATER_THAN_MIN_OCCURRENCES);
+ return Either.right(errorResponse);
+ }
+ return Either.left(Boolean.TRUE);
+ }
+ private Either<Boolean, ResponseFormat> isRequirementCapabilityEmpty(
+ ResponseFormatManager responseFormatManager,
+ String requirementCapability) {
+ if (StringUtils.isEmpty(requirementCapability)) {
+ LOGGER.error("Requirement capability is mandatory");
+ ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
+ .REQUIREMENT_CAPABILITY_MANDATORY);
+ return Either.right(errorResponse);
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ private Either<Boolean, ResponseFormat> validateRequirementNameUnique(
+ RequirementDefinition requirementDefinition,
+ org.openecomp.sdc.be.model.Component component,
+ boolean isUpdate) {
+ boolean isRequirementNameUnique = false;
+
+ Map<String, List<RequirementDefinition>> componentRequirements = component.getRequirements();
+ if(MapUtils.isEmpty(componentRequirements)){
+ return Either.left(true);
+ }
+ List<RequirementDefinition> requirementDefinitionList = componentRequirements.values()
+ .stream().flatMap(Collection::stream).collect(Collectors.toList());
+
+ if(CollectionUtils.isEmpty(requirementDefinitionList)){
+ return Either.left(true);
+ }
+
+ Map<String, String> requirementNameMap = new HashMap<>();
+ requirementDefinitionList.forEach(requirement -> requirementNameMap
+ .put(requirement.getUniqueId(), requirement.getName()));
+
+ if (!requirementNameMap.values().contains(requirementDefinition.getName())){
+ isRequirementNameUnique = true;
+ }
+ if (!isRequirementNameUnique && isUpdate){
+ List<Map.Entry<String, String>> reqNamesEntry = requirementNameMap.entrySet()
+ .stream().filter(entry -> entry.getValue().equalsIgnoreCase(requirementDefinition.getName()))
+ .collect(Collectors.toList());
+ if(reqNamesEntry.size() == 1 && reqNamesEntry.get(0).getKey()
+ .equals(requirementDefinition.getUniqueId())) {
+ isRequirementNameUnique = true;
+ }
+ }
+ return Either.left(isRequirementNameUnique);
+ }
+
+ private Either<Boolean, ResponseFormat> isRequirementExist(
+ RequirementDefinition definition,
+ ResponseFormatManager responseFormatManager,
+ org.openecomp.sdc.be.model.Component component) {
+ Map<String, List<RequirementDefinition>> componentRequirements = component.getRequirements();
+ if(MapUtils.isEmpty(componentRequirements)){
+ LOGGER.error(REQUIREMENT_NOT_FOUND_IN_COMPONENT, component.getUniqueId());
+ ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
+ .REQUIREMENT_NOT_FOUND, component.getUniqueId());
+ return Either.right(errorResponse);
+ }
+
+ List<RequirementDefinition> requirementDefinitionList = componentRequirements.values()
+ .stream().flatMap(Collection::stream).collect(Collectors.toList());
+ if(CollectionUtils.isEmpty(requirementDefinitionList)){
+ LOGGER.error(REQUIREMENT_NOT_FOUND_IN_COMPONENT, component.getUniqueId());
+ ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
+ .REQUIREMENT_NOT_FOUND, component.getUniqueId());
+ return Either.right(errorResponse);
+ }
+ boolean isRequirementExist = requirementDefinitionList.stream()
+ .anyMatch(requirementDefinition -> requirementDefinition.getUniqueId()
+ .equalsIgnoreCase(definition.getUniqueId()));
+
+ if(!isRequirementExist) {
+ LOGGER.error(REQUIREMENT_NOT_FOUND_IN_COMPONENT, component.getUniqueId());
+ ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus
+ .REQUIREMENT_NOT_FOUND, component.getUniqueId());
+ return Either.right(errorResponse);
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ private Either<Boolean, ResponseFormat> isRequirementNameRegexValid(ResponseFormatManager responseFormatManager,
+ String requirementName) {
+ if (!isValidRequirementName(requirementName)) {
+ LOGGER.error("Requirement name {} is invalid, Only alphanumeric chars, underscore and dot allowed",
+ requirementName);
+ ResponseFormat errorResponse = responseFormatManager
+ .getResponseFormat(ActionStatus.INVALID_REQUIREMENT_NAME, requirementName);
+ return Either.right(errorResponse);
+ }
+ return Either.left(Boolean.TRUE);
+ }
+
+ private boolean isValidRequirementName(String requirementName) {
+ return NAME_VALIDATION_REGEX_PATTERN.matcher(requirementName).matches();
+ }
+
+ protected ResponseFormatManager getResponseFormatManager() {
+ return ResponseFormatManager.getInstance();
+ }
+
+}
+
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java
index 909d4da994..0930daad04 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java
@@ -1522,5 +1522,32 @@ public class ComponentsUtils {
}
return getResponseFormat(exception.getActionStatus(), exception.getParams());
}
+ public ActionStatus convertFromStorageResponseForRelationshipType(
+ StorageOperationStatus storageResponse) {
+ ActionStatus responseEnum;
+ switch (storageResponse) {
+ case OK:
+ responseEnum = ActionStatus.OK;
+ break;
+ case CONNECTION_FAILURE:
+ case GRAPH_IS_LOCK:
+ responseEnum = ActionStatus.GENERAL_ERROR;
+ break;
+ case BAD_REQUEST:
+ responseEnum = ActionStatus.INVALID_CONTENT;
+ break;
+ case ENTITY_ALREADY_EXISTS:
+ responseEnum = ActionStatus.RELATIONSHIP_TYPE_ALREADY_EXIST;
+ break;
+ case SCHEMA_VIOLATION:
+ responseEnum = ActionStatus.RELATIONSHIP_TYPE_ALREADY_EXIST;
+ break;
+ default:
+ responseEnum = ActionStatus.GENERAL_ERROR;
+ break;
+ }
+ log.debug(CONVERT_STORAGE_RESPONSE_TO_ACTION_RESPONSE, storageResponse, responseEnum);
+ return responseEnum;
+ }
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java
index c321df1449..d27db55158 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java
@@ -148,6 +148,16 @@ public class BeGenericServlet extends BasicServlet {
return getClassFromWebAppContext(context, () -> InterfaceOperationBusinessLogic.class);
}
+ protected CapabilitiesBusinessLogic getCapabilitiesBL(ServletContext context) {
+ return getClassFromWebAppContext(context, () -> CapabilitiesBusinessLogic.class);
+ }
+
+ protected RelationshipTypeBusinessLogic getRelationshipTypeBL(ServletContext context) {
+ return getClassFromWebAppContext(context, () -> RelationshipTypeBusinessLogic.class);
+ }
+ protected RequirementBusinessLogic getRequirementBL(ServletContext context) {
+ return getClassFromWebAppContext(context, () -> RequirementBusinessLogic.class);
+ }
ComponentsCleanBusinessLogic getComponentCleanerBL(ServletContext context) {
return getClassFromWebAppContext(context, () -> ComponentsCleanBusinessLogic.class);
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/CapabilityServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/CapabilityServlet.java
new file mode 100644
index 0000000000..a1456bb65d
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/CapabilityServlet.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.servlets;
+
+import com.jcabi.aspects.Loggable;
+import fj.data.Either;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.openecomp.sdc.be.components.impl.CapabilitiesBusinessLogic;
+import org.openecomp.sdc.be.config.BeEcompErrorManager;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
+import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
+import org.openecomp.sdc.common.api.Constants;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.openecomp.sdc.exception.ResponseFormat;
+
+import javax.inject.Singleton;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.List;
+import java.util.Optional;
+
+@Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
+@Path("/v1/catalog")
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Api(value = "Capability Servlet", description = "Capability Servlet")
+@Singleton
+public class CapabilityServlet extends AbstractValidationsServlet {
+ private static final Logger LOGGER = Logger.getLogger(CapabilityServlet.class);
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/resources/{resourceId}/capabilities")
+ @ApiOperation(value = "Create Capabilities on resource", httpMethod = "POST",
+ notes = "Create Capabilities on resource", response = Response.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Capabilities"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 409, message = "Capability already exist")})
+ public Response createCapabilitiesOnResource(
+ @ApiParam(value = "Capability to create", required = true) String data,
+ @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+ return createOrUpdate(data, "resources" , resourceId,
+ request, userId, false, "createCapabilities");
+ }
+
+ @PUT
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/resources/{resourceId}/capabilities")
+ @ApiOperation(value = "Update Capabilities on resource", httpMethod = "PUT",
+ notes = "Update Capabilities on resource", response = CapabilityDefinition.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Update Capabilities"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+ public Response updateCapabilitiesOnResource(
+ @ApiParam(value = "Capabilities to update", required = true) String data,
+ @ApiParam(value = "Component Id") @PathParam("resourceId") String resourceId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+ return createOrUpdate(data, "resources", resourceId,
+ request, userId, true, "updateCapabilities");
+ }
+
+ @GET
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/resources/{resourceId}/capabilities/{capabilityId}")
+ @ApiOperation(value = "Get Capability from resource", httpMethod = "GET",
+ notes = "GET Capability from resource", response = CapabilityDefinition.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "GET Capability"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+ public Response getCapabilityOnResource(
+ @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
+ @ApiParam(value = "Capability Id") @PathParam("capabilityId") String capabilityId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+ return get(capabilityId, resourceId, request, userId);
+ }
+
+ @DELETE
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/resources/{resourceId}/capabilities/{capabilityId}")
+ @ApiOperation(value = "Delete capability from resource", httpMethod = "DELETE",
+ notes = "Delete capability from resource", response = CapabilityDefinition.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete capability"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+ public Response deleteCapabilityOnResource(
+ @ApiParam(value = "capability Id") @PathParam("capabilityId") String capabilityId,
+ @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+ return delete(capabilityId, resourceId, request, userId);
+ }
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/services/{serviceId}/capabilities")
+ @ApiOperation(value = "Create Capabilities on service", httpMethod = "POST",
+ notes = "Create Capabilities on service", response = Response.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Capabilities"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 409, message = "Capability already exist")})
+ public Response createCapabilitiesOnService(
+ @ApiParam(value = "Capability to create", required = true) String data,
+ @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+ return createOrUpdate(data, "services" , serviceId,
+ request, userId, false, "createCapabilities");
+ }
+
+ @PUT
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/services/{serviceId}/capabilities")
+ @ApiOperation(value = "Update Capabilities on service", httpMethod = "PUT",
+ notes = "Update Capabilities on service", response = CapabilityDefinition.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Update Capabilities"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+ public Response updateCapabilitiesOnService(
+ @ApiParam(value = "Capabilities to update", required = true) String data,
+ @ApiParam(value = "Component Id") @PathParam("serviceId") String serviceId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+ return createOrUpdate(data, "services", serviceId,
+ request, userId, true, "updateCapabilities");
+ }
+
+ @GET
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/services/{serviceId}/capabilities/{capabilityId}")
+ @ApiOperation(value = "Get Capability from service", httpMethod = "GET",
+ notes = "GET Capability from service", response = CapabilityDefinition.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "GET Capability"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+ public Response getCapabilityOnService(
+ @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
+ @ApiParam(value = "Capability Id") @PathParam("capabilityId") String capabilityId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+ return get(capabilityId, serviceId, request, userId);
+ }
+
+ @DELETE
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/services/{serviceId}/capabilities/{capabilityId}")
+ @ApiOperation(value = "Delete capability from service", httpMethod = "DELETE",
+ notes = "Delete capability from service", response = CapabilityDefinition.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete capability"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+ public Response deleteCapabilityOnService(
+ @ApiParam(value = "capability Id") @PathParam("capabilityId") String capabilityId,
+ @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+ return delete(capabilityId, serviceId, request, userId);
+ }
+
+ private Response createOrUpdate (String data, String componentType, String componentId,
+ HttpServletRequest request,
+ String userId,
+ boolean isUpdate,
+ String errorContext) {
+ ServletContext context = request.getSession().getServletContext();
+ String url = request.getMethod() + " " + request.getRequestURI();
+
+ User modifier = new User();
+ modifier.setUserId(userId);
+ LOGGER.debug("Start create or update request of {} with modifier id {}", url, userId);
+ try {
+ String componentIdLower = componentId.toLowerCase();
+ CapabilitiesBusinessLogic businessLogic = getCapabilitiesBL(context);
+
+ Either<List<CapabilityDefinition>, ResponseFormat> mappedCapabilitiesDataEither
+ = getMappedCapabilitiesData(data, modifier, ComponentTypeEnum.findByParamName(componentType));
+ if(mappedCapabilitiesDataEither.isRight()) {
+ LOGGER.error("Failed to create or update capabilities");
+ buildErrorResponse(mappedCapabilitiesDataEither.right().value());
+ }
+ List<CapabilityDefinition> mappedCapabilitiesData = mappedCapabilitiesDataEither.left().value();
+ Either<List<CapabilityDefinition>, ResponseFormat> actionResponse;
+ if(isUpdate) {
+ actionResponse = businessLogic.updateCapabilities(componentIdLower,
+ mappedCapabilitiesData, modifier, errorContext, true);
+ } else {
+ actionResponse = businessLogic.createCapabilities(componentIdLower,
+ mappedCapabilitiesData, modifier, errorContext, true);
+ }
+ if (actionResponse.isRight()) {
+ LOGGER.error("Failed to create or update capabilities");
+ return buildErrorResponse(actionResponse.right().value());
+ }
+ return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
+ actionResponse.left().value());
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Capabilities create or update");
+ LOGGER.error("Failed to create or update capabilities with an error", e);
+ return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+ }
+ }
+
+ private Response get (String capabilityIdToGet, String componentId,
+ HttpServletRequest request, String userId){
+ ServletContext context = request.getSession().getServletContext();
+ String url = request.getMethod() + " " + request.getRequestURI();
+
+ User modifier = new User();
+ modifier.setUserId(userId);
+ LOGGER.debug("Start get request of {} with modifier id {}", url, userId);
+
+ try {
+ String componentIdLower = componentId.toLowerCase();
+ CapabilitiesBusinessLogic businessLogic = getCapabilitiesBL(context);
+
+ Either<CapabilityDefinition, ResponseFormat> actionResponse = businessLogic
+ .getCapability(componentIdLower, capabilityIdToGet, modifier, true);
+ if (actionResponse.isRight()) {
+ LOGGER.error("failed to get capability");
+ return buildErrorResponse(actionResponse.right().value());
+ }
+ Object result = RepresentationUtils.toFilteredRepresentation(actionResponse.left().value());
+ return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get capability");
+ LOGGER.error("get capabilities failed with exception", e);
+ return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+ }
+ }
+
+ private Response delete (String capabilityId, String componentId, HttpServletRequest
+ request, String userId){
+
+ ServletContext context = request.getSession().getServletContext();
+ String url = request.getMethod() + " " + request.getRequestURI();
+
+ User modifier = new User();
+ modifier.setUserId(userId);
+ LOGGER.debug("Start delete request of {} with modifier id {}", url, userId);
+
+ try {
+ String componentIdLower = componentId.toLowerCase();
+ CapabilitiesBusinessLogic businessLogic = getCapabilitiesBL(context);
+
+ Either<CapabilityDefinition, ResponseFormat> actionResponse = businessLogic
+ .deleteCapability(componentIdLower, capabilityId, modifier, true);
+ if (actionResponse.isRight()) {
+ LOGGER.error("failed to delete capability");
+ return buildErrorResponse(actionResponse.right().value());
+ }
+ Object result = RepresentationUtils.toRepresentation(actionResponse.left().value());
+ return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete capability");
+ LOGGER.error("Delete capability failed with an error", e);
+ return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+ }
+ }
+
+ private Either<List<CapabilityDefinition>, ResponseFormat> getMappedCapabilitiesData(String inputJson, User user,
+ ComponentTypeEnum componentTypeEnum){
+ Either<UiComponentDataTransfer, ResponseFormat> mappedData = getComponentsUtils()
+ .convertJsonToObjectUsingObjectMapper(inputJson, user, UiComponentDataTransfer.class,
+ AuditingActionEnum.CREATE_RESOURCE, componentTypeEnum);
+ Optional<List<CapabilityDefinition>> capabilityDefinitionList =
+ mappedData.left().value().getCapabilities().values().stream().findFirst();
+ return capabilityDefinitionList.<Either<List<CapabilityDefinition>, ResponseFormat>>
+ map(Either::left).orElseGet(() -> Either.right(getComponentsUtils()
+ .getResponseFormat(ActionStatus.GENERAL_ERROR)));
+ }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementServlet.java
new file mode 100644
index 0000000000..51f6783f0d
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementServlet.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.servlets;
+
+import com.jcabi.aspects.Loggable;
+import fj.data.Either;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.openecomp.sdc.be.components.impl.RequirementBusinessLogic;
+import org.openecomp.sdc.be.config.BeEcompErrorManager;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.model.RequirementDefinition;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
+import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
+import org.openecomp.sdc.common.api.Constants;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.openecomp.sdc.exception.ResponseFormat;
+
+import javax.inject.Singleton;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.List;
+import java.util.Optional;
+
+@Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
+@Path("/v1/catalog")
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Api(value = "Requirement Servlet", description = "Requirement Servlet")
+@Singleton
+public class RequirementServlet extends AbstractValidationsServlet {
+ private static final Logger LOGGER = Logger.getLogger(RequirementServlet.class);
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/resources/{resourceId}/requirements")
+ @ApiOperation(value = "Create requirements on resource", httpMethod = "POST",
+ notes = "Create requirements on resource", response = Response.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Create requirements"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 409, message = "requirement already exist")})
+ public Response createRequirementsOnResource(
+ @ApiParam(value = "Requirement to create", required = true) String data,
+ @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+ return createOrUpdate(data, "resources" , resourceId, request,
+ userId, false, "createRequirements");
+ }
+
+
+ @PUT
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/resources/{resourceId}/requirements")
+ @ApiOperation(value = "Update Requirements on resource", httpMethod = "PUT",
+ notes = "Update Requirements on resource", response = RequirementDefinition.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Update Requirements"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+ public Response updateRequirementsOnResource(
+ @ApiParam(value = "Requirements to update", required = true) String data,
+ @ApiParam(value = "Component Id") @PathParam("resourceId") String resourceId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+ return createOrUpdate(data, "resources", resourceId, request,
+ userId, true, "updateRequirements");
+ }
+
+ @GET
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/resources/{resourceId}/requirements/{requirementId}")
+ @ApiOperation(value = "Get Requirement from resource", httpMethod = "GET",
+ notes = "GET Requirement from resource", response = RequirementDefinition.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "GET requirement"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+ public Response getRequirementsFromResource(
+ @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
+ @ApiParam(value = "Requirement Id") @PathParam("requirementId") String requirementId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+ return get(requirementId, resourceId, request, userId);
+ }
+
+ @DELETE
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/resources/{resourceId}/requirements/{requirementId}")
+ @ApiOperation(value = "Delete requirements from resource", httpMethod = "DELETE",
+ notes = "Delete requirements from resource", response = RequirementDefinition.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete requirement"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+ public Response deleteRequirementsFromResource(
+ @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
+ @ApiParam(value = "requirement Id") @PathParam("requirementId") String requirementId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+ return delete(requirementId, resourceId, request, userId);
+ }
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/services/{serviceId}/requirements")
+ @ApiOperation(value = "Create requirements on service", httpMethod = "POST",
+ notes = "Create requirements on service", response = Response.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Requirements"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 409, message = "Requirement already exist")})
+ public Response createRequirementsOnService(
+ @ApiParam(value = "Requirements to create", required = true) String data,
+ @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+ return createOrUpdate(data, "services" , serviceId, request, userId,
+ false , "createRequirements");
+ }
+
+
+ @PUT
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/services/{serviceId}/requirements")
+ @ApiOperation(value = "Update requirements on service", httpMethod = "PUT",
+ notes = "Update requirements on service", response = RequirementDefinition.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Update requirements"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+ public Response updateRequirementsOnService(
+ @ApiParam(value = "Requirements to update", required = true) String data,
+ @ApiParam(value = "Component Id") @PathParam("serviceId") String serviceId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+ return createOrUpdate(data, "services", serviceId, request, userId,
+ true, "updateRequirements");
+ }
+
+ @GET
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/services/{serviceId}/requirements/{requirementId}")
+ @ApiOperation(value = "Get requirement from service", httpMethod = "GET",
+ notes = "GET requirement from service", response = RequirementDefinition.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "GET Requirements"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+ public Response getRequirementsOnService(
+ @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
+ @ApiParam(value = "Requirement Id") @PathParam("requirementId") String requirementId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+ return get(requirementId, serviceId, request, userId);
+ }
+
+
+ @DELETE
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/services/{serviceId}/requirements/{requirementId}")
+ @ApiOperation(value = "Delete requirement from service", httpMethod = "DELETE",
+ notes = "Delete requirement from service", response = RequirementDefinition.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete Requirements"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+ public Response deleteRequirementsOnService(
+ @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
+ @ApiParam(value = "Requirement Id") @PathParam("requirementId") String requirementId,
+ @Context final HttpServletRequest request,
+ @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+ return delete(requirementId, serviceId, request, userId);
+ }
+
+
+ private Response createOrUpdate (String data, String componentType, String componentId,
+ HttpServletRequest request, String userId,
+ boolean isUpdate, String errorContext) {
+ ServletContext context = request.getSession().getServletContext();
+ String url = request.getMethod() + " " + request.getRequestURI();
+
+ User modifier = new User();
+ modifier.setUserId(userId);
+ LOGGER.debug("Start create or update request of {} with modifier id {}", url, userId);
+
+ try {
+ String componentIdLower = componentId.toLowerCase();
+ RequirementBusinessLogic businessLogic = getRequirementBL(context);
+
+ Either<List<RequirementDefinition>, ResponseFormat> mappedRequirementDataEither =
+ getMappedRequirementData(data, modifier, ComponentTypeEnum.findByParamName(componentType));
+ if(mappedRequirementDataEither.isRight()) {
+ LOGGER.error("Failed to create or update requirements");
+ return buildErrorResponse(mappedRequirementDataEither.right().value());
+ }
+ List<RequirementDefinition> mappedRequirementData = mappedRequirementDataEither.left().value();
+ Either<List<RequirementDefinition>, ResponseFormat> actionResponse;
+ if(isUpdate) {
+ actionResponse = businessLogic.updateRequirements(componentIdLower, mappedRequirementData, modifier,
+ errorContext, true);
+ } else {
+ actionResponse = businessLogic.createRequirements(componentIdLower, mappedRequirementData, modifier,
+ errorContext, true);
+ }
+
+ if (actionResponse.isRight()) {
+ LOGGER.error("Failed to create or update requirements");
+ return buildErrorResponse(actionResponse.right().value());
+ }
+
+ return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
+ actionResponse.left().value());
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("requirements create or update");
+ LOGGER.error("Failed to create or update requirements with an error", e);
+ return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+ }
+ }
+
+ private Response get (String requirementIdToGet, String componentId,
+ HttpServletRequest request, String userId){
+ ServletContext context = request.getSession().getServletContext();
+ String url = request.getMethod() + " " + request.getRequestURI();
+
+ User modifier = new User();
+ modifier.setUserId(userId);
+ LOGGER.debug("Start get request of {} with modifier id {}", url, userId);
+
+ try {
+ String componentIdLower = componentId.toLowerCase();
+ RequirementBusinessLogic businessLogic = getRequirementBL(context);
+
+ Either<RequirementDefinition, ResponseFormat> actionResponse = businessLogic
+ .getRequirement(componentIdLower, requirementIdToGet, modifier, true);
+ if (actionResponse.isRight()) {
+ LOGGER.error("failed to get requirements");
+ return buildErrorResponse(actionResponse.right().value());
+ }
+ Object result = RepresentationUtils.toFilteredRepresentation(actionResponse.left().value());
+ return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get requirements");
+ LOGGER.error("get requirements failed with exception", e);
+ return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+ }
+ }
+
+ private Response delete (String requirementId, String componentId, HttpServletRequest
+ request, String userId){
+
+ ServletContext context = request.getSession().getServletContext();
+ String url = request.getMethod() + " " + request.getRequestURI();
+
+ User modifier = new User();
+ modifier.setUserId(userId);
+ LOGGER.debug("Start delete request of {} with modifier id {}", url, userId);
+
+ try {
+ String componentIdLower = componentId.toLowerCase();
+ RequirementBusinessLogic businessLogic = getRequirementBL(context);
+
+ Either<RequirementDefinition, ResponseFormat> actionResponse = businessLogic
+ .deleteRequirement(componentIdLower, requirementId, modifier, true);
+ if (actionResponse.isRight()) {
+ LOGGER.error("failed to delete requirements");
+ return buildErrorResponse(actionResponse.right().value());
+ }
+ Object result = RepresentationUtils.toRepresentation(actionResponse.left().value());
+ return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete requirements");
+ LOGGER.error("Delete requirements failed with an error", e);
+ return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+ }
+ }
+
+ private Either<List<RequirementDefinition>, ResponseFormat> getMappedRequirementData(String inputJson, User user,
+ ComponentTypeEnum componentTypeEnum){
+ Either<UiComponentDataTransfer, ResponseFormat> mappedData = getComponentsUtils()
+ .convertJsonToObjectUsingObjectMapper(inputJson, user, UiComponentDataTransfer.class,
+ AuditingActionEnum.CREATE_RESOURCE, componentTypeEnum);
+ Optional<List<RequirementDefinition>> requirementDefinitionList = mappedData.left().value()
+ .getRequirements().values().stream().findFirst();
+ return requirementDefinitionList.<Either<List<RequirementDefinition>, ResponseFormat>>
+ map(Either::left).orElseGet(() -> Either.right(getComponentsUtils()
+ .getResponseFormat(ActionStatus.GENERAL_ERROR)));
+ }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java
index 00b04a4ffc..459629ff26 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java
@@ -26,28 +26,44 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
+import org.apache.commons.collections4.ListUtils;
+import org.openecomp.sdc.be.components.impl.CapabilitiesBusinessLogic;
+import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic;
import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic;
import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic;
+import org.openecomp.sdc.be.components.impl.RelationshipTypeBusinessLogic;
import org.openecomp.sdc.be.config.BeEcompErrorManager;
import org.openecomp.sdc.be.dao.api.ActionStatus;
-import org.openecomp.sdc.be.impl.WebAppContextWrapper;
+import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum;
+import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
+import org.openecomp.sdc.be.model.Component;
import org.openecomp.sdc.be.model.DataTypeDefinition;
import org.openecomp.sdc.be.model.InterfaceDefinition;
+import org.openecomp.sdc.be.model.RelationshipTypeDefinition;
import org.openecomp.sdc.be.model.User;
import org.openecomp.sdc.common.api.Constants;
import org.openecomp.sdc.common.datastructure.Wrapper;
import org.openecomp.sdc.common.log.wrappers.Logger;
import org.openecomp.sdc.exception.ResponseFormat;
-import org.springframework.web.context.WebApplicationContext;
import javax.inject.Singleton;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.*;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
+
@Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
@Path("/v1/catalog")
@@ -56,6 +72,7 @@ import java.util.Map;
public class TypesFetchServlet extends AbstractValidationsServlet {
private static final Logger log = Logger.getLogger(TypesFetchServlet.class);
+ private static final String FAILED_TO_GET_ALL_NON_ABSTRACT = "failed to get all non abstract {}";
@GET
@Path("dataTypes")
@@ -154,4 +171,188 @@ public class TypesFetchServlet extends AbstractValidationsServlet {
return buildErrorResponse(responseFormat);
}
}
+ @GET
+ @Path("capabilityTypes")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Get capability types", httpMethod = "GET", notes = "Returns capability types", response =
+ Response.class)
+ @ApiResponses(value = {@ApiResponse(code = 200, message = "capabilityTypes"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 404, message = "Capability types not found")})
+ public Response getAllCapabilityTypesServlet(@Context final HttpServletRequest request, @HeaderParam(value =
+ Constants.USER_ID_HEADER) String userId) {
+
+ Wrapper<Response> responseWrapper = new Wrapper<>();
+ Wrapper<User> userWrapper = new Wrapper<>();
+ ServletContext context = request.getSession().getServletContext();
+
+ try {
+ init();
+ validateUserExist(responseWrapper, userWrapper, userId);
+
+ if (responseWrapper.isEmpty()) {
+ String url = request.getMethod() + " " + request.getRequestURI();
+ log.debug("Start handle request of {} | modifier id is {}", url, userId);
+
+ CapabilitiesBusinessLogic businessLogic = getCapabilitiesBL(context);
+ Either<Map<String, CapabilityTypeDefinition>, ResponseFormat> allDataTypes =
+ businessLogic.getAllCapabilityTypes();
+
+ if (allDataTypes.isRight()) {
+ log.info("Failed to get all capability types. Reason - {}", allDataTypes.right().value());
+ Response errorResponse = buildErrorResponse(allDataTypes.right().value());
+ responseWrapper.setInnerElement(errorResponse);
+
+ } else {
+
+ Map<String, CapabilityTypeDefinition> dataTypes = allDataTypes.left().value();
+ String dataTypeJson = gson.toJson(dataTypes);
+ Response okResponse =
+ buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), dataTypeJson);
+ responseWrapper.setInnerElement(okResponse);
+
+ }
+ }
+
+ return responseWrapper.getInnerElement();
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Capability Types");
+ log.debug("get all capability types failed with exception", e);
+ ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
+ return buildErrorResponse(responseFormat);
+ }
+ }
+
+ @GET
+ @Path("relationshipTypes")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Get relationship types", httpMethod = "GET", notes = "Returns relationship types", response =
+ Response.class)
+ @ApiResponses(value = {@ApiResponse(code = 200, message = "relationshipTypes"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 404, message = "Relationship types not found")})
+ public Response getAllRelationshipTypesServlet(@Context final HttpServletRequest request, @HeaderParam(value =
+ Constants.USER_ID_HEADER) String userId) {
+
+ Wrapper<Response> responseWrapper = new Wrapper<>();
+ Wrapper<User> userWrapper = new Wrapper<>();
+ ServletContext context = request.getSession().getServletContext();
+
+ try {
+ init();
+ validateUserExist(responseWrapper, userWrapper, userId);
+
+ if (responseWrapper.isEmpty()) {
+ String url = request.getMethod() + " " + request.getRequestURI();
+ log.debug("Start handle request of {} | modifier id is {}", url, userId);
+
+ RelationshipTypeBusinessLogic businessLogic = getRelationshipTypeBL(context);
+ Either<Map<String, RelationshipTypeDefinition>, ResponseFormat> allDataTypes =
+ businessLogic.getAllRelationshipTypes();
+
+ if (allDataTypes.isRight()) {
+ log.info("Failed to get all relationship types. Reason - {}", allDataTypes.right().value());
+ Response errorResponse = buildErrorResponse(allDataTypes.right().value());
+ responseWrapper.setInnerElement(errorResponse);
+
+ } else {
+
+ Map<String, RelationshipTypeDefinition> dataTypes = allDataTypes.left().value();
+ String dataTypeJson = gson.toJson(dataTypes);
+ Response okResponse =
+ buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), dataTypeJson);
+ responseWrapper.setInnerElement(okResponse);
+
+ }
+ }
+
+ return responseWrapper.getInnerElement();
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Relationship Types");
+ log.debug("get all relationship types failed with exception", e);
+ ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
+ return buildErrorResponse(responseFormat);
+ }
+ }
+
+ @GET
+ @Path("nodeTypes")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Get node types", httpMethod = "GET", notes = "Returns node types", response = Response.class)
+ @ApiResponses(value = {@ApiResponse(code = 200, message = "nodeTypes"), @ApiResponse(code = 403, message =
+ "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 404, message = "Node types not found")})
+ public Response getAllNodeTypesServlet(@Context final HttpServletRequest request, @HeaderParam(value =
+ Constants.USER_ID_HEADER) String userId) {
+
+ Wrapper<Response> responseWrapper = new Wrapper<>();
+ Wrapper<User> userWrapper = new Wrapper<>();
+ ServletContext context = request.getSession().getServletContext();
+ Either<Map<String, Component>, Response> response;
+ Map<String, Component> componentMap;
+
+ try {
+ init();
+ validateUserExist(responseWrapper, userWrapper, userId);
+
+ if (responseWrapper.isEmpty()) {
+ String url = request.getMethod() + " " + request.getRequestURI();
+ log.debug("Start handle request of {} | modifier id is {}", url, userId);
+
+ ComponentBusinessLogic resourceBL = getComponentBL(ComponentTypeEnum.RESOURCE, context);
+ response = getComponent(resourceBL, true, userId);
+ if (response.isRight()) {
+ return response.right().value();
+ }
+ componentMap = new HashMap<>(response.left().value());
+
+ response = getComponent(resourceBL, false, userId);
+ if (response.isRight()) {
+ return response.right().value();
+ }
+ componentMap.putAll(response.left().value());
+
+ String nodeTypesJson = gson.toJson(componentMap);
+ Response okResponse =
+ buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), nodeTypesJson);
+ responseWrapper.setInnerElement(okResponse);
+ }
+
+ return responseWrapper.getInnerElement();
+ } catch (Exception e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Node Types");
+ log.debug("get all node types failed with exception", e);
+ ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
+ return buildErrorResponse(responseFormat);
+ }
+ }
+
+ private Either<Map<String, Component>, Response> getComponent(ComponentBusinessLogic resourceBL, boolean isAbstract,
+ String userId) {
+ Either<List<Component>, ResponseFormat> actionResponse;
+ List<Component> componentList;
+
+ actionResponse =
+ resourceBL.getLatestVersionNotAbstractComponentsMetadata(isAbstract, HighestFilterEnum.HIGHEST_ONLY
+ , ComponentTypeEnum.RESOURCE, null, userId);
+ if (actionResponse.isRight()) {
+ log.debug(FAILED_TO_GET_ALL_NON_ABSTRACT, ComponentTypeEnum.RESOURCE.getValue());
+ return Either.right(buildErrorResponse(actionResponse.right().value()));
+ }
+
+ componentList = actionResponse.left().value();
+
+ return Either.left(ListUtils.emptyIfNull(componentList).stream()
+ .filter(component -> ((ResourceMetadataDataDefinition) component
+ .getComponentMetadataDefinition().getMetadataDataDefinition()).getToscaResourceName() != null)
+ .collect(Collectors.toMap(
+ component -> ((ResourceMetadataDataDefinition) component
+ .getComponentMetadataDefinition().getMetadataDataDefinition()).getToscaResourceName(),
+ component -> component, (component1, component2) -> component1)));
+ }
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java
index a09e34fa9a..8ecda2ce61 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java
@@ -34,6 +34,7 @@ import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
import org.openecomp.sdc.be.model.DataTypeDefinition;
import org.openecomp.sdc.be.model.GroupTypeDefinition;
import org.openecomp.sdc.be.model.PolicyTypeDefinition;
+import org.openecomp.sdc.be.model.RelationshipTypeDefinition;
import org.openecomp.sdc.be.model.User;
import org.openecomp.sdc.be.model.normatives.ToscaTypeMetadata;
import org.openecomp.sdc.common.api.Constants;
@@ -72,15 +73,18 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
private final DataTypeImportManager dataTypeImportManager;
private final GroupTypeImportManager groupTypeImportManager;
private final PolicyTypeImportManager policyTypeImportManager;
+ private final RelationshipTypeImportManager relationshipTypeImportManager;
public TypesUploadServlet(CapabilityTypeImportManager capabilityTypeImportManager, InterfaceLifecycleTypeImportManager interfaceLifecycleTypeImportManager, CategoriesImportManager categoriesImportManager, DataTypeImportManager dataTypeImportManager,
- GroupTypeImportManager groupTypeImportManager, PolicyTypeImportManager policyTypeImportManager) {
+ GroupTypeImportManager groupTypeImportManager, PolicyTypeImportManager policyTypeImportManager,
+ RelationshipTypeImportManager relationshipTypeImportManager) {
this.capabilityTypeImportManager = capabilityTypeImportManager;
this.interfaceLifecycleTypeImportManager = interfaceLifecycleTypeImportManager;
this.categoriesImportManager = categoriesImportManager;
this.dataTypeImportManager = dataTypeImportManager;
this.groupTypeImportManager = groupTypeImportManager;
this.policyTypeImportManager = policyTypeImportManager;
+ this.relationshipTypeImportManager = relationshipTypeImportManager;
}
@POST
@@ -94,6 +98,21 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
}
@POST
+ @Path("/relationship")
+ @ApiOperation(value = "Create Relationship Type from yaml", httpMethod = "POST",
+ notes = "Returns created Relationship Type", response = Response.class)
+ @ApiResponses(value = {@ApiResponse(code = 201, message = "Relationship Type created"),
+ @ApiResponse(code = 403, message = "Restricted operation"),
+ @ApiResponse(code = 400, message = "Invalid content / Missing content"),
+ @ApiResponse(code = 409, message = "Relationship Type already exist")})
+ public Response uploadRelationshipType(@ApiParam("FileInputStream") @FormDataParam("relationshipTypeZip") File file,
+ @Context final HttpServletRequest request,
+ @HeaderParam("USER_ID") String creator) {
+ return uploadElementTypeServletLogic(this::createRelationshipTypes, file, request, creator,
+ NodeTypeEnum.RelationshipType.getName());
+ }
+
+ @POST
@Path("/interfaceLifecycle")
@ApiOperation(value = "Create Interface Lyfecycle Type from yaml", httpMethod = "POST", notes = "Returns created Interface Lifecycle Type", response = Response.class)
@ApiResponses(value = { @ApiResponse(code = 201, message = "Interface Lifecycle Type created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"),
@@ -299,6 +318,13 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
}
}
}
-
+ // relationship types
+ private void createRelationshipTypes(Wrapper<Response> responseWrapper, String relationshipTypesYml) {
+ final Supplier<Either<List<ImmutablePair<RelationshipTypeDefinition, Boolean>>, ResponseFormat>>
+ generateElementTypeFromYml =
+ () -> relationshipTypeImportManager.createRelationshipTypes(relationshipTypesYml);
+ buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml,
+ ActionStatus.RELATIONSHIP_TYPE_ALREADY_EXIST, NodeTypeEnum.RelationshipType.name());
+ }
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java
index 04119fed7b..bd797c970b 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java
@@ -258,22 +258,22 @@ public class CapabilityRequirementConverter {
private Either<Map<String, String[]>, ToscaError> buildAddSubstitutionMappingsCapabilities(Map<String, Component> componentsCache, Component component, Map<String, List<CapabilityDefinition>> capabilities) {
- Map<String, String[]> toscaRequirements = new HashMap<>();
+ Map<String, String[]> toscaCapabilities = new HashMap<>();
Either<Map<String, String[]>, ToscaError> result = null;
for (Map.Entry<String, List<CapabilityDefinition>> entry : capabilities.entrySet()) {
Optional<CapabilityDefinition> failedToAddRequirement = entry.getValue()
.stream()
- .filter(c->!addEntry(componentsCache, toscaRequirements, component, new SubstitutionEntry(c.getName(), c.getParentName(), ""), c.getPreviousName(), c.getOwnerId(), c.getPath()))
+ .filter(c->!addEntry(componentsCache, toscaCapabilities, component, new SubstitutionEntry(c.getName(), c.getParentName(), ""), c.getPreviousName(), c.getOwnerId(), c.getPath()))
.findAny();
if(failedToAddRequirement.isPresent()){
- logger.debug("Failed to convert capalility {} for substitution mappings section of a tosca template of the component {}. ",
+ logger.debug("Failed to convert capability {} for substitution mappings section of a tosca template of the component {}. ",
failedToAddRequirement.get().getName(), component.getName());
result = Either.right(ToscaError.NODE_TYPE_CAPABILITY_ERROR);
}
- logger.debug("Finish convert capalilities for the component {}. ", component.getName());
+ logger.debug("Finish convert capabilities for the component {}. ", component.getName());
}
if(result == null){
- result = Either.left(toscaRequirements);
+ result = Either.left(toscaCapabilities);
}
return result;
}
@@ -284,7 +284,7 @@ public class CapabilityRequirementConverter {
return false;
}
logger.debug("The requirement/capability {} belongs to the component {} ", entry.getFullName(), component.getUniqueId());
- if (entry.getSourceName() != null) {
+ if (StringUtils.isNotEmpty(entry.getSourceName())) {
addEntry(capReqMap, component, path, entry);
}
logger.debug("Finish convert the requirement/capability {} for the component {}. ", entry.getFullName(), component.getName());
@@ -318,14 +318,15 @@ public class CapabilityRequirementConverter {
}
}
- Optional<ComponentInstance> ci = component.getComponentInstances().stream().filter(c->c.getUniqueId().equals(Iterables.getLast(path))).findFirst();
+ Optional<ComponentInstance> ci =
+ component.safeGetComponentInstances().stream().filter(c->c.getUniqueId().equals(Iterables.getLast(path))).findFirst();
if(!ci.isPresent()){
logger.debug("Failed to find ci in the path is {} component {}", path, component.getUniqueId());
Collections.reverse(path);
logger.debug("try to reverse path {} component {}", path, component.getUniqueId());
- ci = component.getComponentInstances().stream().filter(c->c.getUniqueId().equals(Iterables.getLast(path))).findFirst();
+ ci = component.safeGetComponentInstances().stream().filter(c->c.getUniqueId().equals(Iterables.getLast(path))).findFirst();
}
if(ci.isPresent()){
prefix = buildCapReqNamePrefix(ci.get().getNormalizedName());
@@ -352,10 +353,10 @@ public class CapabilityRequirementConverter {
private void addEntry(Map<String, String[]> toscaRequirements, Component component, List<String> capPath, SubstitutionEntry entry) {
Optional<ComponentInstance> findFirst = component.safeGetComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(Iterables.getLast(capPath))).findFirst();
- if (findFirst.isPresent()) {
- entry.setOwner(findFirst.get().getNormalizedName());
+ findFirst.ifPresent(componentInstance -> entry.setOwner(componentInstance.getName()));
+ if (StringUtils.isNotEmpty(entry.getOwner()) && StringUtils.isNotEmpty(entry.getSourceName())) {
+ toscaRequirements.put(entry.getFullName(), new String[] { entry.getOwner(), entry.getSourceName() });
}
- toscaRequirements.put(entry.getFullName(), new String[] { entry.getOwner(), entry.getSourceName() });
}
public Either<String, Boolean> buildSubstitutedName(Map<String, Component> componentsCache, String name, String previousName, List<String> path, String ownerId, ComponentInstance instance) {
@@ -469,31 +470,9 @@ public class CapabilityRequirementConverter {
return buildCapReqNamePerOwnerByPath(componentsCache, component, c.getName(), c.getPreviousName(), c.getPath());
}
- private void convertProxyCapability(Map<String, ToscaCapability> toscaCapabilities, CapabilityDefinition c, Map<String, DataTypeDefinition> dataTypes, String capabilityName) {
- ToscaCapability toscaCapability = new ToscaCapability();
- toscaCapability.setDescription(c.getDescription());
- toscaCapability.setType(c.getType());
-
- List<Object> occurrences = new ArrayList<>();
- occurrences.add(Integer.valueOf(c.getMinOccurrences()));
- if (c.getMaxOccurrences().equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
- occurrences.add(c.getMaxOccurrences());
- } else {
- occurrences.add(Integer.valueOf(c.getMaxOccurrences()));
- }
- toscaCapability.setOccurrences(occurrences);
-
- toscaCapability.setValid_source_types(c.getValidSourceTypes());
- List<ComponentInstanceProperty> properties = c.getProperties();
- if (isNotEmpty(properties)) {
- Map<String, ToscaProperty> toscaProperties = new HashMap<>();
- for (PropertyDefinition property : properties) {
- ToscaProperty toscaProperty = PropertyConvertor.getInstance().convertProperty(dataTypes, property, PropertyConvertor.PropertyType.CAPABILITY);
- toscaProperties.put(property.getName(), toscaProperty);
- }
- toscaCapability.setProperties(toscaProperties);
- }
- toscaCapabilities.put(capabilityName, toscaCapability);
+ private void convertProxyCapability(Map<String, ToscaCapability> toscaCapabilities, CapabilityDefinition c,
+ Map<String, DataTypeDefinition> dataTypes, String capabilityName) {
+ createToscaCapability(toscaCapabilities, c, dataTypes, capabilityName);
}
private void convertCapability(Map<String, Component> componentsCache, Component component, Map<String, ToscaCapability> toscaCapabilities, boolean isNodeType, CapabilityDefinition c, Map<String, DataTypeDefinition> dataTypes , String capabilityName) {
@@ -502,6 +481,11 @@ public class CapabilityRequirementConverter {
name = buildCapNamePerOwnerByPath(componentsCache, c, component);
}
logger.debug("The capability {} belongs to resource {} ", name, component.getUniqueId());
+ createToscaCapability(toscaCapabilities, c, dataTypes, name);
+ }
+
+ private void createToscaCapability(Map<String, ToscaCapability> toscaCapabilities, CapabilityDefinition c,
+ Map<String, DataTypeDefinition> dataTypes, String name) {
ToscaCapability toscaCapability = new ToscaCapability();
toscaCapability.setDescription(c.getDescription());
toscaCapability.setType(c.getType());
@@ -529,6 +513,9 @@ public class CapabilityRequirementConverter {
}
private String buildCapReqNamePerOwnerByPath(Map<String, Component> componentsCache, Component component, String name, String previousName, List<String> path) {
+ if (CollectionUtils.isEmpty(path)) {
+ return name;
+ }
String ownerId = path.get(path.size() - 1);
String prefix;
if(CollectionUtils.isNotEmpty(component.getGroups())) {
@@ -541,14 +528,14 @@ public class CapabilityRequirementConverter {
return name;
}
}
- Optional<ComponentInstance> ci = component.getComponentInstances().stream().filter(c->c.getUniqueId().equals(Iterables.getLast(path))).findFirst();
+ Optional<ComponentInstance> ci = component.safeGetComponentInstances().stream().filter(c->c.getUniqueId().equals(Iterables.getLast(path))).findFirst();
if(!ci.isPresent()){
logger.debug("Failed to find ci in the path is {} component {}", path, component.getUniqueId());
Collections.reverse(path);
logger.debug("try to reverse path {} component {}", path, component.getUniqueId());
- ci = component.getComponentInstances().stream().filter(c->c.getUniqueId().equals(Iterables.getLast(path))).findFirst();
+ ci = component.safeGetComponentInstances().stream().filter(c->c.getUniqueId().equals(Iterables.getLast(path))).findFirst();
}
if(ci.isPresent()){
prefix = buildCapReqNamePrefix(ci.get().getNormalizedName());