aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--asdctool/src/main/resources/config/error-configuration.yaml113
-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
-rw-r--r--catalog-be/src/main/resources/import/tosca/relationship-types/relationshipTypes.yml59
-rw-r--r--catalog-be/src/main/resources/scripts/import/tosca/importNormativeAll.py4
-rw-r--r--catalog-be/src/main/resources/scripts/import/tosca/importNormativeRelationships.py83
-rw-r--r--catalog-be/src/main/resources/scripts/import/tosca/importONAPNormativeAll.py8
-rw-r--r--catalog-be/src/main/resources/scripts/import/tosca/upgradeNormative.py4
-rw-r--r--catalog-be/src/main/resources/scripts/import/tosca/upgradeONAPNormative.py4
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/CapabilitiesBusinessLogicTest.java443
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/RequirementBusinessLogicTest.java412
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/CapabilitiesValidationTest.java159
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/RequirementValidationTest.java156
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/servlets/TypesUploadServletTest.java2
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java15
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/GraphElementFactory.java1
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/VertexTypeEnum.java2
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphPropertiesDictionary.java301
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/RelationshipTypeData.java14
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipTypeDefinition.java69
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeType.java27
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElement.java30
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/BaseOperation.java10
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperation.java91
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperation.java239
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTypeOperation.java10
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/RequirementOperation.java92
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java80
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java5
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java160
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java4
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java137
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OperationUtils.java27
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RelationshipTypeOperation.java513
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java4
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/utils/TypeCompareUtils.java16
-rw-r--r--catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeTypeTest.java8
-rw-r--r--catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/RelationshipTypeOperationTest.java474
-rw-r--r--catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ToscaElementLifecycleOperationTest.java8
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CapabilityDataDefinition.java2
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RelationshipInstDataDefinition.java13
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementDataDefinition.java6
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/JsonPresentationFields.java3
-rw-r--r--test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/api/Urls.java12
-rw-r--r--test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/capability/CapabilitiesTest.java119
-rw-r--r--test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/CapabilityDetails.java56
-rw-r--r--test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/RequirementDetails.java74
-rw-r--r--test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/requirements/RequirementsTest.java118
-rw-r--r--test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/CapabilityRestUtils.java76
-rw-r--r--test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/RequirementsUtils.java75
-rw-r--r--test-apis-ci/src/main/resources/ci/testSuites/cap_req.xml10
66 files changed, 6758 insertions, 399 deletions
diff --git a/asdctool/src/main/resources/config/error-configuration.yaml b/asdctool/src/main/resources/config/error-configuration.yaml
index 92ba0610ae..01f8ea4785 100644
--- a/asdctool/src/main/resources/config/error-configuration.yaml
+++ b/asdctool/src/main/resources/config/error-configuration.yaml
@@ -1689,4 +1689,117 @@ errors:
message: "Error: The server was acting as a gateway or proxy and received an invalid response from the upstream server",
messageId: "SVC4674"
}
+#---------SVC4675------------------------------
+# %1 - resource Id
+ CAPABILITY_NOT_FOUND: {
+ code: 400,
+ message: "Error: Capability not found in the resource '%1'.",
+ messageId: "SVC4675"
+ }
+#---------SVC4676------------------------------
+# %1 - resource Id
+ REQUIREMENT_NOT_FOUND: {
+ code: 400,
+ message: "Error: Requirement not found in the resource '%1'.",
+ messageId: "SVC4676"
+ }
+#---------SVC4677-----------------------------
+ CAPABILITY_NAME_MANDATORY: {
+ code: 404,
+ message: "Error: Capability name is mandatory, Capability name can't be empty.",
+ messageId: "SVC4677"
+ }
+#---------SVC4678-----------------------------
+ CAPABILITY_TYPE_MANDATORY: {
+ code: 404,
+ message: "Error: Capability type is mandatory, Capability type can't be empty.",
+ messageId: "SVC4678"
+ }
+#---------SVC4679-----------------------------
+# %1 - Capability Name
+ CAPABILITY_NAME_ALREADY_IN_USE: {
+ code: 400,
+ message: "Error: Capability name '%1' already in use, Your current changes will not be saved.",
+ messageId: "SVC4679"
+ }
+
+#---------SVC4680-----------------------------
+ REQUIREMENT_NAME_MANDATORY: {
+ code: 404,
+ message: "Error: Requirement name is mandatory, Requirement name can't be empty.",
+ messageId: "SVC4680"
+ }
+#---------SVC4681-----------------------------
+ REQUIREMENT_CAPABILITY_MANDATORY: {
+ code: 404,
+ message: "Error: Requirement capability is mandatory, Requirement capability can't be empty.",
+ messageId: "SVC4681"
+ }
+#---------SVC4682-----------------------------
+# %1 - Requirement Name
+ REQUIREMENT_NAME_ALREADY_IN_USE: {
+ code: 400,
+ message: "Error: Requirement name '%1' already in use, Your current changes will not be saved.",
+ messageId: "SVC4682"
+ }
+#---------SVC4683-----------------------------
+ MAX_OCCURRENCES_SHOULD_BE_GREATER_THAN_MIN_OCCURRENCES: {
+ code: 400,
+ message: "Error: maxOccurrences should be greater than minOccurrences",
+ messageId: "SVC4683"
+ }
+#---------SVC4684-----------------------------
+# %1 - Capability name
+ CAPABILITY_DELETION_NOT_ALLOWED_USED_IN_COMPOSITION: {
+ code: 409,
+ message: "Error: Capability '%1' can't be deleted, since it is used in service composition",
+ messageId: "SVC4684"
+ }
+#---------SVC4685-----------------------------
+# %1 - Requirement name
+ REQUIREMENT_DELETION_NOT_ALLOWED_USED_IN_COMPOSITION: {
+ code: 409,
+ message: "Error: Requirement '%1' can't be deleted, since it is used in service composition",
+ messageId: "SVC4685"
+ }
+#---------SVC4686-----------------------------
+ CAPABILITY_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION: {
+ code: 409,
+ message: "Error: Capability can't be updated, since it is used in service composition",
+ messageId: "SVC4686"
+ }
+
+#---------SVC4687-----------------------------
+ REQUIREMENT_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION: {
+ code: 409,
+ message: "Error: Requirement can't be updated, since it is used in service composition",
+ messageId: "SVC4687"
+ }
+#---------SVC4688-----------------------------
+ CAPABILITY_TYPE_CANNOT_BE_EMPTY: {
+ code: 500,
+ message: "Error: Capability types are empty. Please import the capability types.",
+ messageId: "SVC4688"
+ }
+#---------SVC4689-----------------------------
+ RELATIONSHIP_TYPE_ALREADY_EXIST: {
+ code: 409,
+ message: "Error: Relationship Type with name '%1' already exists.",
+ messageId: "SVC4689"
+ }
+#---------SVC4690-----------------------------
+# %1 - Requirement name
+ INVALID_REQUIREMENT_NAME: {
+ code: 400,
+ message: "Requirement name '%1' is invalid, Only alphanumeric chars, underscore and dot allowed",
+ messageId: "SVC4690"
+ }
+
+#---------SVC4691-----------------------------
+# %1 - Capability name
+ INVALID_CAPABILITY_NAME: {
+ code: 400,
+ message: "Capability name '%1' is invalid, Only alphanumeric chars, underscore and dot allowed",
+ messageId: "SVC4691"
+ } \ No newline at end of file
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());
diff --git a/catalog-be/src/main/resources/import/tosca/relationship-types/relationshipTypes.yml b/catalog-be/src/main/resources/import/tosca/relationship-types/relationshipTypes.yml
index 4506fa1b97..f446f21a62 100644
--- a/catalog-be/src/main/resources/import/tosca/relationship-types/relationshipTypes.yml
+++ b/catalog-be/src/main/resources/import/tosca/relationship-types/relationshipTypes.yml
@@ -15,18 +15,22 @@ tosca.relationships.Root:
Configure:
type: tosca.interfaces.relationship.Configure
+tosca.relationships.ConnectsTo:
+ derived_from: tosca.relationships.Root
+ description: This type represents a network connection relationship between two nodes.
+ valid_target_types:
+ - tosca.capabilities.Endpoint
+ properties:
+ credential:
+ type: tosca.datatypes.Credential
+ required: false
+
tosca.relationships.RoutesTo:
derived_from: tosca.relationships.ConnectsTo
description: This type represents an intentional network routing between two Endpoints in different networks.
valid_target_types:
- tosca.capabilities.Endpoint
-tosca.relationships.network.LinksTo:
- derived_from: tosca.relationships.DependsOn
- description: This relationship type represents an association relationship between Port and Network node types.
- valid_target_types:
- - tosca.capabilities.network.Linkable
-
tosca.relationships.AttachesTo:
derived_from: tosca.relationships.Root
description: This type represents an attachment relationship between two nodes. For example, an AttachesTo relationship type would be used for attaching a storage node to a Compute node.
@@ -52,12 +56,6 @@ tosca.relationships.AttachesTo:
orchestrator.'
type: string
-tosca.relationships.network.BindsTo:
- derived_from: tosca.relationships.DependsOn
- description: This type represents a network association relationship between Port and Compute node types.
- valid_target_types:
- - tosca.capabilities.network.Bindable
-
tosca.relationships.HostedOn:
derived_from: tosca.relationships.Root
description: This type represents a hosting relationship between two nodes.
@@ -70,15 +68,27 @@ tosca.relationships.DependsOn:
valid_target_types:
- tosca.capabilities.Node
-tosca.relationships.ConnectsTo:
- derived_from: tosca.relationships.Root
- description: This type represents a network connection relationship between two nodes.
+tosca.relationships.network.LinksTo:
+ derived_from: tosca.relationships.DependsOn
+ description: This relationship type represents an association relationship between Port and Network node types.
valid_target_types:
- - tosca.capabilities.Endpoint
- properties:
- credential:
- type: tosca.datatypes.Credential
- required: false
+ - tosca.capabilities.network.Linkable
+
+tosca.relationships.network.BindsTo:
+ derived_from: tosca.relationships.DependsOn
+ description: This type represents a network association relationship between Port and Compute node types.
+ valid_target_types:
+ - tosca.capabilities.network.Bindable
+
+org.openecomp.relationships.AttachesTo:
+ derived_from: tosca.relationships.AttachesTo
+ description: This type represents an attachment relationship
+ properties:
+ location:
+ description: The relative location (e.g., path on the file system), which provides the root location to address an attached node.
+ type: string
+ status: SUPPORTED
+ required: false
org.openecomp.relationships.VolumeAttachesTo:
derived_from: org.openecomp.relationships.AttachesTo
@@ -100,15 +110,6 @@ org.openecomp.relationships.VolumeAttachesTo:
type: string
status: SUPPORTED
-org.openecomp.relationships.AttachesTo:
- derived_from: tosca.relationships.AttachesTo
- description: This type represents an attachment relationship
- properties:
- location:
- description: The relative location (e.g., path on the file system), which provides the root location to address an attached node.
- type: string
- status: SUPPORTED
- required: false
org.openecomp.relationships.ForwardsTo:
derived_from: tosca.relationships.Root
valid_target_types: [org.openecomp.capabilities.Forwarder]
diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importNormativeAll.py b/catalog-be/src/main/resources/scripts/import/tosca/importNormativeAll.py
index 8a8329027f..19ffc1762f 100644
--- a/catalog-be/src/main/resources/scripts/import/tosca/importNormativeAll.py
+++ b/catalog-be/src/main/resources/scripts/import/tosca/importNormativeAll.py
@@ -8,6 +8,7 @@ from importNormativeElements import *
from importNormativeTypes import importNormativeTypes
from importHeatTypes import importHeatTypes
from importNormativeCapabilities import importNormativeCapabilities
+from importNormativeRelationships import importNormativeRelationships
from importCategoryTypes import importCategories
from importNormativeInterfaceLifecycleTypes import importNormativeInterfaceLifecycleType
from importDataTypes import importDataTypes
@@ -116,6 +117,9 @@ def main(argv):
fileLocation = baseFileLocation + "capability-types/"
importNormativeCapabilities(scheme, beHost, bePort, adminUser, False, fileLocation)
+ fileLocation = baseFileLocation + "relationship-types/"
+ importNormativeRelationships(scheme, beHost, bePort, adminUser, False, fileLocation)
+
fileLocation = baseFileLocation + "interface-lifecycle-types/"
importNormativeInterfaceLifecycleType(scheme, beHost, bePort, adminUser, False, fileLocation)
diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importNormativeRelationships.py b/catalog-be/src/main/resources/scripts/import/tosca/importNormativeRelationships.py
new file mode 100644
index 0000000000..a86e520558
--- /dev/null
+++ b/catalog-be/src/main/resources/scripts/import/tosca/importNormativeRelationships.py
@@ -0,0 +1,83 @@
+import pycurl
+import sys, getopt
+from StringIO import StringIO
+import json
+import copy
+from importNormativeElements import createNormativeElement
+from importCommon import *
+import importCommon
+
+#################################################################################################################################################################################################
+# #
+# Import normative relationships
+# #
+# #
+# activation : #
+# python importNormativeRelationships.py [-s <scheme> | --scheme=<scheme> ] [-i <be host> | --ip=<be host>] [-p
+# <be port> | --port=<be port> ] [-f <input file> | --ifile=<input file> ] #
+# #
+# shortest activation (be host = localhost, be port = 8080): #
+# python importNormativeRelationships.py [-f <input file> | --ifile=<input file> ]
+# #
+# #
+#################################################################################################################################################################################################
+
+
+def usage():
+ print sys.argv[0], '[optional -s <scheme> | --scheme=<scheme>, default http] [-i <be host> | --ip=<be host>] [-p <be port> | --port=<be port> ] [-u <user userId> | --user=<user userId> ]'
+
+
+def importNormativeRelationships(scheme, beHost, bePort, adminUser, exitOnSuccess, fileDir):
+ result = createNormativeElement(scheme, beHost, bePort, adminUser, fileDir, "/sdc2/rest/v1/catalog/uploadType/relationship", "relationshipTypes", "relationshipTypeZip")
+
+ print_frame_line()
+ print_name_and_return_code(result[0], result[1])
+ print_frame_line()
+
+ if ( result[1] == None or result[1] not in [200, 201, 409] ):
+ importCommon.error_and_exit(1, None)
+ else:
+ if (exitOnSuccess == True):
+ importCommon.error_and_exit(0, None)
+
+
+def main(argv):
+ print 'Number of arguments:', len(sys.argv), 'arguments.'
+
+ beHost = 'localhost'
+ bePort = '8080'
+ adminUser = 'jh0003'
+ scheme = 'http'
+
+ try:
+ opts, args = getopt.getopt(argv,"i:p:u:h:s:",["ip=","port=","user=","scheme="])
+ except getopt.GetoptError:
+ usage()
+ importCommon.error_and_exit(2, 'Invalid input')
+
+ for opt, arg in opts:
+ #print opt, arg
+ if opt == '-h':
+ usage()
+ sys.exit(3)
+ elif opt in ("-i", "--ip"):
+ beHost = arg
+ elif opt in ("-p", "--port"):
+ bePort = arg
+ elif opt in ("-u", "--user"):
+ adminUser = arg
+ elif opt in ("-s", "--scheme"):
+ scheme = arg
+
+ print 'scheme =',scheme,', be host =',beHost,', be port =', bePort,', user =', adminUser
+
+ if ( beHost == None ):
+ usage()
+ sys.exit(3)
+
+ importNormativeRelationships(scheme, beHost, bePort, adminUser, True, "../../../import/tosca/relationship-types/")
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
+
diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importONAPNormativeAll.py b/catalog-be/src/main/resources/scripts/import/tosca/importONAPNormativeAll.py
index ef1fe4d3b9..30b5a5435d 100644
--- a/catalog-be/src/main/resources/scripts/import/tosca/importONAPNormativeAll.py
+++ b/catalog-be/src/main/resources/scripts/import/tosca/importONAPNormativeAll.py
@@ -12,6 +12,7 @@ from importNfvTypes import importNfvTypes
from importOnapTypes import importOnapTypes
from importSolTypes import importSolTypes
from importNormativeCapabilities import importNormativeCapabilities
+from importNormativeRelationships import importNormativeRelationships
from importCategoryTypes import importCategories
from importNormativeInterfaceLifecycleTypes import importNormativeInterfaceLifecycleType
from importDataTypes import importDataTypes
@@ -111,12 +112,15 @@ def main(argv):
print 'sleep until data type cache is updated'
time.sleep( 70 )
-
+
fileLocation = baseFileLocation + "capability-types/"
importNormativeCapabilities(scheme, beHost, bePort, adminUser, False, fileLocation)
+
+ fileLocation = baseFileLocation + "relationship-types/"
+ importNormativeRelationships(scheme, beHost, bePort, adminUser, False, fileLocation)
fileLocation = baseFileLocation + "interface-lifecycle-types/"
- importNormativeInterfaceLifecycleType(scheme, beHost, bePort, adminUser, False, fileLocation)
+ importNormativeInterfaceLifecycleType(scheme, beHost, bePort, adminUser, False, fileLocation)
fileLocation = baseFileLocation + "categories/"
importCategories(scheme, beHost, bePort, adminUser, False, fileLocation)
diff --git a/catalog-be/src/main/resources/scripts/import/tosca/upgradeNormative.py b/catalog-be/src/main/resources/scripts/import/tosca/upgradeNormative.py
index bbeb3d6972..36a5d1181a 100644
--- a/catalog-be/src/main/resources/scripts/import/tosca/upgradeNormative.py
+++ b/catalog-be/src/main/resources/scripts/import/tosca/upgradeNormative.py
@@ -10,6 +10,7 @@ from importDataTypes import importDataTypes
from importPolicyTypes import importPolicyTypes
from importGroupTypes import importGroupTypes
from importNormativeCapabilities import importNormativeCapabilities
+from importNormativeRelationships import importNormativeRelationships
from importNormativeInterfaceLifecycleTypes import importNormativeInterfaceLifecycleType
from importAnnotationTypes import import_annotation_types
@@ -96,6 +97,9 @@ def main(argv):
fileLocation = baseFileLocation + "categories/"
importCategories(scheme, beHost, bePort, adminUser, False, fileLocation)
+ fileLocation = baseFileLocation + "relationship-types/"
+ importNormativeRelationships(scheme, beHost, bePort, adminUser, False, fileLocation)
+
fileLocation = baseFileLocation + "data-types/"
importDataTypes(scheme, beHost, bePort, adminUser, False, fileLocation)
diff --git a/catalog-be/src/main/resources/scripts/import/tosca/upgradeONAPNormative.py b/catalog-be/src/main/resources/scripts/import/tosca/upgradeONAPNormative.py
index bebba6c2cb..c6d217f986 100644
--- a/catalog-be/src/main/resources/scripts/import/tosca/upgradeONAPNormative.py
+++ b/catalog-be/src/main/resources/scripts/import/tosca/upgradeONAPNormative.py
@@ -10,6 +10,7 @@ from importDataTypes import importDataTypes
from importPolicyTypes import importPolicyTypes
from importGroupTypes import importGroupTypes
from importNormativeCapabilities import importNormativeCapabilities
+from importNormativeRelationships import importNormativeRelationships
from importNormativeInterfaceLifecycleTypes import importNormativeInterfaceLifecycleType
from upgradeNfvTypes import upgradeNfvTypesPerConfigFile
from upgradeONAPTypes import upgradeOnapTypesPerConfigFile
@@ -101,6 +102,9 @@ def main(argv):
fileLocation = baseFileLocation + "categories/"
importCategories(scheme, beHost, bePort, adminUser, False, fileLocation)
+ fileLocation = baseFileLocation + "relationship-types/"
+ importNormativeRelationships(scheme, beHost, bePort, adminUser, False, fileLocation)
+
fileLocation = baseFileLocation + "data-types/"
importDataTypes(scheme, beHost, bePort, adminUser, False, fileLocation)
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/CapabilitiesBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/CapabilitiesBusinessLogicTest.java
new file mode 100644
index 0000000000..393ef58d1d
--- /dev/null
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/CapabilitiesBusinessLogicTest.java
@@ -0,0 +1,443 @@
+/*
+ * 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.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.openecomp.sdc.be.auditing.impl.AuditingManager;
+import org.openecomp.sdc.be.components.validation.CapabilitiesValidation;
+import org.openecomp.sdc.be.components.validation.UserValidations;
+import org.openecomp.sdc.be.config.ConfigurationManager;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.impl.ComponentsUtils;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
+import org.openecomp.sdc.be.model.ComponentParametersView;
+import org.openecomp.sdc.be.model.LifecycleStateEnum;
+import org.openecomp.sdc.be.model.RelationshipInfo;
+import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
+import org.openecomp.sdc.be.model.Resource;
+import org.openecomp.sdc.be.model.Service;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.model.jsontitan.operations.CapabilitiesOperation;
+import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.operations.impl.GraphLockOperation;
+import org.openecomp.sdc.be.user.Role;
+import org.openecomp.sdc.be.user.UserBusinessLogic;
+import org.openecomp.sdc.common.api.ConfigurationSource;
+import org.openecomp.sdc.common.impl.ExternalConfiguration;
+import org.openecomp.sdc.common.impl.FSConfigurationSource;
+import org.openecomp.sdc.exception.ResponseFormat;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyCollection;
+import static org.mockito.ArgumentMatchers.anyObject;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+public class CapabilitiesBusinessLogicTest {
+ private final String componentId = "resourceId1";
+ private final String capabilityId = "uniqueId1";
+
+ private final TitanDao mockTitanDao = Mockito.mock(TitanDao.class);
+ private final UserBusinessLogic mockUserAdmin = Mockito.mock(UserBusinessLogic.class);
+ private final ToscaOperationFacade toscaOperationFacade = Mockito.mock(ToscaOperationFacade.class);
+ private final UserValidations userValidations = Mockito.mock(UserValidations.class);
+ private final CapabilitiesOperation capabilitiesOperation = Mockito.mock(CapabilitiesOperation.class);
+ private final CapabilitiesValidation capabilitiesValidation = Mockito.mock(CapabilitiesValidation.class);
+
+ private final GraphLockOperation graphLockOperation = Mockito.mock(GraphLockOperation.class);
+ private User user = null;
+
+ @InjectMocks
+ private CapabilitiesBusinessLogic capabilitiesBusinessLogicMock = new CapabilitiesBusinessLogic();
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ExternalConfiguration.setAppName("catalog-be");
+
+ // init Configuration
+ String appConfigDir = "src/test/resources/config/catalog-be";
+ ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), appConfigDir);
+ ConfigurationManager configurationManager = new ConfigurationManager(configurationSource);
+
+ ComponentsUtils componentsUtils = new ComponentsUtils(Mockito.mock(AuditingManager.class));
+
+ // User data and management
+ user = new User();
+ user.setUserId("jh0003");
+ user.setFirstName("Jimmi");
+ user.setLastName("Hendrix");
+ user.setRole(Role.ADMIN.name());
+
+ Either<User, ActionStatus> eitherGetUser = Either.left(user);
+ when(mockUserAdmin.getUser("jh0003", false)).thenReturn(eitherGetUser);
+ when(graphLockOperation.lockComponent(Mockito.anyString(), eq(NodeTypeEnum.Resource)))
+ .thenReturn(StorageOperationStatus.OK);
+
+ //CapabilityOperation
+ when(capabilitiesValidation.validateCapabilities(anyCollection(), anyObject(), anyBoolean())
+ ).thenReturn(Either.left(true));
+ when(capabilitiesOperation.addCapabilities(anyString(), anyObject()))
+ .thenReturn(Either.left(createMockCapabilityListToReturn(
+ createCapability("capName", "capDesc", "capType", "source1",
+ "0", "10"))));
+
+ when(capabilitiesOperation.updateCapabilities(anyString(), anyObject()))
+ .thenReturn(Either.left(createMockCapabilityListToReturn(
+ createCapability("capName", "capDesc", "capType", "source1",
+ "0", "10"))));
+ when(capabilitiesOperation.deleteCapabilities( anyObject(), anyString()))
+ .thenReturn(StorageOperationStatus.OK);
+ when(mockTitanDao.commit()).thenReturn(TitanOperationStatus.OK);
+
+ capabilitiesBusinessLogicMock = new CapabilitiesBusinessLogic();
+ capabilitiesBusinessLogicMock.setComponentsUtils(componentsUtils);
+ capabilitiesBusinessLogicMock.setUserAdmin(mockUserAdmin);
+ capabilitiesBusinessLogicMock.setGraphLockOperation(graphLockOperation);
+ capabilitiesBusinessLogicMock.setTitanGenericDao(mockTitanDao);
+ capabilitiesBusinessLogicMock.setToscaOperationFacade(toscaOperationFacade);
+ capabilitiesBusinessLogicMock.setUserValidations(userValidations);
+ capabilitiesBusinessLogicMock.setCapabilitiesOperation(capabilitiesOperation);
+ capabilitiesBusinessLogicMock.setCapabilitiesValidation(capabilitiesValidation);
+ }
+
+ @Test
+ public void shouldPassCreateCapabilitiesFirstTimeInComponentForHappyScenario(){
+ List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
+ createCapability("capName", "capDesc", "capType", "source1",
+ "0", "10"));
+ Resource resource = createComponent(false);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ Either<List<CapabilityDefinition>, ResponseFormat> capabilities = capabilitiesBusinessLogicMock
+ .createCapabilities(componentId, capabilityDefinitions, user,
+ "createCapabilities", true);
+ Assert.assertTrue(capabilities.isLeft());
+ Assert.assertTrue(capabilities.left().value().stream().anyMatch(capabilityDefinition ->
+ capabilityDefinition.getName().equals("capName")));
+ }
+
+ @Test
+ public void shouldPassCreateCapabilitiesForHappyScenario(){
+ List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
+ createCapability("capName2", "capDesc", "capType", "source1",
+ "0", "10"));
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ Either<List<CapabilityDefinition>, ResponseFormat> capabilities = capabilitiesBusinessLogicMock
+ .createCapabilities(componentId, capabilityDefinitions, user,
+ "createCapabilities", false);
+
+ Assert.assertTrue(capabilities.isLeft());
+ Assert.assertTrue(capabilities.left().value().stream().anyMatch(capabilityDefinition ->
+ capabilityDefinition.getName().equals("capName2")));
+ }
+
+ @Test
+ public void shouldFailCreateCapabilitiesWhenOperationFailedInTitan(){
+ List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
+ createCapability("capName2", "capDesc", "capType", "source1",
+ "0", "10"));
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(capabilitiesOperation.addCapabilities(anyString(), anyObject()))
+ .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR));
+ when(capabilitiesOperation.updateCapabilities(anyString(), anyObject()))
+ .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR));
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ Either<List<CapabilityDefinition>, ResponseFormat> capabilities = capabilitiesBusinessLogicMock
+ .createCapabilities(componentId, capabilityDefinitions, user,
+ "createCapabilities", true);
+
+ Assert.assertTrue(capabilities.isRight());
+ }
+ @Test
+ public void shouldPassUpdateCapabilitiesForHappyScenario(){
+
+ List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
+ createCapability("capName", "capDesc updated", "capType", "source1",
+ "6", "11"));
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ when(toscaOperationFacade.getParentComponents(anyString()))
+ .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+ Either<List<CapabilityDefinition>, ResponseFormat> capabilities = capabilitiesBusinessLogicMock
+ .updateCapabilities(componentId, capabilityDefinitions, user
+ , "updateCapabilities", true);
+ Assert.assertTrue(capabilities.isLeft());
+ Assert.assertTrue(capabilities.left().value().stream().anyMatch(capabilityDefinition ->
+ capabilityDefinition.getMaxOccurrences().equals("11")));
+ }
+
+ @Test
+ public void shouldPassUpdateCapabilityTypeUpdateWhenTypeIsNotAvailable(){
+
+ List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
+ createCapability("capName", "capDesc updated", "capTypeUpdate", "source1",
+ "6", "11"));
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ when(toscaOperationFacade.getParentComponents(anyString()))
+ .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+ Either<List<CapabilityDefinition>, ResponseFormat> capabilities = capabilitiesBusinessLogicMock
+ .updateCapabilities(componentId, capabilityDefinitions, user,
+ "updateCapabilities",true);
+ Assert.assertTrue(capabilities.isLeft());
+ Assert.assertTrue(capabilities.left().value().stream().anyMatch(capabilityDefinition ->
+ capabilityDefinition.getMaxOccurrences().equals("11")));
+ }
+
+ @Test
+ public void shouldPassUpdateCapabilityTypeUpdateWhenTypeIsAvailable(){
+
+ List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
+ createCapability("capName", "capDesc updated", "capTypeUpdate1", "source1",
+ "6", "11"));
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+
+ CapabilityDefinition capability = createCapability("capName", "capDesc", "capTypeUpdate1",
+ "source1", "0", "10");
+ capability.setUniqueId("unique2");
+ List<CapabilityDefinition> capabilityDefinitions1 = createMockCapabilityListToReturn(capability);
+ Map<String, List<CapabilityDefinition>> capabilityMap = new HashMap<>();
+ capabilityMap.put("capTypeUpdate1", capabilityDefinitions1);
+ resource.getCapabilities().putAll(capabilityMap);
+
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ when(toscaOperationFacade.getParentComponents(anyString()))
+ .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+ Either<List<CapabilityDefinition>, ResponseFormat> capabilities = capabilitiesBusinessLogicMock
+ .updateCapabilities(componentId, capabilityDefinitions, user,
+ "updateCapabilities",true);
+ Assert.assertTrue(capabilities.isLeft());
+ Assert.assertTrue(capabilities.left().value().stream().anyMatch(capabilityDefinition ->
+ capabilityDefinition.getMaxOccurrences().equals("11")));
+ }
+
+ @Test
+ public void shouldFailUpdateCapabilitiesWhenOperaitonFailedInTitan(){
+ List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
+ createCapability("capName2", "capDesc", "capType", "source1",
+ "0", "10"));
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(capabilitiesOperation.addCapabilities(anyString(), anyObject()))
+ .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR));
+ when(capabilitiesOperation.updateCapabilities(anyString(), anyObject()))
+ .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR));
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ Either<List<CapabilityDefinition>, ResponseFormat> capabilities = capabilitiesBusinessLogicMock
+ .updateCapabilities(componentId, capabilityDefinitions, user,
+ "updateCapabilities", true);
+
+ Assert.assertTrue(capabilities.isRight());
+ }
+
+ @Test
+ public void shouldPassDeleteCapabilitiesForHappyScenario(){
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ when(toscaOperationFacade.getParentComponents(anyString()))
+ .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+ Either<CapabilityDefinition, ResponseFormat> deleteCapabilityEither =
+ capabilitiesBusinessLogicMock.deleteCapability(componentId, capabilityId, user, true);
+ Assert.assertTrue(deleteCapabilityEither.isLeft());
+
+ }
+
+ @Test
+ public void shouldFailDeleteCapabilitiesWhenOperationFailedInTitan(){
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ when(toscaOperationFacade.getParentComponents(anyString()))
+ .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+ when(capabilitiesOperation.deleteCapabilities(anyObject(), anyString()))
+ .thenReturn(StorageOperationStatus.GENERAL_ERROR);
+ Either<CapabilityDefinition, ResponseFormat> deleteCapabilityEither
+ = capabilitiesBusinessLogicMock.deleteCapability(componentId, capabilityId, user, true);
+ Assert.assertTrue(deleteCapabilityEither.isRight());
+ }
+
+ @Test
+ public void shouldFailDeleteCapabilitiesWhenCapabilityUsedInServiceComposition(){
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ when(toscaOperationFacade.getParentComponents(anyString()))
+ .thenReturn(Either.left(Collections.singletonList(createParentService())));
+ Either<CapabilityDefinition, ResponseFormat> deleteCapabilityEither
+ = capabilitiesBusinessLogicMock.deleteCapability(componentId, capabilityId, user, true);
+ Assert.assertTrue(deleteCapabilityEither.isRight());
+ }
+
+ @Test
+ public void shouldPassGetCapabilitiesForHappyScenario(){
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ when(toscaOperationFacade.getParentComponents(anyString()))
+ .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+ Either<CapabilityDefinition, ResponseFormat> getCapabilityEither
+ = capabilitiesBusinessLogicMock.getCapability(componentId, capabilityId, user, true);
+ Assert.assertTrue(getCapabilityEither.isLeft());
+
+ }
+
+ @Test
+ public void shouldFailGetCapabilitiesWhenCapabilityNotExist(){
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ when(toscaOperationFacade.getParentComponents(anyString()))
+ .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+ Either<CapabilityDefinition, ResponseFormat> getCapabilityEither
+ = capabilitiesBusinessLogicMock.getCapability(componentId, "capId1", user, true);
+ Assert.assertTrue(getCapabilityEither.isRight());
+
+ }
+
+ private Resource createComponent(boolean needCapability) {
+ Resource resource = new Resource();
+ resource.setName("Resource1");
+ resource.addCategory("Network Layer 2-3", "Router");
+ resource.setDescription("My short description");
+ List<String> tgs = new ArrayList<>();
+ tgs.add("test");
+ tgs.add(resource.getName());
+ resource.setTags(tgs);
+
+ if(needCapability) {
+ List<CapabilityDefinition> capabilityDefinitions = createMockCapabilityListToReturn(
+ createCapability("capName", "capDesc", "capType", "source1",
+ "0", "10"));
+ Map<String, List<CapabilityDefinition>> capabilityMap = new HashMap<>();
+ capabilityMap.put("capType", capabilityDefinitions);
+ resource.setCapabilities(capabilityMap);
+ }
+ resource.setName(resource.getName());
+ resource.setVersion("0.1");
+ resource.setUniqueId(resource.getName().toLowerCase() + ":" + resource.getVersion());
+ resource.setCreatorUserId(user.getUserId());
+ resource.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
+ resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+ return resource;
+ }
+
+ private List<CapabilityDefinition> createMockCapabilityListToReturn(CapabilityDefinition capabilityDefinition) {
+ List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
+ capabilityDefinitions.add(capabilityDefinition);
+ return capabilityDefinitions;
+ }
+
+ private void validateUserRoles(Role... roles) {
+ List<Role> listOfRoles = Stream.of(roles).collect(Collectors.toList());
+ }
+
+ private CapabilityDefinition createCapability(String name, String description, String type,
+ String validSourceTypes, String minOccurrences,
+ String maxOccurrences) {
+ CapabilityDefinition capabilityDefinition = new CapabilityDefinition();
+ capabilityDefinition.setName(name);
+ capabilityDefinition.setDescription(description);
+ capabilityDefinition.setType(type);
+ capabilityDefinition.setValidSourceTypes(Collections.singletonList(validSourceTypes));
+ capabilityDefinition.setMaxOccurrences(maxOccurrences);
+ capabilityDefinition.setMinOccurrences(minOccurrences);
+ capabilityDefinition.setUniqueId(capabilityId);
+
+ return capabilityDefinition;
+ }
+
+ private Service createParentService() {
+ Service service = new Service();
+ service.setUniqueId("serviceUniqueId");
+
+ List<RequirementCapabilityRelDef> resourceInstancesRelations = new ArrayList<>();
+ RequirementCapabilityRelDef relationDef = new RequirementCapabilityRelDef();
+ relationDef.setFromNode("fromNode");
+ relationDef.setToNode("toNode");
+
+ List<CapabilityRequirementRelationship> relationships = new ArrayList<>();
+ CapabilityRequirementRelationship capabilityRequirementRelationship = new CapabilityRequirementRelationship();
+
+ RelationshipInfo relation = new RelationshipInfo();
+ relation.setCapabilityUid(capabilityId);
+ relation.setRequirementUid("reqUniqueId1");
+ capabilityRequirementRelationship.setRelation(relation);
+
+ relationships.add(capabilityRequirementRelationship);
+ relationDef.setRelationships(relationships);
+ resourceInstancesRelations.add(relationDef);
+
+ service.setComponentInstancesRelations(resourceInstancesRelations);
+
+ return service;
+ }
+
+} \ No newline at end of file
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/RequirementBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/RequirementBusinessLogicTest.java
new file mode 100644
index 0000000000..3cac5f5b15
--- /dev/null
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/RequirementBusinessLogicTest.java
@@ -0,0 +1,412 @@
+/*
+ * 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.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.openecomp.sdc.be.auditing.impl.AuditingManager;
+import org.openecomp.sdc.be.components.validation.RequirementValidation;
+import org.openecomp.sdc.be.components.validation.UserValidations;
+import org.openecomp.sdc.be.config.ConfigurationManager;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.impl.ComponentsUtils;
+import org.openecomp.sdc.be.model.CapabilityRequirementRelationship;
+import org.openecomp.sdc.be.model.ComponentParametersView;
+import org.openecomp.sdc.be.model.LifecycleStateEnum;
+import org.openecomp.sdc.be.model.RelationshipInfo;
+import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
+import org.openecomp.sdc.be.model.RequirementDefinition;
+import org.openecomp.sdc.be.model.Resource;
+import org.openecomp.sdc.be.model.Service;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.model.jsontitan.operations.RequirementOperation;
+import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.operations.impl.GraphLockOperation;
+import org.openecomp.sdc.be.user.Role;
+import org.openecomp.sdc.be.user.UserBusinessLogic;
+import org.openecomp.sdc.common.api.ConfigurationSource;
+import org.openecomp.sdc.common.impl.ExternalConfiguration;
+import org.openecomp.sdc.common.impl.FSConfigurationSource;
+import org.openecomp.sdc.exception.ResponseFormat;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyCollection;
+import static org.mockito.ArgumentMatchers.anyObject;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+public class RequirementBusinessLogicTest {
+ private final String componentId = "resourceId1";
+ private final String requirementId = "uniqueId1";
+
+ private final TitanDao mockTitanDao = Mockito.mock(TitanDao.class);
+ private final UserBusinessLogic mockUserAdmin = Mockito.mock(UserBusinessLogic.class);
+ private final ToscaOperationFacade toscaOperationFacade = Mockito.mock(ToscaOperationFacade.class);
+ private final UserValidations userValidations = Mockito.mock(UserValidations.class);
+ private final RequirementOperation requirementOperation = Mockito.mock(RequirementOperation.class);
+ private final RequirementValidation requirementValidation = Mockito.mock(RequirementValidation.class);
+
+ private final GraphLockOperation graphLockOperation = Mockito.mock(GraphLockOperation.class);
+ private User user = null;
+
+ @InjectMocks
+ private RequirementBusinessLogic requirementsBusinessLogicMock = new RequirementBusinessLogic();
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ExternalConfiguration.setAppName("catalog-be");
+
+ // init Configuration
+ String appConfigDir = "src/test/resources/config/catalog-be";
+ ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration
+ .getChangeListener(), appConfigDir);
+ ConfigurationManager configurationManager = new ConfigurationManager(configurationSource);
+
+ ComponentsUtils componentsUtils = new ComponentsUtils(Mockito.mock(AuditingManager.class));
+ // User data and management
+ user = new User();
+ user.setUserId("jh0003");
+ user.setFirstName("Jimmi");
+ user.setLastName("Hendrix");
+ user.setRole(Role.ADMIN.name());
+
+ Either<User, ActionStatus> eitherGetUser = Either.left(user);
+ when(mockUserAdmin.getUser("jh0003", false)).thenReturn(eitherGetUser);
+ when(graphLockOperation.lockComponent(Mockito.anyString(), eq(NodeTypeEnum.Resource)))
+ .thenReturn(StorageOperationStatus.OK);
+
+ //CapabilityOperation
+ when(requirementValidation.validateRequirements(anyCollection(), anyObject(), anyBoolean()))
+ .thenReturn(Either.left(true));
+ when(requirementOperation.addRequirement(anyString(), anyObject()))
+ .thenReturn(Either.left(createMockRequirementListToReturn(createRequirement(
+ "reqName", "capType", "node", "source1",
+ "0", "10"))));
+
+ when(requirementOperation.updateRequirement(anyString(), anyObject()))
+ .thenReturn(Either.left(createMockRequirementListToReturn(createRequirement(
+ "reqName", "capType", "node", "source1",
+ "0", "10"))));
+ when(requirementOperation.deleteRequirements( anyObject(), anyString()))
+ .thenReturn(StorageOperationStatus.OK);
+ when(mockTitanDao.commit()).thenReturn(TitanOperationStatus.OK);
+
+ requirementsBusinessLogicMock = new RequirementBusinessLogic();
+
+ requirementsBusinessLogicMock.setComponentsUtils(componentsUtils);
+ requirementsBusinessLogicMock.setUserAdmin(mockUserAdmin);
+ requirementsBusinessLogicMock.setGraphLockOperation(graphLockOperation);
+ requirementsBusinessLogicMock.setTitanGenericDao(mockTitanDao);
+ requirementsBusinessLogicMock.setToscaOperationFacade(toscaOperationFacade);
+ requirementsBusinessLogicMock.setUserValidations(userValidations);
+ requirementsBusinessLogicMock.setRequirementOperation(requirementOperation);
+ requirementsBusinessLogicMock.setRequirementValidation(requirementValidation);
+ }
+
+ @Test
+ public void shouldPassCreateRequirementsFirstTimeInComponentForHappyScenario(){
+ List<RequirementDefinition> requirementDefinitions = createMockRequirementListToReturn(
+ createRequirement("reqName", "reqDesc", "capType", "source1",
+ "0", "10"));
+ Resource resource = createComponent(false);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ Either<List<RequirementDefinition>, ResponseFormat> requirements = requirementsBusinessLogicMock
+ .createRequirements(componentId, requirementDefinitions, user,
+ "createRequirements", true);
+ Assert.assertTrue(requirements.isLeft());
+ Assert.assertTrue(requirements.left().value().stream().anyMatch(requirementDefinition ->
+ requirementDefinition.getName().equals("reqName")));
+ }
+
+ @Test
+ public void shouldPassCreateRequirementsForHappyScenario(){
+ List<RequirementDefinition> requirementDefinitions = createMockRequirementListToReturn(
+ createRequirement("reqName2", "capType", "node", "source1",
+ "0", "10"));
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ Either<List<RequirementDefinition>, ResponseFormat> requirements = requirementsBusinessLogicMock
+ .createRequirements(componentId, requirementDefinitions, user,
+ "createRequirements", true);
+
+ Assert.assertTrue(requirements.isLeft());
+ Assert.assertTrue(requirements.left().value().stream().anyMatch(requirementDefinition ->
+ requirementDefinition.getName().equals("reqName2")));
+ }
+
+ @Test
+ public void shouldPassUpdateRequirementsForHappyScenario(){
+
+ List<RequirementDefinition> requirementDefinitions = createMockRequirementListToReturn(
+ createRequirement("reqName", "capType", "node", "source1",
+ "6", "11"));
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ when(toscaOperationFacade.getParentComponents(anyString()))
+ .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+ Either<List<RequirementDefinition>, ResponseFormat> capabilities = requirementsBusinessLogicMock
+ .updateRequirements(componentId, requirementDefinitions, user,
+ "updateRequirements", true);
+ Assert.assertTrue(capabilities.isLeft());
+ Assert.assertTrue(capabilities.left().value().stream().anyMatch(requirementDefinition ->
+ requirementDefinition.getMaxOccurrences().equals("11")));
+ }
+
+ @Test
+ public void shouldPassDeleteRequirementsForHappyScenario(){
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ when(toscaOperationFacade.getParentComponents(anyString()))
+ .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+ Either<RequirementDefinition, ResponseFormat> deleteRequirementEither
+ = requirementsBusinessLogicMock.deleteRequirement(componentId, requirementId, user, true);
+ Assert.assertTrue(deleteRequirementEither.isLeft());
+
+ }
+
+ @Test
+ public void shouldPassUpdateRequirementCapabilityUpdateWhenCapabilityNotExist(){
+
+ List<RequirementDefinition> requirementDefinitions
+ = createMockRequirementListToReturn(createRequirement(
+ "reqName", "capTypeUpdate", "node", "source1",
+ "6", "11"));
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ when(toscaOperationFacade.getParentComponents(anyString()))
+ .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+ Either<List<RequirementDefinition>, ResponseFormat> updateRequirements
+ = requirementsBusinessLogicMock.updateRequirements(componentId, requirementDefinitions,
+ user, "updateRequirements", true);
+ Assert.assertTrue(updateRequirements.isLeft());
+ Assert.assertTrue(updateRequirements.left().value().stream().anyMatch(requirementDefinition ->
+ requirementDefinition.getMaxOccurrences().equals("11")));
+ }
+
+ @Test
+ public void shouldPassUpdateRequirementTypeWhenCapabilityExist(){
+
+ List<RequirementDefinition> requirementDefinitions = createMockRequirementListToReturn(
+ createRequirement("reqName", "capTypeUpdate1", "node",
+ "source1","6", "11"));
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+
+ RequirementDefinition requirement = createRequirement("reqName",
+ "capTypeUpdate1", "node", "source1",
+ "6", "11");
+ requirement.setUniqueId("unique2");
+ List<RequirementDefinition> requirementDefinitions1 = createMockRequirementListToReturn(requirement);
+ Map<String, List<RequirementDefinition>> requirementMap = new HashMap<>();
+ requirementMap.put("capTypeUpdate1", requirementDefinitions1);
+ resource.getRequirements().putAll(requirementMap);
+
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ when(toscaOperationFacade.getParentComponents(anyString()))
+ .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+ Either<List<RequirementDefinition>, ResponseFormat> capabilities
+ = requirementsBusinessLogicMock.updateRequirements(componentId, requirementDefinitions,
+ user, "updateRequirements", true);
+ Assert.assertTrue(capabilities.isLeft());
+ Assert.assertTrue(capabilities.left().value().stream().anyMatch(capabilityDefinition ->
+ capabilityDefinition.getMaxOccurrences().equals("11")));
+ }
+
+ @Test
+ public void shouldFailUpdateRequirementWhenOperationFailedInTitan(){
+ List<RequirementDefinition> requirementDefinitions = createMockRequirementListToReturn(
+ createRequirement("reqName", "capType", "node", "source1",
+ "6", "11"));
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(requirementOperation.addRequirement(anyString(), anyObject()))
+ .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR));
+ when(requirementOperation.updateRequirement(anyString(), anyObject()))
+ .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR));
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ Either<List<RequirementDefinition>, ResponseFormat> capabilities = requirementsBusinessLogicMock
+ .updateRequirements(componentId, requirementDefinitions, user,
+ "updateRequirements", true);
+
+ Assert.assertTrue(capabilities.isRight());
+ }
+
+
+ @Test
+ public void shouldFailDeleteRequirementWhenOperationFailedInTitan(){
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ when(toscaOperationFacade.getParentComponents(anyString()))
+ .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+ when(requirementOperation.deleteRequirements(anyObject(), anyString()))
+ .thenReturn(StorageOperationStatus.GENERAL_ERROR);
+ Either<RequirementDefinition, ResponseFormat> deleteRequirementEither
+ = requirementsBusinessLogicMock.deleteRequirement(componentId, requirementId, user, true);
+ Assert.assertTrue(deleteRequirementEither.isRight());
+ }
+
+ @Test
+ public void shouldFailDeleteRequirementWhenRequirementUsedInServiceComposition(){
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ when(toscaOperationFacade.getParentComponents(anyString()))
+ .thenReturn(Either.left(Collections.singletonList(createParentService())));
+ Either<RequirementDefinition, ResponseFormat> deleteRequirementEither
+ = requirementsBusinessLogicMock.deleteRequirement(componentId, requirementId, user, true);
+ Assert.assertTrue(deleteRequirementEither.isRight());
+ }
+
+ @Test
+ public void shouldPassGetRequirementsForHappyScenario(){
+ Resource resource = createComponent(true);
+ resource.setComponentType(ComponentTypeEnum.RESOURCE);
+ validateUserRoles(Role.ADMIN, Role.DESIGNER);
+ when(toscaOperationFacade.getToscaElement(anyString(), any(ComponentParametersView.class)))
+ .thenReturn(Either.left(resource));
+ when(toscaOperationFacade.getParentComponents(anyString()))
+ .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+ Either<RequirementDefinition, ResponseFormat> getRequirementEither
+ = requirementsBusinessLogicMock.getRequirement(componentId, requirementId, user, true);
+ Assert.assertTrue(getRequirementEither.isLeft());
+
+ }
+
+ private Resource createComponent(boolean needRequirements) {
+ Resource resource = new Resource();
+ resource.setName("Resource1");
+ resource.addCategory("Network Layer 2-3", "Router");
+ resource.setDescription("My short description");
+ List<String> tgs = new ArrayList<>();
+ tgs.add("test");
+ tgs.add(resource.getName());
+ resource.setTags(tgs);
+
+ if(needRequirements) {
+ List<RequirementDefinition> requirementDefinitions = createMockRequirementListToReturn(
+ createRequirement("reqName", "capType", "node", "source1",
+ "0", "10"));
+ Map<String, List<RequirementDefinition>> requirementsMap = new HashMap<>();
+ requirementsMap.put("capType", requirementDefinitions);
+ resource.setRequirements(requirementsMap);
+ }
+ resource.setName(resource.getName());
+ resource.setVersion("0.1");
+ resource.setUniqueId(resource.getName().toLowerCase() + ":" + resource.getVersion());
+ resource.setCreatorUserId(user.getUserId());
+ resource.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
+ resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+ return resource;
+ }
+
+ private List<RequirementDefinition> createMockRequirementListToReturn(RequirementDefinition requirementDefinition) {
+ List<RequirementDefinition> requirementDefinitions = new ArrayList<>();
+ requirementDefinitions.add(requirementDefinition);
+ return requirementDefinitions;
+ }
+
+ private void validateUserRoles(Role... roles) {
+ List<Role> listOfRoles = Stream.of(roles).collect(Collectors.toList());
+ }
+
+ private RequirementDefinition createRequirement(String name, String capability, String node,
+ String relationship, String minOccurrences,
+ String maxOccurrences) {
+ RequirementDefinition requirementDefinition = new RequirementDefinition();
+ requirementDefinition.setName(name);
+ requirementDefinition.setCapability(capability);
+ requirementDefinition.setNode(node);
+ requirementDefinition.setRelationship(relationship);
+ requirementDefinition.setMaxOccurrences(maxOccurrences);
+ requirementDefinition.setMinOccurrences(minOccurrences);
+ requirementDefinition.setUniqueId(requirementId);
+
+ return requirementDefinition;
+ }
+
+ private Service createParentService() {
+ Service service = new Service();
+ service.setUniqueId("serviceUniqueId");
+
+ List<RequirementCapabilityRelDef> resourceInstancesRelations = new ArrayList<>();
+ RequirementCapabilityRelDef relationDef = new RequirementCapabilityRelDef();
+ relationDef.setFromNode("fromNode");
+ relationDef.setToNode("toNode");
+
+ List<CapabilityRequirementRelationship> relationships = new ArrayList<>();
+ CapabilityRequirementRelationship capabilityRequirementRelationship = new CapabilityRequirementRelationship();
+
+ RelationshipInfo relation = new RelationshipInfo();
+ relation.setCapabilityUid("capabilityId");
+ relation.setRequirementUid(requirementId);
+ capabilityRequirementRelationship.setRelation(relation);
+
+ relationships.add(capabilityRequirementRelationship);
+ relationDef.setRelationships(relationships);
+ resourceInstancesRelations.add(relationDef);
+
+ service.setComponentInstancesRelations(resourceInstancesRelations);
+
+ return service;
+ }
+
+} \ No newline at end of file
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/CapabilitiesValidationTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/CapabilitiesValidationTest.java
new file mode 100644
index 0000000000..b4856b96b4
--- /dev/null
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/CapabilitiesValidationTest.java
@@ -0,0 +1,159 @@
+/*
+ * 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.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.Resource;
+import org.openecomp.sdc.exception.ResponseFormat;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+public class CapabilitiesValidationTest {
+ private ResponseFormatManager responseFormatManagerMock;
+ private final Component component = createComponent();
+ private final CapabilitiesValidationUtilTest capabilitiesValidationUtilTest = new CapabilitiesValidationUtilTest();
+ @Before
+ public void init() {
+ MockitoAnnotations.initMocks(this);
+ responseFormatManagerMock = Mockito.mock(ResponseFormatManager.class);
+ when(responseFormatManagerMock.getResponseFormat(any())).thenReturn(new ResponseFormat());
+ when(responseFormatManagerMock.getResponseFormat(any(), any())).thenReturn(new ResponseFormat());
+ when(responseFormatManagerMock.getResponseFormat(any(), any(), any())).thenReturn(new ResponseFormat());
+ }
+
+ @Test
+ public void shouldPassCapabilitiesValidationForHappyScenario() {
+ List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
+ capabilityDefinitions.add(createCapability("capName", "capDesc", "capType", "source1",
+ "0", "10"));
+ Either<Boolean, ResponseFormat> validateCapabilitiesResponseEither = capabilitiesValidationUtilTest
+ .validateCapabilities(capabilityDefinitions, component, false);
+ Assert.assertTrue(validateCapabilitiesResponseEither.isLeft());
+ }
+
+ @Test
+ public void shouldFailWhenCapabilityNameAlreadyExist() {
+ List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
+ capabilityDefinitions.add(createCapability("capNameC", "capDesc", "capType", "source1",
+ "0", "10"));
+ Either<Boolean, ResponseFormat> validateCapabilitiesResponseEither = capabilitiesValidationUtilTest
+ .validateCapabilities(capabilityDefinitions, component, false);
+ Assert.assertTrue(validateCapabilitiesResponseEither.isRight());
+ }
+
+ @Test
+ public void shouldFailWhenCapabilityNameEmpty() {
+ List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
+ capabilityDefinitions.add(createCapability("", "capDesc", "capType", "source1",
+ "0", "10"));
+ Either<Boolean, ResponseFormat> validateCapabilitiesResponseEither = capabilitiesValidationUtilTest
+ .validateCapabilities(capabilityDefinitions, component, false);
+ Assert.assertTrue(validateCapabilitiesResponseEither.isRight());
+ }
+
+ @Test
+ public void shouldFailWhenCapabilityTypeEmpty() {
+ List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
+ capabilityDefinitions.add(createCapability("capName1", "capDesc", "", "source1",
+ "0", "10"));
+ Either<Boolean, ResponseFormat> validateCapabilitiesResponseEither = capabilitiesValidationUtilTest
+ .validateCapabilities(capabilityDefinitions, component, false);
+ Assert.assertTrue(validateCapabilitiesResponseEither.isRight());
+ }
+
+ @Test
+ public void shouldFailWhenCapabilityMaxOccurrencesLessThanMinOccurrences() {
+ List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
+ capabilityDefinitions.add(createCapability("capName1", "capDesc", "capType", "source1",
+ "111", "3"));
+ Either<Boolean, ResponseFormat> validateCapabilitiesResponseEither = capabilitiesValidationUtilTest
+ .validateCapabilities(capabilityDefinitions, component, false);
+ Assert.assertTrue(validateCapabilitiesResponseEither.isRight());
+ }
+
+ @Test
+ public void shouldFailWhenCapabilityNotFoundForUpdate() {
+ List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
+ CapabilityDefinition capabilityToUpdate = createCapability("capName1", "capDesc", "capType", "source1",
+ "1", "3");
+ capabilityToUpdate.setUniqueId("uniqueId2");
+
+ capabilityDefinitions.add(capabilityToUpdate);
+ Either<Boolean, ResponseFormat> validateCapabilitiesResponseEither = capabilitiesValidationUtilTest
+ .validateCapabilities(capabilityDefinitions, component, true);
+ Assert.assertTrue(validateCapabilitiesResponseEither.isRight());
+ }
+
+ private CapabilityDefinition createCapability(String name, String description, String type,
+ String validSourceTypes, String minOccurrences,
+ String maxOccurrences) {
+ CapabilityDefinition capabilityDefinition = new CapabilityDefinition();
+ capabilityDefinition.setName(name);
+ capabilityDefinition.setDescription(description);
+ capabilityDefinition.setType(type);
+ capabilityDefinition.setValidSourceTypes(Collections.singletonList(validSourceTypes));
+ capabilityDefinition.setMaxOccurrences(maxOccurrences);
+ capabilityDefinition.setMinOccurrences(minOccurrences);
+ capabilityDefinition.setUniqueId("uniqueId");
+
+
+ return capabilityDefinition;
+ }
+
+ private Resource createComponent() {
+ Resource resource = new Resource();
+ resource.setName("Resource1");
+ resource.addCategory("Network Layer 2-3", "Router");
+ resource.setDescription("My short description");
+ List<String> tgs = new ArrayList<>();
+ tgs.add("test");
+ tgs.add(resource.getName());
+ resource.setTags(tgs);
+
+ List<CapabilityDefinition> capabilityDefinitions = new ArrayList<>();
+ capabilityDefinitions.add(createCapability("capNameC", "capDesc", "capType", "source1",
+ "0", "10"));
+ Map<String, List<CapabilityDefinition>> capabilityMap = new HashMap<>();
+ capabilityMap.put("capTypeC", capabilityDefinitions);
+ resource.setCapabilities(capabilityMap);
+
+ return resource;
+ }
+
+ private class CapabilitiesValidationUtilTest extends CapabilitiesValidation {
+
+ protected ResponseFormatManager getResponseFormatManager() {
+ return responseFormatManagerMock;
+ }
+ }
+} \ No newline at end of file
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/RequirementValidationTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/RequirementValidationTest.java
new file mode 100644
index 0000000000..ff9bcd1bac
--- /dev/null
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/RequirementValidationTest.java
@@ -0,0 +1,156 @@
+/*
+ * 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.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.RequirementDefinition;
+import org.openecomp.sdc.be.model.Resource;
+import org.openecomp.sdc.exception.ResponseFormat;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+public class RequirementValidationTest {
+ private ResponseFormatManager responseFormatManagerMock;
+ private final Component component = createComponent();
+ private final RequirementValidationUtilTest requirementValidationUtilTest = new RequirementValidationUtilTest();
+ @Before
+ public void init() {
+ MockitoAnnotations.initMocks(this);
+ responseFormatManagerMock = Mockito.mock(ResponseFormatManager.class);
+ when(responseFormatManagerMock.getResponseFormat(any())).thenReturn(new ResponseFormat());
+ when(responseFormatManagerMock.getResponseFormat(any(), any())).thenReturn(new ResponseFormat());
+ when(responseFormatManagerMock.getResponseFormat(any(), any(), any())).thenReturn(new ResponseFormat());
+ }
+
+ @Test
+ public void shouldPassRequirementsValidationForHappyScenario() {
+ List<RequirementDefinition> requirementsDefinitions = new ArrayList<>();
+ requirementsDefinitions.add(createRequirement("reqName", "capType", "node", "source1",
+ "0", "10"));
+ Either<Boolean, ResponseFormat> validateRequirementsResponseEither = requirementValidationUtilTest
+ .validateRequirements(requirementsDefinitions, component, false);
+ Assert.assertTrue(validateRequirementsResponseEither.isLeft());
+ }
+
+ @Test
+ public void shouldFailWhenRequirementNameAlreadyExist() {
+ List<RequirementDefinition> requirementsDefinitions = new ArrayList<>();
+ requirementsDefinitions.add(createRequirement("ReqNameC", "capType", "node", "source1",
+ "0", "10"));
+ Either<Boolean, ResponseFormat> validateRequirementsResponseEither = requirementValidationUtilTest
+ .validateRequirements(requirementsDefinitions, component, false);
+ Assert.assertTrue(validateRequirementsResponseEither.isRight());
+ }
+
+ @Test
+ public void shouldFailWhenRequirementNameEmpty() {
+ List<RequirementDefinition> requirementsDefinitions = new ArrayList<>();
+ requirementsDefinitions.add(createRequirement("", "capType", "node", "source1",
+ "0", "10"));
+ Either<Boolean, ResponseFormat> validateRequirementsResponseEither = requirementValidationUtilTest
+ .validateRequirements(requirementsDefinitions, component, false);
+ Assert.assertTrue(validateRequirementsResponseEither.isRight());
+ }
+
+ @Test
+ public void shouldFailWhenRequirementCapabilityEmpty() {
+ List<RequirementDefinition> requirementsDefinitions = new ArrayList<>();
+ requirementsDefinitions.add(createRequirement("reqName1", "", "node", "source1",
+ "0", "10"));
+ Either<Boolean, ResponseFormat> validateRequirementsResponseEither = requirementValidationUtilTest
+ .validateRequirements(requirementsDefinitions, component, false);
+ Assert.assertTrue(validateRequirementsResponseEither.isRight());
+ }
+
+ @Test
+ public void shouldFailWhenRequirementMaxOccurrencesLessThanMinOccurrences() {
+ List<RequirementDefinition> requirementsDefinitions = new ArrayList<>();
+ requirementsDefinitions.add(createRequirement("reqName1", "capType", "node", "source1",
+ "111", "3"));
+ Either<Boolean, ResponseFormat> validateRequirementsResponseEither = requirementValidationUtilTest
+ .validateRequirements(requirementsDefinitions, component, false);
+ Assert.assertTrue(validateRequirementsResponseEither.isRight());
+ }
+
+ @Test
+ public void shouldFailWhenRequirementNotFoundForUpdate() {
+ List<RequirementDefinition> requirementsDefinitions = new ArrayList<>();
+ RequirementDefinition requirementsToUpdate = createRequirement("reqName1", "capType", "node", "source1",
+ "1", "3");
+ requirementsToUpdate.setUniqueId("uniqueId2");
+
+ requirementsDefinitions.add(requirementsToUpdate);
+ Either<Boolean, ResponseFormat> validateRequirementsResponseEither = requirementValidationUtilTest
+ .validateRequirements(requirementsDefinitions, component, true);
+ Assert.assertTrue(validateRequirementsResponseEither.isRight());
+ }
+
+ private RequirementDefinition createRequirement(String name, String capability, String node,
+ String relationship, String minOccurrences,
+ String maxOccurrences) {
+ RequirementDefinition requirementDefinition = new RequirementDefinition();
+ requirementDefinition.setName(name);
+ requirementDefinition.setCapability(capability);
+ requirementDefinition.setNode(node);
+ requirementDefinition.setRelationship(relationship);
+ requirementDefinition.setMaxOccurrences(maxOccurrences);
+ requirementDefinition.setMinOccurrences(minOccurrences);
+ requirementDefinition.setUniqueId("uniqueId");
+
+ return requirementDefinition;
+ }
+
+ private Resource createComponent() {
+ Resource resource = new Resource();
+ resource.setName("Resource1");
+ resource.addCategory("Network Layer 2-3", "Router");
+ resource.setDescription("My short description");
+ List<String> tgs = new ArrayList<>();
+ tgs.add("test");
+ tgs.add(resource.getName());
+ resource.setTags(tgs);
+
+ List<RequirementDefinition> requirementsDefinitions = new ArrayList<>();
+ requirementsDefinitions.add(createRequirement("ReqNameC", "reqDesc", "capType", "source1",
+ "0", "10"));
+ Map<String, List<RequirementDefinition>> requirementsMap = new HashMap<>();
+ requirementsMap.put("capTypeC", requirementsDefinitions);
+ resource.setRequirements(requirementsMap);
+
+ return resource;
+ }
+
+ private class RequirementValidationUtilTest extends RequirementValidation {
+
+ protected ResponseFormatManager getResponseFormatManager() {
+ return responseFormatManagerMock;
+ }
+ }
+} \ No newline at end of file
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/TypesUploadServletTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/TypesUploadServletTest.java
index e97f13c716..807ded8f5c 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/TypesUploadServletTest.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/TypesUploadServletTest.java
@@ -125,7 +125,7 @@ public class TypesUploadServletTest extends JerseyTest {
protected ResourceConfig configure() {
ResourceConfig resourceConfig = new ResourceConfig()
- .register(new TypesUploadServlet(importManager, null, null, null, null, null));
+ .register(new TypesUploadServlet(importManager, null, null, null, null, null, null));
resourceConfig.register(MultiPartFeature.class);
resourceConfig.register(new AbstractBinder() {
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
index ff6e0481f6..15a7fa72c7 100644
--- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
@@ -145,5 +145,18 @@ public enum ActionStatus {
//InterfaceLifeCycleType
- INTERFACE_LIFECYCLE_TYPES_NOT_FOUND
+ INTERFACE_LIFECYCLE_TYPES_NOT_FOUND,
+
+ //Capability related
+ CAPABILITY_NOT_FOUND, CAPABILITY_NAME_MANDATORY, CAPABILITY_TYPE_MANDATORY,CAPABILITY_NAME_ALREADY_IN_USE,
+ MAX_OCCURRENCES_SHOULD_BE_GREATER_THAN_MIN_OCCURRENCES, CAPABILITY_DELETION_NOT_ALLOWED_USED_IN_COMPOSITION,
+ CAPABILITY_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION,INVALID_CAPABILITY_NAME,
+
+ RELATIONSHIP_TYPE_ALREADY_EXIST, MISSING_RELATIONSHIP_TYPE, CAPABILITY_TYPE_CANNOT_BE_EMPTY,
+
+
+ //Requirement related
+ REQUIREMENT_NOT_FOUND, REQUIREMENT_NAME_MANDATORY, REQUIREMENT_CAPABILITY_MANDATORY,REQUIREMENT_NAME_ALREADY_IN_USE,
+ REQUIREMENT_DELETION_NOT_ALLOWED_USED_IN_COMPOSITION, REQUIREMENT_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION, INVALID_REQUIREMENT_NAME
+ ;
}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/GraphElementFactory.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/GraphElementFactory.java
index a6bb026a71..350909e66d 100644
--- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/GraphElementFactory.java
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/GraphElementFactory.java
@@ -172,6 +172,7 @@ public class GraphElementFactory {
element = clazz.cast(new InputValueData(properties));
break;
case RelationshipType:
+ element = clazz.cast(new RelationshipTypeData(properties));
break;
case LockNode:
element = clazz.cast(new GraphNodeLock(properties));
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/VertexTypeEnum.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/VertexTypeEnum.java
index 108d5e7201..9ba7048dd7 100644
--- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/VertexTypeEnum.java
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/VertexTypeEnum.java
@@ -33,7 +33,7 @@ public enum VertexTypeEnum {
INTERFACE_ARTIFACTS ("interface_artifacts", InterfaceDataDefinition.class),
INSTANCE_ARTIFACTS ("instance_artifacts", MapArtifactDataDefinition.class),
PROPERTIES ("properties", PropertyDataDefinition.class),
- CAPABILTIES ("capabilities", ListCapabilityDataDefinition.class),
+ CAPABILITIES ("capabilities", ListCapabilityDataDefinition.class),
CAPABILITIES_PROPERTIES ("capabilities_properties", MapPropertiesDataDefinition.class),
REQUIREMENTS ("requirements", ListRequirementDataDefinition.class),
ATTRIBUTES ("attributes", PropertyDataDefinition.class),
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphPropertiesDictionary.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphPropertiesDictionary.java
index 1da09e0cc5..b3f9037ea6 100644
--- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphPropertiesDictionary.java
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphPropertiesDictionary.java
@@ -21,161 +21,162 @@
package org.openecomp.sdc.be.dao.neo4j;
public enum GraphPropertiesDictionary {
-// field name class type unique indexed
+// field name class type unique indexed
// stored in graph index
- // Common
- LABEL ("nodeLabel", String.class, false, true),
- HEALTH_CHECK ("healthcheckis", String.class, true, true),
- // Resource
- NAME ("name", String.class, false, true),
- TOSCA_RESOURCE_NAME ("toscaResourceName", String.class, false, true),
- CATEGORY_NAME ("categoryName", String.class, false, true),
- VERSION ("version", String.class, false, true),
- CREATION_DATE ("creationDate", Long.class, false, false),
- LAST_UPDATE_DATE ("modificationDate", Long.class, false, false),
- IS_HIGHEST_VERSION ("highestVersion", Boolean.class, false, true),
- IS_ABSTRACT ("abstract", Boolean.class, false, true),
- DESCRIPTION ("description", String.class, false, false),
- UNIQUE_ID ("uid", String.class, true, true),
- STATE ("state", String.class, false, true),
- TYPE ("type", String.class, false, true),
- REQUIRED ("required", Boolean.class, false, false),
- DEFAULT_VALUE ("defaultValue", String.class, false, false),
- CONSTRAINTS ("constraints", String.class, false, false),
- CONTACT_ID ("contactId", String.class, false, false),
- VENDOR_NAME ("vendorName", String.class, false, false),
- VENDOR_RELEASE ("vendorRelease", String.class, false, false),
- CONFORMANCE_LEVEL ("conformanceLevel", String.class, false, false),
- ICON ("icon", String.class, false, false),
- TAGS ("tags", String.class, false, false),
- UUID ("uuid", String.class, false, true),
- COST ("cost", String.class, false, false),
- LICENSE_TYPE ("licenseType", String.class, false, false),
- NORMALIZED_NAME ("normalizedName", String.class, false, true),
- SYSTEM_NAME ("systemName", String.class, false, true),
- IS_DELETED ("deleted", Boolean.class, false, true),
- RESOURCE_TYPE ("resourceType", String.class, false, true),
- ENTRY_SCHEMA ("entry_schema", String.class, false, false),
- CSAR_UUID ("csarUuid", String.class, false, true),
- CSAR_VERSION ("csarVersion", String.class, false, true),
- IMPORTED_TOSCA_CHECKSUM ("importedToscaChecksum", String.class, false, true),
- GENERATED ("generated", Boolean.class, false, false),
- // User
- USERID ("userId", String.class, true, true),
- EMAIL ("email", String.class, false, false),
- FIRST_NAME ("firstName", String.class, false, false),
- LAST_NAME ("lastName", String.class, false, false),
- ROLE ("role", String.class, false, true),
- USER_STATUS ("status", String.class, false, true),
- VALID_SOURCE_TYPES ("validSourceTypes", String.class, false, false),
- NODE ("node", String.class, false, false),
- VALUE ("value", String.class, false, false),
- HIDDEN ("Hidden", Boolean.class, false, false),
- PROPERTIES ("properties", String.class, false, false),
- POSITION_X ("positionX", String.class, false, false),
- POSITION_Y ("positionY", String.class, false, false),
- RELATIONSHIP_TYPE ("relationshipType", String.class, false, false),
- ARTIFACT_TYPE ("artifactType", String.class, false, true),
- ARTIFACT_REF ("artifactRef", String.class, false, false),
- ARTIFACT_REPOSITORY ("artifactRepository", String.class, false, false),
- ARTIFACT_CHECKSUM ("artifactChecksum", String.class, false, false),
- CREATOR ("creator", String.class, false, false),
- CREATOR_ID ("creatorId", String.class, false, false),
- LAST_UPDATER ("lastUpdater", String.class, false, false),
- CREATOR_FULL_NAME ("creatorFullName", String.class, false, false),
- UPDATER_FULL_NAME ("updaterFullName", String.class, false, false),
- ES_ID ("esId", String.class, false, false),
- ARTIFACT_LABEL ("artifactLabel", String.class, false, true),
- ARTIFACT_DISPLAY_NAME("artifactDisplayName", String.class, false, true),
- INSTANCE_COUNTER ("instanceCounter", Integer.class, false, false),
- PROJECT_CODE ("projectCode", String.class, false, false),
- DISTRIBUTION_STATUS ("distributionStatus", String.class, false, false),
- IS_VNF ("isVNF", Boolean.class, false, false),
- LAST_LOGIN_TIME ("lastLoginTime", Long.class, false, true),
- ATTRIBUTE_COUNTER ("attributeCounter", Integer.class, false, false),
- INPUT_COUNTER ("inputCounter", Integer.class, false, false),
- PROPERTY_COUNTER ("propertyCounter", Integer.class, false, false),
- API_URL ("apiUrl", String.class, false, false),
- SERVICE_API ("serviceApi", Boolean.class, false, true),
- ADDITIONAL_INFO_PARAMS ("additionalInfo", String.class, false, false),
- ADDITIONAL_INFO_ID_TO_KEY ("idToKey", String.class, false, false),
- ARTIFACT_GROUP_TYPE ("artifactGroupType", String.class, false, true),
- ARTIFACT_TIMEOUT ("timeout", Integer.class, false, false),
- IS_ACTIVE ("isActive", Boolean.class, false, true),
- PROPERTY_VALUE_RULES ("propertyValueRules", String.class, false, false),
- //authantication
- CONSUMER_NAME ("consumerName", String.class, true, true),
- CONSUMER_PASSWORD ("consumerPassword", String.class, false, false),
- CONSUMER_SALT ("consumerSalt", String.class, false, false),
- CONSUMER_LAST_AUTHENTICATION_TIME ("consumerLastAuthenticationTime", Long.class, false, false),
- CONSUMER_DETAILS_LAST_UPDATED_TIME ("consumerDetailsLastupdatedtime", Long.class, false, false),
- LAST_MODIFIER_USER_ID("lastModfierUserId", String.class, false, false),
- ARTIFACT_VERSION ("artifactVersion", String.class, false, false),
- ARTIFACT_UUID ("artifactUUID", String.class, false, false),
- PAYLOAD_UPDATE_DATE ("payloadUpdateDate", Long.class, false, false),
- HEAT_PARAMS_UPDATE_DATE ("heatParamsUpdateDate",Long.class, false, false),
- //product
- FULL_NAME ("fullName", String.class, false, true),
- //was changed as part of migration from 1602 to 1602 ( in 1602 was defined as unique. it's problem to reconfigure the index )
- CONSTANT_UUID ("constantUuidNew", String.class, false, true),
- CONTACTS ("contacts", String.class, false, false),
- //categorys
- ICONS ("icons", String.class, false, false),
- //relation
- CAPABILITY_OWNER_ID ("capOwnerId", String.class, false, false),
- REQUIREMENT_OWNER_ID ("reqOwnerId", String.class, false, false),
- CAPABILITY_ID ("capabiltyId", String.class, false, false),
- REQUIREMENT_ID ("requirementId", String.class, false, false),
- PROPERTY_ID ("propertyId", String.class, false, false),
- PROPERTY_NAME ("propertyName", String.class, false, false),
- //component instance
- ORIGIN_TYPE ("originType", String.class, false, false),
- //requirement & capabilty
- MIN_OCCURRENCES ("minOccurrences", String.class, false, false),
- MAX_OCCURRENCES ("maxOccurrences", String.class, false, false),
- //Data type
- DERIVED_FROM ("derivedFrom", String.class, false, false),
- MEMBERS ("members", String.class, false, false),
- TARGETS ("targets ", String.class, false, false),
- METADATA ("metadata", String.class, false, false),
- INVARIANT_UUID ("invariantUuid", String.class, false, true),
- IS_BASE ("isBase", Boolean.class, false, true),
- GROUP_UUID ("groupUuid", String.class, false, true),
- STATUS ("status", String.class, false, false),
- FUNCTIONAL_MENU ("functionalMenu", String.class, false, false),
- REQUIRED_ARTIFACTS ("requiredArtifacts", String.class, false, false),
- CUSTOMIZATION_UUID ("customizationUUID", String.class, false, false),
- IS_ARCHIVED ("isArchived", Boolean.class, false, true),
- IS_VSP_ARCHIVED ("isVspArchived", Boolean.class, false, true),
- ARCHIVE_TIME ("archiveTime", Long.class, false, true);
+ // Common
+ LABEL("nodeLabel", String.class, false, true),
+ HEALTH_CHECK("healthcheckis", String.class, true, true),
+ // Resource
+ NAME("name", String.class, false, true),
+ TOSCA_RESOURCE_NAME("toscaResourceName", String.class, false, true),
+ CATEGORY_NAME("categoryName", String.class, false, true),
+ VERSION("version", String.class, false, true),
+ CREATION_DATE("creationDate", Long.class, false, false),
+ LAST_UPDATE_DATE("modificationDate", Long.class, false, false),
+ IS_HIGHEST_VERSION("highestVersion", Boolean.class, false, true),
+ IS_ABSTRACT("abstract", Boolean.class, false, true),
+ DESCRIPTION("description", String.class, false, false),
+ UNIQUE_ID("uid", String.class, true, true),
+ STATE("state", String.class, false, true),
+ TYPE("type", String.class, false, true),
+ REQUIRED("required", Boolean.class, false, false),
+ DEFAULT_VALUE("defaultValue", String.class, false, false),
+ CONSTRAINTS("constraints", String.class, false, false),
+ CONTACT_ID("contactId", String.class, false, false),
+ VENDOR_NAME("vendorName", String.class, false, false),
+ VENDOR_RELEASE("vendorRelease", String.class, false, false),
+ CONFORMANCE_LEVEL("conformanceLevel", String.class, false, false),
+ ICON("icon", String.class, false, false),
+ TAGS("tags", String.class, false, false),
+ UUID("uuid", String.class, false, true),
+ COST("cost", String.class, false, false),
+ LICENSE_TYPE("licenseType", String.class, false, false),
+ NORMALIZED_NAME("normalizedName", String.class, false, true),
+ SYSTEM_NAME("systemName", String.class, false, true),
+ IS_DELETED("deleted", Boolean.class, false, true),
+ RESOURCE_TYPE("resourceType", String.class, false, true),
+ ENTRY_SCHEMA("entry_schema", String.class, false, false),
+ CSAR_UUID("csarUuid", String.class, false, true),
+ CSAR_VERSION("csarVersion", String.class, false, true),
+ IMPORTED_TOSCA_CHECKSUM("importedToscaChecksum", String.class, false, true),
+ GENERATED("generated", Boolean.class, false, false),
+ // User
+ USERID("userId", String.class, true, true),
+ EMAIL("email", String.class, false, false),
+ FIRST_NAME("firstName", String.class, false, false),
+ LAST_NAME("lastName", String.class, false, false),
+ ROLE("role", String.class, false, true),
+ USER_STATUS("status", String.class, false, true),
+ VALID_SOURCE_TYPES("validSourceTypes", String.class, false, false),
+ VALID_TARGET_TYPES("validTargetTypes", String.class, false, false),
+ NODE("node", String.class, false, false),
+ VALUE("value", String.class, false, false),
+ HIDDEN("Hidden", Boolean.class, false, false),
+ PROPERTIES("properties", String.class, false, false),
+ POSITION_X("positionX", String.class, false, false),
+ POSITION_Y("positionY", String.class, false, false),
+ RELATIONSHIP_TYPE("relationshipType", String.class, false, false),
+ ARTIFACT_TYPE("artifactType", String.class, false, true),
+ ARTIFACT_REF("artifactRef", String.class, false, false),
+ ARTIFACT_REPOSITORY("artifactRepository", String.class, false, false),
+ ARTIFACT_CHECKSUM("artifactChecksum", String.class, false, false),
+ CREATOR("creator", String.class, false, false),
+ CREATOR_ID("creatorId", String.class, false, false),
+ LAST_UPDATER("lastUpdater", String.class, false, false),
+ CREATOR_FULL_NAME("creatorFullName", String.class, false, false),
+ UPDATER_FULL_NAME("updaterFullName", String.class, false, false),
+ ES_ID("esId", String.class, false, false),
+ ARTIFACT_LABEL("artifactLabel", String.class, false, true),
+ ARTIFACT_DISPLAY_NAME("artifactDisplayName", String.class, false, true),
+ INSTANCE_COUNTER("instanceCounter", Integer.class, false, false),
+ PROJECT_CODE("projectCode", String.class, false, false),
+ DISTRIBUTION_STATUS("distributionStatus", String.class, false, false),
+ IS_VNF("isVNF", Boolean.class, false, false),
+ LAST_LOGIN_TIME("lastLoginTime", Long.class, false, true),
+ ATTRIBUTE_COUNTER("attributeCounter", Integer.class, false, false),
+ INPUT_COUNTER("inputCounter", Integer.class, false, false),
+ PROPERTY_COUNTER("propertyCounter", Integer.class, false, false),
+ API_URL("apiUrl", String.class, false, false),
+ SERVICE_API("serviceApi", Boolean.class, false, true),
+ ADDITIONAL_INFO_PARAMS("additionalInfo", String.class, false, false),
+ ADDITIONAL_INFO_ID_TO_KEY("idToKey", String.class, false, false),
+ ARTIFACT_GROUP_TYPE("artifactGroupType", String.class, false, true),
+ ARTIFACT_TIMEOUT("timeout", Integer.class, false, false),
+ IS_ACTIVE("isActive", Boolean.class, false, true),
+ PROPERTY_VALUE_RULES("propertyValueRules", String.class, false, false),
+ //authantication
+ CONSUMER_NAME("consumerName", String.class, true, true),
+ CONSUMER_PASSWORD("consumerPassword", String.class, false, false),
+ CONSUMER_SALT("consumerSalt", String.class, false, false),
+ CONSUMER_LAST_AUTHENTICATION_TIME("consumerLastAuthenticationTime", Long.class, false, false),
+ CONSUMER_DETAILS_LAST_UPDATED_TIME("consumerDetailsLastupdatedtime", Long.class, false, false),
+ LAST_MODIFIER_USER_ID("lastModfierUserId", String.class, false, false),
+ ARTIFACT_VERSION("artifactVersion", String.class, false, false),
+ ARTIFACT_UUID("artifactUUID", String.class, false, false),
+ PAYLOAD_UPDATE_DATE("payloadUpdateDate", Long.class, false, false),
+ HEAT_PARAMS_UPDATE_DATE("heatParamsUpdateDate", Long.class, false, false),
+ //product
+ FULL_NAME("fullName", String.class, false, true),
+ //was changed as part of migration from 1602 to 1602 ( in 1602 was defined as unique. it's problem to reconfigure the index )
+ CONSTANT_UUID("constantUuidNew", String.class, false, true),
+ CONTACTS("contacts", String.class, false, false),
+ //categorys
+ ICONS("icons", String.class, false, false),
+ //relation
+ CAPABILITY_OWNER_ID("capOwnerId", String.class, false, false),
+ REQUIREMENT_OWNER_ID("reqOwnerId", String.class, false, false),
+ CAPABILITY_ID("capabiltyId", String.class, false, false),
+ REQUIREMENT_ID("requirementId", String.class, false, false),
+ PROPERTY_ID("propertyId", String.class, false, false),
+ PROPERTY_NAME("propertyName", String.class, false, false),
+ //component instance
+ ORIGIN_TYPE("originType", String.class, false, false),
+ //requirement & capabilty
+ MIN_OCCURRENCES("minOccurrences", String.class, false, false),
+ MAX_OCCURRENCES("maxOccurrences", String.class, false, false),
+ //Data type
+ DERIVED_FROM("derivedFrom", String.class, false, false),
+ MEMBERS("members", String.class, false, false),
+ TARGETS("targets ", String.class, false, false),
+ METADATA("metadata", String.class, false, false),
+ INVARIANT_UUID("invariantUuid", String.class, false, true),
+ IS_BASE("isBase", Boolean.class, false, true),
+ GROUP_UUID("groupUuid", String.class, false, true),
+ STATUS("status", String.class, false, false),
+ FUNCTIONAL_MENU("functionalMenu", String.class, false, false),
+ REQUIRED_ARTIFACTS("requiredArtifacts", String.class, false, false),
+ CUSTOMIZATION_UUID("customizationUUID", String.class, false, false),
+ IS_ARCHIVED("isArchived", Boolean.class, false, true),
+ IS_VSP_ARCHIVED("isVspArchived", Boolean.class, false, true),
+ ARCHIVE_TIME("archiveTime", Long.class, false, true);
- private final String property;
- private final Class clazz;
- private final boolean unique;
- private final boolean indexed;
-
- GraphPropertiesDictionary(String property,Class clazz, boolean unique,boolean indexed) {
- this.property = property;
- this.clazz = clazz;
- this.unique = unique;
- this.indexed = indexed;
- }
-
+ private final String property;
+ private final Class clazz;
+ private final boolean unique;
+ private final boolean indexed;
- public String getProperty() {
- return property;
- }
+ GraphPropertiesDictionary(String property, Class clazz, boolean unique, boolean indexed) {
+ this.property = property;
+ this.clazz = clazz;
+ this.unique = unique;
+ this.indexed = indexed;
+ }
- public Class getClazz() {
- return clazz;
- }
- public boolean isUnique() {
- return unique;
- }
+ public String getProperty() {
+ return property;
+ }
- public boolean isIndexed() {
- return indexed;
- }
+ public Class getClazz() {
+ return clazz;
+ }
+
+ public boolean isUnique() {
+ return unique;
+ }
+
+ public boolean isIndexed() {
+ return indexed;
+ }
}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/RelationshipTypeData.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/RelationshipTypeData.java
index 32a86e42ce..440cddad55 100644
--- a/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/RelationshipTypeData.java
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/RelationshipTypeData.java
@@ -57,13 +57,20 @@ public class RelationshipTypeData extends GraphNode {
relationshipTypeDataDefinition
.setDescription((String) properties.get(GraphPropertiesDictionary.DESCRIPTION.getProperty()));
- Type listType = new TypeToken<List<String>>() {
+ Type listSourceType = new TypeToken<List<String>>() {
}.getType();
List<String> validSourceTypesfromJson = getGson().fromJson(
- (String) properties.get(GraphPropertiesDictionary.VALID_SOURCE_TYPES.getProperty()), listType);
+ (String) properties.get(GraphPropertiesDictionary.VALID_SOURCE_TYPES.getProperty()), listSourceType);
relationshipTypeDataDefinition.setValidSourceTypes(validSourceTypesfromJson);
+ Type listTargetType = new TypeToken<List<String>>() {
+ }.getType();
+ List<String> validTargetTypesfromJson = getGson().fromJson(
+ (String) properties.get(GraphPropertiesDictionary.VALID_TARGET_TYPES.getProperty()), listTargetType);
+
+ relationshipTypeDataDefinition.setValidTargetTypes(validTargetTypesfromJson);
+
// relationshipTypeDataDefinition.setValidSourceTypes((List<String>)
// properties.get(GraphPropertiesDictionary.VALID_SOURCE_TYPES
// .getProperty()));
@@ -98,6 +105,9 @@ public class RelationshipTypeData extends GraphNode {
addIfExists(map, GraphPropertiesDictionary.VALID_SOURCE_TYPES,
relationshipTypeDataDefinition.getValidSourceTypes());
+ addIfExists(map, GraphPropertiesDictionary.VALID_TARGET_TYPES,
+ relationshipTypeDataDefinition.getValidTargetTypes());
+
addIfExists(map, GraphPropertiesDictionary.CREATION_DATE, relationshipTypeDataDefinition.getCreationTime());
addIfExists(map, GraphPropertiesDictionary.LAST_UPDATE_DATE,
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipTypeDefinition.java
new file mode 100644
index 0000000000..5b03d0ce1b
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipTypeDefinition.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.openecomp.sdc.be.model;
+
+import org.openecomp.sdc.be.datatypes.elements.RelationshipInstDataDefinition;
+import org.openecomp.sdc.be.resources.data.RelationshipTypeData;
+
+import java.util.Map;
+
+/**
+ * Specifies the capabilities that the Node Type exposes.
+ */
+public class RelationshipTypeDefinition extends RelationshipInstDataDefinition {
+
+ private String derivedFrom;
+
+ private Map<String, PropertyDefinition> properties;
+
+ public RelationshipTypeDefinition() {
+ super();
+ }
+
+ public RelationshipTypeDefinition(RelationshipInstDataDefinition p) {
+ super(p);
+ }
+
+ public RelationshipTypeDefinition(RelationshipTypeData relationshipTypeData) {
+ this.setUniqueId(relationshipTypeData.getUniqueId());
+ this.setType(relationshipTypeData.getRelationshipTypeDataDefinition().getType());
+ this.setDescription(relationshipTypeData.getRelationshipTypeDataDefinition().getDescription());
+ this.setValidSourceTypes(relationshipTypeData.getRelationshipTypeDataDefinition().getValidSourceTypes());
+ }
+
+ public String getDerivedFrom() {
+ return derivedFrom;
+ }
+
+ public void setDerivedFrom(String derivedFrom) {
+ this.derivedFrom = derivedFrom;
+ }
+
+ public Map<String, PropertyDefinition> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(Map<String, PropertyDefinition> properties) {
+ this.properties = properties;
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + " [ derivedFrom=" + derivedFrom + ", properties=" + properties + " ]";
+ }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeType.java
index 7ac941e5e2..4babd5d4a8 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeType.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeType.java
@@ -34,9 +34,6 @@ public class NodeType extends ToscaElement{
private List<String> derivedFrom;
private List<String> derivedList;
private Map<String, PropertyDataDefinition> attributes;
- private Map<String, ListCapabilityDataDefinition> capabilties;
- private Map<String, MapPropertiesDataDefinition> capabiltiesProperties;
- private Map<String, ListRequirementDataDefinition> requirements;
private Map<String, InterfaceDataDefinition> interfaceArtifacts;
public List<String> getDerivedList() {
@@ -63,30 +60,6 @@ public class NodeType extends ToscaElement{
this.attributes = attributes;
}
- public Map<String, ListCapabilityDataDefinition> getCapabilties() {
- return capabilties;
- }
-
- public void setCapabilties(Map<String, ListCapabilityDataDefinition> capabilties) {
- this.capabilties = capabilties;
- }
-
- public Map<String, ListRequirementDataDefinition> getRequirements() {
- return requirements;
- }
-
- public void setRequirements(Map<String, ListRequirementDataDefinition> requirements) {
- this.requirements = requirements;
- }
-
- public Map<String, MapPropertiesDataDefinition> getCapabiltiesProperties() {
- return capabiltiesProperties;
- }
-
- public void setCapabiltiesProperties(Map<String, MapPropertiesDataDefinition> capabiltiesProperties) {
- this.capabiltiesProperties = capabiltiesProperties;
- }
-
public Map<String, InterfaceDataDefinition> getInterfaceArtifacts() {
return interfaceArtifacts;
}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElement.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElement.java
index 0f0c63f7fb..a18c75bca7 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElement.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/datamodel/ToscaElement.java
@@ -22,6 +22,9 @@ package org.openecomp.sdc.be.model.jsontitan.datamodel;
import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
@@ -45,6 +48,9 @@ public abstract class ToscaElement {
private Map<String, ArtifactDataDefinition> deploymentArtifacts;
private Map<String, AdditionalInfoParameterDataDefinition> additionalInformation;
private Map<String, PropertyDataDefinition> properties;
+ private Map<String, ListCapabilityDataDefinition> capabilities;
+ private Map<String, MapPropertiesDataDefinition> capabiltiesProperties;
+ private Map<String, ListRequirementDataDefinition> requirements;
protected ToscaElementTypeEnum toscaType;
// User
@@ -125,6 +131,30 @@ public abstract class ToscaElement {
this.allVersions = allVersions;
}
+ public Map<String, ListCapabilityDataDefinition> getCapabilities() {
+ return capabilities;
+ }
+
+ public void setCapabilities(Map<String, ListCapabilityDataDefinition> capabilities) {
+ this.capabilities = capabilities;
+ }
+
+ public Map<String, ListRequirementDataDefinition> getRequirements() {
+ return requirements;
+ }
+
+ public void setRequirements(Map<String, ListRequirementDataDefinition> requirements) {
+ this.requirements = requirements;
+ }
+
+ public Map<String, MapPropertiesDataDefinition> getCapabilitiesProperties() {
+ return capabiltiesProperties;
+ }
+
+ public void setCapabilitiesProperties(Map<String, MapPropertiesDataDefinition> capabiltiesProperties) {
+ this.capabiltiesProperties = capabiltiesProperties;
+ }
+
// metadata properties
// ----------------------------
public Object getMetadataValue(JsonPresentationFields name) {
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/BaseOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/BaseOperation.java
index 52801751cc..b18fb96e8e 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/BaseOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/BaseOperation.java
@@ -24,6 +24,7 @@ import com.thinkaurelius.titan.core.TitanVertex;
import fj.data.Either;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
@@ -1390,6 +1391,15 @@ public abstract class BaseOperation {
StorageOperationStatus status = StorageOperationStatus.OK;
String currKey = (String) toscaDataElement.getToscaPresentationValue(mapKeyField);
+
+ if(StringUtils.isEmpty(currKey) && toscaDataElement instanceof ListDataDefinition) {
+ ToscaDataDefinition toscaDataDefinition = ((ListDataDefinition<? extends ToscaDataDefinition>) toscaDataElement)
+ .getListToscaDataDefinition().get(0);
+ if(toscaDataDefinition != null) {
+ currKey = (String) toscaDataDefinition.getToscaPresentationValue(mapKeyField);
+ }
+ }
+
if (StringUtils.isEmpty(currKey)) {
CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add tosca data to tosca element {}. The key is empty. ");
status = StorageOperationStatus.BAD_REQUEST;
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperation.java
new file mode 100644
index 0000000000..a8337b6c4f
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperation.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.model.jsontitan.operations;
+
+import fj.data.Either;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
+import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
+import org.openecomp.sdc.be.model.CapabilityDefinition;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+@org.springframework.stereotype.Component("capabilities-operation")
+public class CapabilitiesOperation extends BaseOperation {
+ private static final Logger LOGGER = LoggerFactory.getLogger(CapabilitiesOperation.class);
+
+ public Either<List<CapabilityDefinition>, StorageOperationStatus> addCapabilities(
+ String componentId,
+ List<CapabilityDefinition> capabilityDefinitions) {
+ return addOrUpdateCapabilities(componentId, capabilityDefinitions, false);
+ }
+
+ public Either<List<CapabilityDefinition>, StorageOperationStatus> updateCapabilities(
+ String componentId,
+ List<CapabilityDefinition> capabilityDefinitions) {
+ return addOrUpdateCapabilities(componentId, capabilityDefinitions, true);
+ }
+
+ private Either<List<CapabilityDefinition>, StorageOperationStatus> addOrUpdateCapabilities(String componentId,
+ List<CapabilityDefinition> capabilityDefinitions,
+ boolean isUpdateAction) {
+ StorageOperationStatus statusRes = performUpdateToscaAction(isUpdateAction,
+ componentId, Collections
+ .singletonList(convertToListCapabilityDataDefinition(capabilityDefinitions)));
+ if (!statusRes.equals(StorageOperationStatus.OK)) {
+ titanDao.rollback();
+ LOGGER.error("Failed to find the parent capability of capability type {}."
+ + " status is {}", componentId, statusRes);
+ return Either.right(statusRes);
+ }
+ titanDao.commit();
+ return Either.left(capabilityDefinitions);
+ }
+
+ public StorageOperationStatus deleteCapabilities(Component component,
+ String capabilityIdToDelete) {
+ return deleteToscaDataElements(component.getUniqueId(),
+ EdgeLabelEnum.CAPABILITIES,
+ Collections.singletonList(capabilityIdToDelete));
+ }
+
+ private static ListCapabilityDataDefinition convertToListCapabilityDataDefinition(
+ List<CapabilityDefinition> capabilities) {
+ List<CapabilityDataDefinition> capabilityDefinitions = new ArrayList<>(capabilities);
+ return new ListCapabilityDataDefinition(capabilityDefinitions);
+ }
+
+ private StorageOperationStatus performUpdateToscaAction(boolean isUpdate,
+ String componentId,
+ List<ListCapabilityDataDefinition> toscaDataList) {
+ if (isUpdate) {
+ return updateToscaDataOfToscaElement(componentId, EdgeLabelEnum.CAPABILITIES,
+ VertexTypeEnum.CAPABILITIES, toscaDataList, JsonPresentationFields.TYPE);
+ } else {
+ return addToscaDataToToscaElement(componentId, EdgeLabelEnum.CAPABILITIES,
+ VertexTypeEnum.CAPABILITIES, toscaDataList, JsonPresentationFields.TYPE);
+ }
+ }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperation.java
index 95f518aace..7bd36eacd1 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTemplateOperation.java
@@ -668,58 +668,145 @@ public class NodeTemplateOperation extends BaseOperation {
return instInput;
}
+ private MapListCapabilityDataDefinition prepareCalculatedCapabiltyForTopologyTemplate(
+ Map<String, ListCapabilityDataDefinition> capabilities,
+ ComponentInstanceDataDefinition componentInstance,
+ MapListCapabilityDataDefinition calculatedCap) {
+ if (capabilities != null) {
+ MapListCapabilityDataDefinition allCalculatedCap =
+ new MapListCapabilityDataDefinition(calculatedCap);
+ populateCapability(capabilities, componentInstance, allCalculatedCap);
+ return allCalculatedCap;
+ }
+ return null;
+ }
+
+ private void populateCapability(Map<String, ListCapabilityDataDefinition> capabilities,
+ ComponentInstanceDataDefinition componentInstance,
+ MapListCapabilityDataDefinition allCalculatedCap) {
+ capabilities.forEach((key, value) -> {
+ List<CapabilityDataDefinition> listCapabilities = value.getListToscaDataDefinition()
+ .stream().map(CapabilityDataDefinition::new).collect(Collectors.toList());
+ listCapabilities.forEach(cap -> {
+ cap.setSource(componentInstance.getComponentUid());
+ cap.addToPath(componentInstance.getUniqueId());
+ cap.setOwnerId(componentInstance.getUniqueId());
+ cap.setOwnerName(componentInstance.getName());
+ cap.setLeftOccurrences(cap.getMaxOccurrences());
+ allCalculatedCap.add(key, cap);
+ });
+ });
+ }
+
+ private MapListRequirementDataDefinition prepareCalculatedRequirementForTopologyTemplate(
+ Map<String, ListRequirementDataDefinition> requirements,
+ ComponentInstanceDataDefinition componentInstance,
+ MapListRequirementDataDefinition calculatedReqs) {
+ if (requirements != null) {
+ MapListRequirementDataDefinition allCalculatedReq =
+ new MapListRequirementDataDefinition(calculatedReqs);
+
+ populateRequirement(requirements, componentInstance, allCalculatedReq);
+ return allCalculatedReq;
+ }
+ return null;
+ }
+ private void populateRequirement(Map<String, ListRequirementDataDefinition> requirements,
+ ComponentInstanceDataDefinition componentInstance,
+ MapListRequirementDataDefinition allCalculatedReq) {
+ requirements.forEach((key, value) -> {
+ List<RequirementDataDefinition> listRequirements = value.getListToscaDataDefinition()
+ .stream().map(RequirementDataDefinition::new).collect(Collectors.toList());
+ listRequirements.forEach(req -> {
+ req.setSource(componentInstance.getComponentUid());
+ req.addToPath(componentInstance.getUniqueId());
+ req.setOwnerId(componentInstance.getUniqueId());
+ req.setOwnerName(componentInstance.getName());
+ req.setLeftOccurrences(req.getMaxOccurrences());
+ allCalculatedReq.add(key, req);
+ });
+ });
+ }
+
+
+
private StorageOperationStatus addCalculatedCapReqFromTopologyTemplate(TopologyTemplate originTopologyTemplate, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
Map<String, MapListCapabilityDataDefinition> calculatedCapabilities = originTopologyTemplate.getCalculatedCapabilities();
+ MapListCapabilityDataDefinition allCalculatedCap = new MapListCapabilityDataDefinition();
if (calculatedCapabilities != null) {
- MapListCapabilityDataDefinition allCalculatedCap = new MapListCapabilityDataDefinition();
- calculatedCapabilities.entrySet().forEach(enntryPerInstance -> {
- Map<String, ListCapabilityDataDefinition> mapByType = enntryPerInstance.getValue().getMapToscaDataDefinition();
- mapByType.entrySet().forEach(entryPerType ->
- entryPerType.getValue().getListToscaDataDefinition().forEach(cap -> {
- cap.addToPath(componentInstance.getUniqueId());
- allCalculatedCap.add(entryPerType.getKey(), cap);
- }));
+ calculatedCapabilities.forEach((key1, value1) -> {
+ Map<String, ListCapabilityDataDefinition> mapByType = value1.getMapToscaDataDefinition();
+ mapByType.forEach((key, value) -> value.getListToscaDataDefinition().forEach(cap -> {
+ cap.addToPath(componentInstance.getUniqueId());
+ allCalculatedCap.add(key, cap);
+ }));
});
-
- StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES, allCalculatedCap,
- componentInstance.getUniqueId());
-
- if (calculatedResult != StorageOperationStatus.OK) {
- return calculatedResult;
+ }
+ MapListCapabilityDataDefinition allCaps;
+ Map<String, ListCapabilityDataDefinition> capabilities = originTopologyTemplate.getCapabilities();
+ if (MapUtils.isNotEmpty(capabilities)) {
+ allCaps = prepareCalculatedCapabiltyForTopologyTemplate(capabilities, componentInstance,
+ allCalculatedCap);
+ } else {
+ allCaps = new MapListCapabilityDataDefinition(allCalculatedCap);
+ }
+ if(!allCaps.isEmpty()) {
+ StorageOperationStatus calculatedCapabilitiesResult =
+ addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex,
+ EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES,
+ allCaps, componentInstance.getUniqueId());
+ if (calculatedCapabilitiesResult != StorageOperationStatus.OK) {
+ return calculatedCapabilitiesResult;
}
MapListCapabilityDataDefinition fullCalculatedCap = new MapListCapabilityDataDefinition();
- calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES, fullCalculatedCap, componentInstance.getUniqueId());
-
- if (calculatedResult != StorageOperationStatus.OK) {
- return calculatedResult;
+ calculatedCapabilitiesResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex,
+ EdgeLabelEnum.FULLFILLED_CAPABILITIES, VertexTypeEnum.FULLFILLED_CAPABILITIES,
+ fullCalculatedCap, componentInstance.getUniqueId());
+ if (calculatedCapabilitiesResult != StorageOperationStatus.OK) {
+ return calculatedCapabilitiesResult;
}
}
- Map<String, MapListRequirementDataDefinition> calculatedRequirements = originTopologyTemplate.getCalculatedRequirements();
+ Map<String, MapListRequirementDataDefinition> calculatedRequirements =
+ originTopologyTemplate.getCalculatedRequirements();
+ MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
if (calculatedRequirements != null) {
-
- MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
- calculatedRequirements.entrySet().forEach(enntryPerInstance -> {
- Map<String, ListRequirementDataDefinition> mapByType = enntryPerInstance.getValue().getMapToscaDataDefinition();
- mapByType.entrySet().forEach(entryPerType ->
- entryPerType.getValue().getListToscaDataDefinition().forEach(req -> {
- req.addToPath(componentInstance.getUniqueId());
- allCalculatedReq.add(entryPerType.getKey(), req);
- }));
+ calculatedRequirements.forEach((key, value) -> {
+ Map<String, ListRequirementDataDefinition> mapByType =
+ value.getMapToscaDataDefinition();
+ mapByType.forEach((key1, value1) -> value1.getListToscaDataDefinition().forEach(req -> {
+ req.addToPath(componentInstance.getUniqueId());
+ allCalculatedReq.add(key1, req);
+ }));
});
- StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS, allCalculatedReq,
- componentInstance.getUniqueId());
- if (calculatedResult != StorageOperationStatus.OK) {
- return calculatedResult;
+ }
+
+ MapListRequirementDataDefinition allReqs;
+ Map<String, ListRequirementDataDefinition> requirements = originTopologyTemplate.getRequirements();
+ if (MapUtils.isNotEmpty(requirements)) {
+ allReqs = prepareCalculatedRequirementForTopologyTemplate(requirements,
+ componentInstance, allCalculatedReq);
+ } else
+ allReqs = new MapListRequirementDataDefinition(allCalculatedReq);
+
+ if(!allReqs.isEmpty()) {
+ StorageOperationStatus calculatedRequirementResult =
+ addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex,
+ EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS,
+ allReqs, componentInstance.getUniqueId());
+ if (calculatedRequirementResult != StorageOperationStatus.OK) {
+ return calculatedRequirementResult;
}
MapListRequirementDataDefinition fullCalculatedReq = new MapListRequirementDataDefinition();
- calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS, fullCalculatedReq, componentInstance.getUniqueId());
- if (calculatedResult != StorageOperationStatus.OK) {
- return calculatedResult;
+ calculatedRequirementResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex,
+ EdgeLabelEnum.FULLFILLED_REQUIREMENTS, VertexTypeEnum.FULLFILLED_REQUIREMENTS,
+ fullCalculatedReq,
+ componentInstance.getUniqueId());
+ if (calculatedRequirementResult != StorageOperationStatus.OK) {
+ return calculatedRequirementResult;
}
}
-
Map<String, MapCapabilityProperty> calculatedCapabilitiesProperties = originTopologyTemplate.getCalculatedCapabilitiesProperties();
Map<String, MapPropertiesDataDefinition> updateKeyMap = new HashMap<>();
@@ -730,9 +817,27 @@ public class NodeTemplateOperation extends BaseOperation {
updateKeyMap.put(newKey, entry.getValue());
}
}
- MapCapabilityProperty mapCapabilityProperty = new MapCapabilityProperty(updateKeyMap);
- StorageOperationStatus calculatedResult = addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, mapCapabilityProperty,
- componentInstance.getUniqueId());
+ }
+ Map<String, MapPropertiesDataDefinition> capabilitiesProperties =
+ originTopologyTemplate.getCapabilitiesProperties();
+ Map<String, MapPropertiesDataDefinition> updateKeyMapCapabilitiesProperties;
+ if (MapUtils.isNotEmpty(capabilitiesProperties)) {
+ updateKeyMapCapabilitiesProperties = capabilitiesProperties.entrySet().stream()
+ .collect(Collectors.toMap(e -> createCapPropertyKey(e.getKey(),
+ componentInstance.getUniqueId()), Entry::getValue));
+ }
+ else {
+ updateKeyMapCapabilitiesProperties = new HashMap<>();
+ }
+ updateKeyMap.putAll(updateKeyMapCapabilitiesProperties);
+ MapCapabilityProperty mapCapabilityProperty = new MapCapabilityProperty(updateKeyMap);
+
+ if(MapUtils.isNotEmpty(capabilitiesProperties) || MapUtils.isNotEmpty(calculatedCapabilitiesProperties )) {
+ StorageOperationStatus calculatedResult =
+ addToscaDataDeepElementsBlockToToscaElement(updatedContainerVertex,
+ EdgeLabelEnum.CALCULATED_CAP_PROPERTIES,
+ VertexTypeEnum.CALCULATED_CAP_PROPERTIES, mapCapabilityProperty,
+ componentInstance.getUniqueId());
if (calculatedResult != StorageOperationStatus.OK) {
return calculatedResult;
}
@@ -857,7 +962,7 @@ public class NodeTemplateOperation extends BaseOperation {
*/
private StorageOperationStatus addCalculatedCapReqFromNodeType(NodeType originNodeType, ComponentInstanceDataDefinition componentInstance, GraphVertex updatedContainerVertex) {
- Map<String, ListCapabilityDataDefinition> capabilities = originNodeType.getCapabilties();
+ Map<String, ListCapabilityDataDefinition> capabilities = originNodeType.getCapabilities();
MapListCapabilityDataDefinition allCalculatedCap = prepareCalculatedCapabiltyForNodeType(capabilities, componentInstance);
StorageOperationStatus calculatedResult;
if (allCalculatedCap != null) {
@@ -867,7 +972,7 @@ public class NodeTemplateOperation extends BaseOperation {
return calculatedResult;
}
}
- Map<String, MapPropertiesDataDefinition> capabiltiesProperties = originNodeType.getCapabiltiesProperties();
+ Map<String, MapPropertiesDataDefinition> capabiltiesProperties = originNodeType.getCapabilitiesProperties();
if (capabiltiesProperties != null) {
Map<String, MapPropertiesDataDefinition> updateKeyMap = capabiltiesProperties.entrySet().stream().collect(Collectors.toMap(e -> createCapPropertyKey(e.getKey(), componentInstance.getUniqueId()), Entry::getValue));
MapCapabilityProperty mapCapabilityProperty = new MapCapabilityProperty(updateKeyMap);
@@ -918,17 +1023,7 @@ public class NodeTemplateOperation extends BaseOperation {
if (capabilities != null) {
MapListCapabilityDataDefinition allCalculatedCap = new MapListCapabilityDataDefinition();
- capabilities.entrySet().forEach(e -> {
- List<CapabilityDataDefinition> listCapabilities = e.getValue().getListToscaDataDefinition().stream().map(CapabilityDataDefinition::new).collect(Collectors.toList());
- listCapabilities.forEach(cap -> {
- cap.setSource(componentInstance.getComponentUid());
- cap.addToPath(componentInstance.getUniqueId());
- cap.setOwnerId(componentInstance.getUniqueId());
- cap.setOwnerName(componentInstance.getName());
- cap.setLeftOccurrences(cap.getMaxOccurrences());
- allCalculatedCap.add(e.getKey(), cap);
- });
- });
+ populateCapability(capabilities, componentInstance, allCalculatedCap);
return allCalculatedCap;
}
return null;
@@ -945,17 +1040,7 @@ public class NodeTemplateOperation extends BaseOperation {
if (requirements != null) {
MapListRequirementDataDefinition allCalculatedReq = new MapListRequirementDataDefinition();
- requirements.entrySet().forEach(e -> {
- List<RequirementDataDefinition> listRequirements = e.getValue().getListToscaDataDefinition().stream().map(RequirementDataDefinition::new).collect(Collectors.toList());
- listRequirements.forEach(req -> {
- req.setSource(componentInstance.getComponentUid());
- req.addToPath(componentInstance.getUniqueId());
- req.setOwnerId(componentInstance.getUniqueId());
- req.setOwnerName(componentInstance.getName());
- req.setLeftOccurrences(req.getMaxOccurrences());
- allCalculatedReq.add(e.getKey(), req);
- });
- });
+ populateRequirement(requirements, componentInstance, allCalculatedReq);
return allCalculatedReq;
}
return null;
@@ -1135,7 +1220,7 @@ public class NodeTemplateOperation extends BaseOperation {
requirementAndRelationshipPair.setId(relationshipInstData.getUniqueId());
CapabilityRequirementRelationship capReqRel = new CapabilityRequirementRelationship();
capReqRel.setRelation(requirementAndRelationshipPair);
- capReqRel.setCapability((CapabilityDataDefinition) associateRes.left().value().get(JsonPresentationFields.CAPAPILITY));
+ capReqRel.setCapability((CapabilityDataDefinition) associateRes.left().value().get(JsonPresentationFields.CAPABILITY));
capReqRel.setRequirement((RequirementDataDefinition) associateRes.left().value().get(JsonPresentationFields.REQUIREMENT));
relationshipsResult.add(capReqRel);
CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "update customization UUID for from CI {} and to CI {}", relation.getFromNode(), relation.getToNode());
@@ -1680,7 +1765,7 @@ public class NodeTemplateOperation extends BaseOperation {
CapabilityDataDefinition cap = iteratorCap.next();
if (cap.getUniqueId().equals(relationPair.getCapabilityUid()) && cap.getOwnerId().equals(relationPair.getCapabilityOwnerId())) {
capabilityForRelation = cap;
- capReqRelationship.put(JsonPresentationFields.CAPAPILITY, (T) capabilityForRelation);
+ capReqRelationship.put(JsonPresentationFields.CAPABILITY, (T) capabilityForRelation);
String leftOccurrences = cap.getLeftOccurrences();
if (leftOccurrences != null && !leftOccurrences.equals(CapabilityDataDefinition.MAX_OCCURRENCES)) {
Integer leftIntValue = Integer.parseInt(leftOccurrences);
@@ -1807,23 +1892,23 @@ public class NodeTemplateOperation extends BaseOperation {
return relationshipInstData;
}
- public StorageOperationStatus associateComponentInstancesToComponent(Component containerComponent, Map<ComponentInstance, Resource> resourcesInstancesMap, GraphVertex containerVertex, boolean allowDeleted) {
+ public <T extends Component> StorageOperationStatus associateComponentInstancesToComponent(Component containerComponent, Map<ComponentInstance, T> componentInstanceTMap, GraphVertex containerVertex, boolean allowDeleted) {
StorageOperationStatus result = null;
String containerId = containerComponent.getUniqueId();
Map<String, ComponentInstanceDataDefinition> instancesJsonData = null;
Either<GraphVertex, TitanOperationStatus> updateElement = null;
- if (!validateInstanceNames(resourcesInstancesMap)) {
+ if (!validateInstanceNames(componentInstanceTMap)) {
result = StorageOperationStatus.INCONSISTENCY;
}
- if (result == null && !validateInstanceNames(resourcesInstancesMap)) {
+ if (result == null && !validateInstanceNames(componentInstanceTMap)) {
result = StorageOperationStatus.INCONSISTENCY;
}
- if (result == null && !allowDeleted && !validateDeletedResources(resourcesInstancesMap)) {
+ if (result == null && !allowDeleted && !validateDeletedResources(componentInstanceTMap)) {
result = StorageOperationStatus.INCONSISTENCY;
}
if (result == null) {
- instancesJsonData = convertToComponentInstanceDataDefinition(resourcesInstancesMap, containerId);
+ instancesJsonData = convertToComponentInstanceDataDefinition(componentInstanceTMap, containerId);
}
if (result == null && MapUtils.isNotEmpty(instancesJsonData)) {
containerVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
@@ -1846,21 +1931,21 @@ public class NodeTemplateOperation extends BaseOperation {
return result;
}
- private Map<String, ComponentInstanceDataDefinition> convertToComponentInstanceDataDefinition(Map<ComponentInstance, Resource> resourcesInstancesMap, String containerId) {
+ private <T extends Component> Map<String, ComponentInstanceDataDefinition> convertToComponentInstanceDataDefinition(Map<ComponentInstance, T> componentInstanceTMap, String containerId) {
Map<String, ComponentInstanceDataDefinition> instances = new HashMap<>();
- for (Entry<ComponentInstance, Resource> entry : resourcesInstancesMap.entrySet()) {
+ for (Entry<ComponentInstance, T> entry : componentInstanceTMap.entrySet()) {
ComponentInstanceDataDefinition instance = buildComponentInstanceDataDefinition(entry.getKey(), containerId, null, true, ModelConverter.convertToToscaElement(entry.getValue()));
instances.put(instance.getUniqueId(), instance);
}
return instances;
}
- private boolean validateDeletedResources(Map<ComponentInstance, Resource> resourcesInstancesMap) {
+ private <T extends Component> boolean validateDeletedResources(Map<ComponentInstance, T> resourcesInstancesMap) {
boolean result = true;
- for (Resource resource : resourcesInstancesMap.values()) {
- if (resource.getIsDeleted() != null && resource.getIsDeleted()) {
- CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Component {} is already deleted. Cannot add component instance. ", resource.getName());
+ for (Component component : resourcesInstancesMap.values()) {
+ if (component.getIsDeleted() != null && component.getIsDeleted()) {
+ CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Component {} is already deleted. Cannot add component instance. ", component.getName());
result = false;
break;
}
@@ -1868,7 +1953,7 @@ public class NodeTemplateOperation extends BaseOperation {
return result;
}
- private boolean validateInstanceNames(Map<ComponentInstance, Resource> resourcesInstancesMap) {
+ private <T extends Component> boolean validateInstanceNames(Map<ComponentInstance, T> resourcesInstancesMap) {
boolean result = true;
Set<String> names = new HashSet<>();
for (ComponentInstance instance : resourcesInstancesMap.keySet()) {
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTypeOperation.java
index d9ced8c249..967fc16c49 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTypeOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeTypeOperation.java
@@ -289,7 +289,7 @@ public class NodeTypeOperation extends ToscaElementOperation {
private TitanOperationStatus setComponentCapPropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
Either<Map<String, MapPropertiesDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
if (result.isLeft()) {
- toscaElement.setCapabiltiesProperties(result.left().value());
+ toscaElement.setCapabilitiesProperties(result.left().value());
} else {
if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
return result.right().value();
@@ -317,7 +317,7 @@ public class NodeTypeOperation extends ToscaElementOperation {
private TitanOperationStatus setResourceCapabilitiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
Either<Map<String, ListCapabilityDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES);
if (result.isLeft()) {
- toscaElement.setCapabilties(result.left().value());
+ toscaElement.setCapabilities(result.left().value());
} else {
if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
return result.right().value();
@@ -448,7 +448,7 @@ public class NodeTypeOperation extends ToscaElementOperation {
}
Map<String, ListCapabilityDataDefinition> capabiltiesAll = dataFromDerived.left().value();
- Map<String, ListCapabilityDataDefinition> capabilties = nodeType.getCapabilties();
+ Map<String, ListCapabilityDataDefinition> capabilties = nodeType.getCapabilities();
if (capabilties != null) {
if (capabiltiesAll == null) {
capabiltiesAll = new HashMap<>();
@@ -483,7 +483,7 @@ public class NodeTypeOperation extends ToscaElementOperation {
});
});
if (!capabiltiesAll.isEmpty()) {
- Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILTIES, EdgeLabelEnum.CAPABILITIES, capabiltiesAll);
+ Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILITIES, EdgeLabelEnum.CAPABILITIES, capabiltiesAll);
if (assosiateElementToData.isRight()) {
return assosiateElementToData.right().value();
}
@@ -556,7 +556,7 @@ public class NodeTypeOperation extends ToscaElementOperation {
return dataFromDerived.right().value();
}
Map<String, MapPropertiesDataDefinition> propertiesAll = dataFromDerived.left().value();
- Map<String, MapPropertiesDataDefinition> capabiltiesProps = nodeType.getCapabiltiesProperties();
+ Map<String, MapPropertiesDataDefinition> capabiltiesProps = nodeType.getCapabilitiesProperties();
if (capabiltiesProps != null) {
capabiltiesProps.values().forEach(l -> {
if (l.getMapToscaDataDefinition() != null && l.getMapToscaDataDefinition().values() != null) {
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/RequirementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/RequirementOperation.java
new file mode 100644
index 0000000000..1fd37500bf
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/RequirementOperation.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.be.model.jsontitan.operations;
+
+import fj.data.Either;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
+import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.RequirementDefinition;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+@org.springframework.stereotype.Component("requirement-operation")
+public class RequirementOperation extends BaseOperation {
+ private static final Logger LOGGER = LoggerFactory.getLogger(RequirementOperation.class);
+
+ public Either<List<RequirementDefinition>, StorageOperationStatus> addRequirement(
+ String componentId,
+ List<RequirementDefinition> requirementDefinitions) {
+ return addOrUpdateRequirements( componentId, requirementDefinitions, false);
+ }
+
+ public Either<List<RequirementDefinition>, StorageOperationStatus> updateRequirement(
+ String componentId,
+ List<RequirementDefinition> requirementDefinitions) {
+ return addOrUpdateRequirements( componentId, requirementDefinitions, true);
+ }
+
+
+ private Either<List<RequirementDefinition>, StorageOperationStatus> addOrUpdateRequirements(String componentId,
+ List<RequirementDefinition> requirementDefinitions,
+ boolean isUpdateAction) {
+
+ StorageOperationStatus statusRes = performUpdateToscaAction(isUpdateAction,
+ componentId, Collections
+ .singletonList(convertToListRequirementDataDefinition(requirementDefinitions)));
+ if (!statusRes.equals(StorageOperationStatus.OK)) {
+ titanDao.rollback();
+ LOGGER.error("Failed to find the parent capability of capability type {}."
+ + " status is {}", componentId, statusRes);
+ return Either.right(statusRes);
+ }
+ titanDao.commit();
+ return Either.left(requirementDefinitions);
+ }
+
+ public StorageOperationStatus deleteRequirements(Component component,
+ String requirementToDelete) {
+ return deleteToscaDataElements(component.getUniqueId(),
+ EdgeLabelEnum.REQUIREMENTS, Collections.singletonList(requirementToDelete));
+ }
+
+ private static ListRequirementDataDefinition convertToListRequirementDataDefinition(
+ List<RequirementDefinition> requirementDefinitions) {
+ List<RequirementDataDefinition> requirementDataDefinitions =
+ new ArrayList<>(requirementDefinitions);
+ return new ListRequirementDataDefinition(requirementDataDefinitions);
+ }
+
+ private StorageOperationStatus performUpdateToscaAction(boolean isUpdate,
+ String componentId, List<ListRequirementDataDefinition> toscaDataList) {
+ if (isUpdate) {
+ return updateToscaDataOfToscaElement(componentId, EdgeLabelEnum.REQUIREMENTS,
+ VertexTypeEnum.REQUIREMENTS, toscaDataList, JsonPresentationFields.CAPABILITY);
+ } else {
+ return addToscaDataToToscaElement(componentId, EdgeLabelEnum.REQUIREMENTS,
+ VertexTypeEnum.REQUIREMENTS, toscaDataList, JsonPresentationFields.CAPABILITY);
+ }
+ }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java
index 38c6b5d16e..095425748a 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java
@@ -50,6 +50,8 @@ import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.MapCapabilityProperty;
import org.openecomp.sdc.be.datatypes.elements.MapDataDefinition;
@@ -272,6 +274,15 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
return assosiateElementToData.right().value();
}
}
+ Map<String, ListCapabilityDataDefinition> capabilities = topologyTemplate.getCapabilities();
+ if(MapUtils.isNotEmpty(capabilities)) {
+ Either<GraphVertex, StorageOperationStatus> associateElementToData =
+ associateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILITIES,
+ EdgeLabelEnum.CAPABILITIES, capabilities);
+ if (associateElementToData.isRight()) {
+ return associateElementToData.right().value();
+ }
+ }
return StorageOperationStatus.OK;
}
@@ -291,6 +302,15 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
return assosiateElementToData.right().value();
}
}
+ Map<String, ListRequirementDataDefinition> requirements = topologyTemplate.getRequirements();
+ if(MapUtils.isNotEmpty(requirements)) {
+ Either<GraphVertex, StorageOperationStatus> associateElementToData =
+ associateElementToData(nodeTypeVertex, VertexTypeEnum.REQUIREMENTS,
+ EdgeLabelEnum.REQUIREMENTS, requirements);
+ if (associateElementToData.isRight()) {
+ return associateElementToData.right().value();
+ }
+ }
return StorageOperationStatus.OK;
}
@@ -905,6 +925,15 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
return result.right().value();
}
}
+ Either<Map<String, ListRequirementDataDefinition>, TitanOperationStatus> requirementResult =
+ getDataFromGraph(componentV, EdgeLabelEnum.REQUIREMENTS);
+ if (requirementResult.isLeft()) {
+ toscaElement.setRequirements(requirementResult.left().value());
+ } else {
+ if (requirementResult.right().value() != TitanOperationStatus.NOT_FOUND) {
+ return requirementResult.right().value();
+ }
+ }
return TitanOperationStatus.OK;
}
@@ -926,6 +955,15 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
return result.right().value();
}
}
+ Either<Map<String, ListCapabilityDataDefinition>, TitanOperationStatus> capabilitiesResult =
+ getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES);
+ if (capabilitiesResult.isLeft()) {
+ toscaElement.setCapabilities(capabilitiesResult.left().value());
+ } else {
+ if (capabilitiesResult.right().value() != TitanOperationStatus.NOT_FOUND) {
+ return capabilitiesResult.right().value();
+ }
+ }
return TitanOperationStatus.OK;
}
@@ -1139,6 +1177,21 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
}
+ status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT,
+ EdgeLabelEnum.REQUIREMENTS);
+ if (status != TitanOperationStatus.OK) {
+ log.debug("Failed to disassociate requirements for {} error {}",
+ toscaElementVertex.getUniqueId(), status);
+ Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+ }
+ status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT,
+ EdgeLabelEnum.CAPABILITIES);
+ if (status != TitanOperationStatus.OK) {
+ log.debug("Failed to disassociate capabilities for {} error {}",
+ toscaElementVertex.getUniqueId(), status);
+ Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+ }
+
toscaElementVertex.getVertex().remove();
log.trace("Tosca element vertex for {} was removed", toscaElementVertex.getUniqueId());
@@ -1444,5 +1497,32 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
filter.setIgnoreRequirements(false);
return filter;
}
+ public void updateCapReqOwnerId(String componentId, TopologyTemplate toscaElement) {
+ GraphVertex toscaElementV = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse)
+ .left().on(this::throwStorageException);
+ updateCapOwnerId(toscaElement, componentId);
+ updateReqOwnerId(toscaElement, componentId);
+ topologyTemplateOperation
+
+ .updateFullToscaData(toscaElementV, EdgeLabelEnum.CAPABILITIES,
+ VertexTypeEnum.CAPABILITIES, toscaElement.getCapabilities());
+ topologyTemplateOperation
+ .updateFullToscaData(toscaElementV, EdgeLabelEnum.REQUIREMENTS,
+ VertexTypeEnum.REQUIREMENTS, toscaElement.getRequirements());
+ }
+
+ private void updateCapOwnerId(ToscaElement toscaElement, String ownerId) {
+ if(MapUtils.isNotEmpty(toscaElement.getCapabilities())) {
+ toscaElement.getCapabilities().values().stream().flatMap(listCapDef -> listCapDef.getListToscaDataDefinition().stream())
+ .forEach(capabilityDefinition -> capabilityDefinition.setOwnerId(ownerId));
+ }
+ }
+
+ private void updateReqOwnerId(ToscaElement toscaElement, String ownerId) {
+ if(MapUtils.isNotEmpty(toscaElement.getRequirements())) {
+ toscaElement.getRequirements().values().stream().flatMap(listReqDef -> listReqDef.getListToscaDataDefinition().stream())
+ .forEach(requirementDefinition -> requirementDefinition.setOwnerId(ownerId));
+ }
+ }
}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java
index d8a4fc4af1..a69c80cd36 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java
@@ -2546,5 +2546,8 @@ public class ToscaOperationFacade {
}
return Either.left(parentComponents);
}
-
+ public void updateCapReqOwnerId(String componentId) {
+ topologyTemplateOperation
+ .updateCapReqOwnerId(componentId, getTopologyTemplate(componentId));
+ }
}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java
index 5e40bd57e7..6fbd7adc98 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java
@@ -152,6 +152,8 @@ public class ModelConverter {
convertServiceInterfaces(topologyTemplate, service);
convertNodeFiltersComponents(topologyTemplate, service);
+ setCapabilitiesToComponent(topologyTemplate, service);
+ setRequirementsToComponent(topologyTemplate, service);
return service;
}
@@ -200,6 +202,8 @@ public class ModelConverter {
convertPolicies(topologyTemplate, resource);
convertNodeFiltersComponents(topologyTemplate, resource);
convertProperties(topologyTemplate, resource);
+ setCapabilitiesToComponent(topologyTemplate, resource);
+ setRequirementsToComponent(topologyTemplate, resource);
}
convertArtifacts(toscaElement, resource);
convertAdditionalInformation(toscaElement, resource);
@@ -401,6 +405,7 @@ public class ModelConverter {
}
private static void convertCapabilities(Component component, TopologyTemplate topologyTemplate) {
+ convertTopologyTemplateCapabilities(component, topologyTemplate);
if(componentInstancesCapabilitiesExist(component) || groupsCapabilitiesExist(component)){
topologyTemplate.setCalculatedCapabilities(new HashMap<>());
topologyTemplate.setCalculatedCapabilitiesProperties(new HashMap<>());
@@ -418,6 +423,65 @@ public class ModelConverter {
}
}
+ private static void convertTopologyTemplateCapabilities(Component component, ToscaElement toscaElement) {
+ Map<String, List<CapabilityDefinition>> capabilities = component.getCapabilities();
+
+ Map<String, ListCapabilityDataDefinition> toscaCapMap = new HashMap<>();
+ Map<String, MapPropertiesDataDefinition> toscaCapPropMap = new HashMap<>();
+
+ if (MapUtils.isNotEmpty(capabilities )) {
+ capabilities.forEach((s, caps) -> {
+ if (CollectionUtils.isNotEmpty(caps)) {
+ List<CapabilityDataDefinition> capList = caps.stream().filter(capabilityDefinition -> capabilityDefinition.getOwnerId()
+ .equals(component.getUniqueId())).map(CapabilityDataDefinition::new).collect(Collectors.toList());
+
+ populateCapabilityMap(toscaCapMap, toscaCapPropMap, s, caps, capList);
+ }
+ }
+ );
+
+ toscaElement.setCapabilities(toscaCapMap);
+ toscaElement.setCapabilitiesProperties(toscaCapPropMap);
+ }
+ }
+ private static void populateCapabilityMap(Map<String, ListCapabilityDataDefinition> toscaCapMap,
+ Map<String, MapPropertiesDataDefinition> toscaCapPropMap,
+ String s, List<CapabilityDefinition> caps,
+ List<CapabilityDataDefinition> capList) {
+ ListCapabilityDataDefinition listCapabilityDataDefinition = new ListCapabilityDataDefinition(capList);
+ toscaCapMap.put(s, listCapabilityDataDefinition);
+
+ for (CapabilityDefinition cap : caps) {
+ List<ComponentInstanceProperty> capPrps = cap.getProperties();
+ if (CollectionUtils.isNotEmpty(capPrps)) {
+ MapPropertiesDataDefinition dataToCreate = new MapPropertiesDataDefinition();
+ for (ComponentInstanceProperty cip : capPrps) {
+ dataToCreate.put(cip.getName(), new PropertyDataDefinition(cip));
+ }
+ toscaCapPropMap.put(s + CAP_PROP_DELIM + cap.getName(), dataToCreate);
+ }
+ }
+ }
+
+ private static void convertTopologyTemplateRequirements(Component component, ToscaElement toscaElement) {
+ Map<String, List<RequirementDefinition>> requirements = component.getRequirements();
+
+ Map<String, ListRequirementDataDefinition> toscaReqMap = new HashMap<>();
+
+ if (MapUtils.isNotEmpty(requirements )) {
+ requirements.forEach((s, reqs)-> {
+ if (CollectionUtils.isNotEmpty(reqs)) {
+ List<RequirementDataDefinition> reqList = reqs.stream().filter(requirementDefinition -> requirementDefinition.getOwnerId()
+ .equals(component.getUniqueId())).map(RequirementDataDefinition::new).collect(Collectors.toList());
+
+ ListRequirementDataDefinition listRequirementDataDefinition = new ListRequirementDataDefinition(reqList);
+ toscaReqMap.put(s, listRequirementDataDefinition);
+ }
+ }
+ );
+ toscaElement.setRequirements(toscaReqMap);
+ }
+ }
private static void convertComponentInstancesCapabilities(Component component, TopologyTemplate topologyTemplate) {
if (componentInstancesCapabilitiesExist(component)) {
component.getComponentInstances()
@@ -510,6 +574,7 @@ public class ModelConverter {
private static void convertRequirements(Component component, TopologyTemplate topologyTemplate) {
+ convertTopologyTemplateRequirements(component, topologyTemplate);
if (component.getRequirements() != null && component.getComponentInstances() != null) {
topologyTemplate.setCalculatedRequirements(new HashMap<>());
for (ComponentInstance instance : component.getComponentInstances()) {
@@ -759,27 +824,13 @@ public class ModelConverter {
if (caps != null && !caps.isEmpty()) {
List<CapabilityDataDefinition> capList = caps.stream().map(CapabilityDataDefinition::new).collect(Collectors.toList());
- ListCapabilityDataDefinition listCapabilityDataDefinition = new ListCapabilityDataDefinition(capList);
- toscaCapMap.put(s, listCapabilityDataDefinition);
-
- for (CapabilityDefinition cap : caps) {
- List<ComponentInstanceProperty> capPrps = cap.getProperties();
- if (capPrps != null && !capPrps.isEmpty()) {
-
- MapPropertiesDataDefinition dataToCreate = new MapPropertiesDataDefinition();
- for (ComponentInstanceProperty cip : capPrps) {
- dataToCreate.put(cip.getName(), new PropertyDataDefinition(cip));
- }
-
- toscaCapPropMap.put(s + CAP_PROP_DELIM + cap.getName(), dataToCreate);
- }
- }
+ populateCapabilityMap(toscaCapMap, toscaCapPropMap, s, caps, capList);
}
}
);
- toscaElement.setCapabilties(toscaCapMap);
- toscaElement.setCapabiltiesProperties(toscaCapPropMap);
+ toscaElement.setCapabilities(toscaCapMap);
+ toscaElement.setCapabilitiesProperties(toscaCapPropMap);
}
}
@@ -812,8 +863,8 @@ public class ModelConverter {
}
private static void convertCapabilities(NodeType toscaElement, Component component) {
- Map<String, ListCapabilityDataDefinition> toscaCapabilities = toscaElement.getCapabilties();
- Map<String, MapPropertiesDataDefinition> toscaCapPropMap = toscaElement.getCapabiltiesProperties();
+ Map<String, ListCapabilityDataDefinition> toscaCapabilities = toscaElement.getCapabilities();
+ Map<String, MapPropertiesDataDefinition> toscaCapPropMap = toscaElement.getCapabilitiesProperties();
Map<String, List<CapabilityDefinition>> compCap = new HashMap<>();
if (toscaCapabilities == null || toscaCapabilities.isEmpty())
@@ -1295,7 +1346,76 @@ public class ModelConverter {
}
}
- private static void setCapabilitiesToComponentAndGroups(TopologyTemplate topologyTemplate, Component component) {
+ private static void setCapabilitiesToComponent(TopologyTemplate topologyTemplate, Component component) {
+ Map<String, ListCapabilityDataDefinition> capabilities = topologyTemplate.getCapabilities();
+ Map<String, List<CapabilityDefinition>> componentCapabilities = component.getCapabilities();
+ if(MapUtils.isNotEmpty(capabilities)) {
+ if(componentCapabilities == null) {
+ componentCapabilities = new HashMap<>();
+ }
+ componentCapabilities.putAll(groupCapabilityByType(capabilities));
+ component.setCapabilities(componentCapabilities);
+ }
+
+ }
+ private static Map<String, List<CapabilityDefinition>> groupCapabilityByType(Map<String,
+ ListCapabilityDataDefinition> capabilities) {
+ Map<String, List<CapabilityDefinition>> groupedCapabilities = new HashMap<>();
+
+ Set<String> typesSet = new HashSet<>();
+ List<CapabilityDefinition> allCapabilityDefinitions = new ArrayList<>();
+ for (Entry<String, ListCapabilityDataDefinition> capabilitiesEntry : capabilities.entrySet()) {
+ typesSet.addAll( capabilitiesEntry.getValue().getListToscaDataDefinition()
+ .stream().map(CapabilityDataDefinition::getType).collect(Collectors.toSet()));
+
+ allCapabilityDefinitions.addAll(capabilitiesEntry.getValue().getListToscaDataDefinition()
+ .stream().map(CapabilityDefinition::new).collect(Collectors.toList()));
+ }
+
+ for(String capType : typesSet) {
+ groupedCapabilities.put(capType, allCapabilityDefinitions.stream()
+ .filter(capabilityDefinition -> capabilityDefinition.getType()
+ .equals(capType)).collect(Collectors.toList()));
+ }
+ return groupedCapabilities;
+ }
+
+ private static void setRequirementsToComponent(TopologyTemplate topologyTemplate, Component component) {
+ Map<String, ListRequirementDataDefinition> requirements = topologyTemplate.getRequirements();
+ Map<String, List<RequirementDefinition>> componentRequirements = component.getRequirements();
+ if(MapUtils.isNotEmpty(requirements)) {
+ if(componentRequirements == null) {
+ componentRequirements = new HashMap<>();
+ }
+ componentRequirements.putAll(groupRequirementByType(requirements));
+ component.setRequirements(componentRequirements);
+ }
+ }
+
+ private static Map<String, List<RequirementDefinition>> groupRequirementByType(Map<String,
+ ListRequirementDataDefinition> requirements) {
+ Map<String, List<RequirementDefinition>> groupedRequirement = new HashMap<>();
+
+ Set<String> typesSet = new HashSet<>();
+ List<RequirementDefinition> allRequirements = new ArrayList<>();
+ for (Entry<String, ListRequirementDataDefinition> requirementsEntry : requirements.entrySet()) {
+ typesSet.addAll( requirementsEntry.getValue().getListToscaDataDefinition()
+ .stream().map(RequirementDataDefinition::getCapability).collect(Collectors.toSet()));
+
+ allRequirements.addAll(requirementsEntry.getValue().getListToscaDataDefinition()
+ .stream().map(RequirementDefinition::new).collect(Collectors.toList()));
+ }
+
+ for(String capType : typesSet) {
+ groupedRequirement.put(capType, allRequirements.stream().filter(requirementDefinition ->
+ requirementDefinition.getCapability().equals(capType)).collect(Collectors.toList()));
+ }
+ return groupedRequirement;
+
+ }
+
+
+ private static void setCapabilitiesToComponentAndGroups(TopologyTemplate topologyTemplate, Component component) {
Map<String, MapCapabilityProperty> calculatedCapProperties = topologyTemplate.getCalculatedCapabilitiesProperties();
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java
index 7f8e07e2c3..4316f733a7 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java
@@ -21,8 +21,11 @@
package org.openecomp.sdc.be.model.operations.api;
import fj.data.Either;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
+import java.util.Map;
+
public interface ICapabilityTypeOperation {
/**
@@ -43,4 +46,5 @@ public interface ICapabilityTypeOperation {
public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId);
public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId, boolean inTransaction);
+ Either<Map<String, CapabilityTypeDefinition>, TitanOperationStatus> getAllCapabilityTypes();
}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java
index 97f3e80e2a..3a4a2725e2 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java
@@ -42,6 +42,7 @@ import org.openecomp.sdc.common.log.wrappers.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -58,6 +59,10 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab
}
private static final Logger log = Logger.getLogger(CapabilityTypeOperation.class.getName());
+ private static final String DATA_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS = "Data type {} cannot be found in graph."
+ + " status is {}";
+ private static final String FAILED_TO_FETCH_PROPERTIES_OF_DATA_TYPE = "Failed to fetch properties of data type {}";
+
/**
* FOR TEST ONLY
@@ -268,10 +273,15 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab
CapabilityTypeData ctData = capabilityTypesRes.left().value();
CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition(ctData.getCapabilityTypeDataDefinition());
- TitanOperationStatus propertiesStatus = fillProperties(uniqueId, capabilityTypeDefinition);
- if (propertiesStatus != TitanOperationStatus.OK) {
+ Either<Map<String, PropertyDefinition>, TitanOperationStatus> propertiesStatus =
+ OperationUtils.fillProperties(uniqueId, propertyOperation, NodeTypeEnum.CapabilityType);
+ if (propertiesStatus.isRight() && propertiesStatus.right().value() != TitanOperationStatus.OK) {
log.error("Failed to fetch properties of capability type {}", uniqueId);
- return Either.right(propertiesStatus);
+ return Either.right(propertiesStatus.right().value());
+ }
+
+ if (propertiesStatus.isLeft()) {
+ capabilityTypeDefinition.setProperties(propertiesStatus.left().value());
}
Either<ImmutablePair<CapabilityTypeData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, GraphEdgeLabels.DERIVED_FROM,
@@ -295,24 +305,6 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab
return result;
}
- private TitanOperationStatus fillProperties(String uniqueId, CapabilityTypeDefinition capabilityTypeDefinition) {
-
- Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = propertyOperation.findPropertiesOfNode(NodeTypeEnum.CapabilityType, uniqueId);
- if (findPropertiesOfNode.isRight()) {
- TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value();
- log.debug("After looking for properties of vertex {}. status is {}", uniqueId, titanOperationStatus);
- if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) {
- return TitanOperationStatus.OK;
- } else {
- return titanOperationStatus;
- }
- } else {
- Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value();
- capabilityTypeDefinition.setProperties(properties);
- return TitanOperationStatus.OK;
- }
- }
-
public Either<Boolean, StorageOperationStatus> isCapabilityTypeDerivedFrom(String childCandidateType, String parentCandidateType) {
return derivedFromOperation.isTypeDerivedFrom(childCandidateType, parentCandidateType, null, NodeTypeEnum.CapabilityType, CapabilityTypeData.class, t -> t.getCapabilityTypeDataDefinition().getType());
}
@@ -417,4 +409,107 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab
public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId) {
return getCapabilityType(uniqueId, true);
}
+ public Either<Map<String, CapabilityTypeDefinition>, TitanOperationStatus> getAllCapabilityTypes() {
+
+ Map<String, CapabilityTypeDefinition> capabilityTypes = new HashMap<>();
+ Either<Map<String, CapabilityTypeDefinition>, TitanOperationStatus> result = Either.left(capabilityTypes);
+
+ Either<List<CapabilityTypeData>, TitanOperationStatus> getAllCapabilityTypes =
+ titanGenericDao.getByCriteria(NodeTypeEnum.CapabilityType, null, CapabilityTypeData.class);
+ if (getAllCapabilityTypes.isRight()) {
+ TitanOperationStatus status = getAllCapabilityTypes.right().value();
+ if (status != TitanOperationStatus.NOT_FOUND) {
+ return Either.right(status);
+ } else {
+ return result;
+ }
+ }
+
+ List<CapabilityTypeData> list = getAllCapabilityTypes.left().value();
+ if (list != null) {
+
+ log.trace("Number of data types to load is {}", list.size());
+ //Set properties
+ for (CapabilityTypeData capabilityTypeData : list) {
+
+ log.trace("Going to fetch data type {}. uid is {}",
+ capabilityTypeData.getCapabilityTypeDataDefinition().getType(),
+ capabilityTypeData.getUniqueId());
+ Either<CapabilityTypeDefinition, TitanOperationStatus> capabilityTypesByUid =
+ getAndAddPropertiesANdDerivedFrom(capabilityTypeData.getUniqueId(), capabilityTypes);
+ if (capabilityTypesByUid.isRight()) {
+ TitanOperationStatus status = capabilityTypesByUid.right().value();
+ if (status == TitanOperationStatus.NOT_FOUND) {
+ status = TitanOperationStatus.INVALID_ID;
+ }
+ return Either.right(status);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private void fillDerivedFrom(String uniqueId, CapabilityTypeDefinition capabilityType) {
+ log.debug("#fillDerivedFrom - fetching capability type {} derived node", capabilityType.getType());
+ derivedFromOperation.getDerivedFromChild(uniqueId, NodeTypeEnum.CapabilityType, CapabilityTypeData.class)
+ .right()
+ .bind(this::handleDerivedFromNotExist)
+ .left()
+ .map(derivedFrom -> setDerivedFrom(capabilityType, derivedFrom));
+
+ }
+
+ private Either<CapabilityTypeData, StorageOperationStatus> handleDerivedFromNotExist(StorageOperationStatus err) {
+ if (err == StorageOperationStatus.NOT_FOUND) {
+ return Either.left(null);
+ }
+ return Either.right(err);
+ }
+
+ private CapabilityTypeData setDerivedFrom(CapabilityTypeDefinition capabilityTypeDefinition, CapabilityTypeData derivedFrom) {
+ if (derivedFrom != null) {
+ capabilityTypeDefinition.setDerivedFrom(derivedFrom.getCapabilityTypeDataDefinition().getType());
+ }
+ return derivedFrom;
+ }
+
+ private Either<CapabilityTypeDefinition, TitanOperationStatus> getAndAddPropertiesANdDerivedFrom(
+ String uniqueId, Map<String, CapabilityTypeDefinition> capabilityTypeDefinitionMap) {
+ if (capabilityTypeDefinitionMap.containsKey(uniqueId)) {
+ return Either.left(capabilityTypeDefinitionMap.get(uniqueId));
+ }
+
+ Either<CapabilityTypeData, TitanOperationStatus> capabilityTypesRes =
+ titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId,
+ CapabilityTypeData.class);
+
+ if (capabilityTypesRes.isRight()) {
+ TitanOperationStatus status = capabilityTypesRes.right().value();
+ log.debug(DATA_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS, uniqueId, status);
+ return Either.right(status);
+ }
+
+ CapabilityTypeData ctData = capabilityTypesRes.left().value();
+ CapabilityTypeDefinition capabilityTypeDefinition =
+ new CapabilityTypeDefinition(ctData.getCapabilityTypeDataDefinition());
+
+ Either<Map<String, PropertyDefinition>, TitanOperationStatus> propertiesStatus =
+ OperationUtils.fillProperties(uniqueId, propertyOperation, NodeTypeEnum.CapabilityType);
+
+ if (propertiesStatus.isRight() && propertiesStatus.right().value() != TitanOperationStatus.OK) {
+ log.error(FAILED_TO_FETCH_PROPERTIES_OF_DATA_TYPE, uniqueId);
+ return Either.right(propertiesStatus.right().value());
+ }
+
+ if (propertiesStatus.isLeft()) {
+ capabilityTypeDefinition.setProperties(propertiesStatus.left().value());
+ }
+
+ fillDerivedFrom(uniqueId, capabilityTypeDefinition);
+
+ capabilityTypeDefinitionMap.put(capabilityTypeDefinition.getType(), capabilityTypeDefinition);
+
+ return Either.left(capabilityTypeDefinition);
+ }
}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OperationUtils.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OperationUtils.java
index dcaafe55ac..a06d342d26 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OperationUtils.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OperationUtils.java
@@ -1,15 +1,23 @@
package org.openecomp.sdc.be.model.operations.impl;
+import fj.data.Either;
import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.model.PropertyDefinition;
import org.openecomp.sdc.be.model.operations.StorageException;
+import org.openecomp.sdc.common.log.wrappers.Logger;
import org.springframework.stereotype.Component;
+import java.util.Map;
+
@Component
public class OperationUtils {
private final TitanDao titanDao;
+ private static final Logger logger = Logger.getLogger(OperationUtils.class.getName());
+
public OperationUtils(TitanDao titanDao) {
this.titanDao = titanDao;
}
@@ -18,4 +26,23 @@ public class OperationUtils {
titanDao.rollback();
throw new StorageException(status);
}
+
+ static Either<Map<String, PropertyDefinition>, TitanOperationStatus> fillProperties(String uniqueId,
+ PropertyOperation propertyOperation,
+ NodeTypeEnum nodeTypeEnum) {
+
+ Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode =
+ propertyOperation.findPropertiesOfNode(nodeTypeEnum, uniqueId);
+ if (findPropertiesOfNode.isRight()) {
+ TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value();
+ logger.debug("After looking for properties of vertex {}. status is {}", uniqueId, titanOperationStatus);
+ if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) {
+ return Either.right(TitanOperationStatus.OK);
+ } else {
+ return Either.right(titanOperationStatus);
+ }
+ } else {
+ return Either.left(findPropertiesOfNode.left().value());
+ }
+ }
}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RelationshipTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RelationshipTypeOperation.java
new file mode 100644
index 0000000000..13ad7a798c
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RelationshipTypeOperation.java
@@ -0,0 +1,513 @@
+package org.openecomp.sdc.be.model.operations.impl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import fj.data.Either;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
+import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.RelationshipTypeDefinition;
+import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.resources.data.PropertyData;
+import org.openecomp.sdc.be.resources.data.RelationshipTypeData;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component("relationship-type-operation")
+public class RelationshipTypeOperation extends AbstractOperation {
+
+ @Autowired
+ private PropertyOperation propertyOperation;
+
+ @Autowired
+ private DerivedFromOperation derivedFromOperation;
+
+ private static final Logger logger = Logger.getLogger(RelationshipTypeOperation.class.getName());
+ private static final String RELATIONSHIP_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS = "Relationship type {} cannot be "
+ + "found in "
+ + "graph status is {}";
+ private static final String FAILED_TO_FETCH_PROPERTIES_OF_RELATIONSHIP_TYPE = "Failed to fetch properties of "
+ + "relationship type {}";
+
+ public Either<RelationshipTypeDefinition, TitanOperationStatus> getRelationshipTypeByName(String name) {
+ String uid = UniqueIdBuilder.buildRelationshipTypeUid(name);
+ Either<RelationshipTypeDefinition, TitanOperationStatus> result = getRelationshipTypeByUid(uid);
+ if (result.isRight()) {
+ TitanOperationStatus status = result.right().value();
+ if (status != TitanOperationStatus.NOT_FOUND) {
+ logger.error("Failed to get information on relationship type {} status is {}", name, status);
+ }
+ return Either.right(status);
+ }
+ return Either.left(result.left().value());
+ }
+
+ public Either<RelationshipTypeDefinition, TitanOperationStatus> getRelationshipTypeByUid(String uniqueId) {
+
+ Either<RelationshipTypeDefinition, TitanOperationStatus> result;
+
+ Either<RelationshipTypeData, TitanOperationStatus> relationshipTypesRes =
+ titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(
+ NodeTypeEnum.RelationshipType), uniqueId, RelationshipTypeData.class);
+
+ if (relationshipTypesRes.isRight()) {
+ TitanOperationStatus status = relationshipTypesRes.right().value();
+ logger.debug("Relationship type {} cannot be found in graph. status is {}", uniqueId, status);
+ return Either.right(status);
+ }
+
+ RelationshipTypeData relationshipTypeData = relationshipTypesRes.left().value();
+ RelationshipTypeDefinition relationshipTypeDefinition =
+ new RelationshipTypeDefinition(relationshipTypeData.getRelationshipTypeDataDefinition());
+
+ Either<Map<String, PropertyDefinition>, TitanOperationStatus> propertiesStatus =
+ OperationUtils.fillProperties(uniqueId, propertyOperation, NodeTypeEnum.RelationshipType);
+ if (propertiesStatus.isRight() && propertiesStatus.right().value() != TitanOperationStatus.OK) {
+ logger.error("Failed to fetch properties of relationship type {}", uniqueId);
+ return Either.right(propertiesStatus.right().value());
+ }
+
+ if (propertiesStatus.isLeft()) {
+ relationshipTypeDefinition.setProperties(propertiesStatus.left().value());
+ }
+
+ Either<ImmutablePair<RelationshipTypeData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao
+ .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RelationshipType), uniqueId,
+ GraphEdgeLabels.DERIVED_FROM,
+ NodeTypeEnum.RelationshipType, RelationshipTypeData.class);
+ logger.debug("After retrieving DERIVED_FROM node of {}. status is {}", uniqueId, parentNode);
+ if (parentNode.isRight()) {
+ TitanOperationStatus titanOperationStatus = parentNode.right().value();
+ if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) {
+ logger.error("Failed to find the parent relationship of relationship type {}. status is {}", uniqueId,
+ titanOperationStatus);
+ result = Either.right(titanOperationStatus);
+ return result;
+ }
+ } else {
+ // derived from node was found
+ ImmutablePair<RelationshipTypeData, GraphEdge> immutablePair = parentNode.left().value();
+ RelationshipTypeData parentCT = immutablePair.getKey();
+ relationshipTypeDefinition.setDerivedFrom(parentCT.getRelationshipTypeDataDefinition().getType());
+ }
+ result = Either.left(relationshipTypeDefinition);
+
+ return result;
+ }
+
+ private Either<RelationshipTypeDefinition, StorageOperationStatus> validateUpdateProperties(
+ RelationshipTypeDefinition relationshipTypeDefinition) {
+ TitanOperationStatus error = null;
+ if (MapUtils.isNotEmpty(relationshipTypeDefinition.getProperties())
+ && relationshipTypeDefinition.getDerivedFrom() != null) {
+ Either<Map<String, PropertyDefinition>, TitanOperationStatus> allPropertiesRes =
+ getAllRelationshipTypePropertiesFromAllDerivedFrom(relationshipTypeDefinition.getDerivedFrom());
+ if (allPropertiesRes.isRight() && !TitanOperationStatus.NOT_FOUND.equals(allPropertiesRes.right().value())) {
+ error = allPropertiesRes.right().value();
+ logger.debug("Couldn't fetch derived from property nodes for relationship type {}, error: {}",
+ relationshipTypeDefinition.getType(), error);
+ }
+ error = getTitanOperationStatus(relationshipTypeDefinition, error, allPropertiesRes);
+ }
+ if (error == null) {
+ return Either.left(relationshipTypeDefinition);
+ }
+ return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
+ }
+
+ private TitanOperationStatus getTitanOperationStatus(RelationshipTypeDefinition relationshipTypeDefinition,
+ TitanOperationStatus error,
+ Either<Map<String, PropertyDefinition>, TitanOperationStatus> allPropertiesRes) {
+ if (error == null && !allPropertiesRes.left().value().isEmpty()) {
+ Map<String, PropertyDefinition> derivedFromProperties = allPropertiesRes.left().value();
+ relationshipTypeDefinition.getProperties().entrySet().stream()
+ .filter(e -> derivedFromProperties.containsKey(e.getKey()) && e.getValue().getType() == null)
+ .forEach(e -> e.getValue().setType(derivedFromProperties.get(e.getKey()).getType()));
+
+ List<PropertyDefinition>
+ properties = new ArrayList<>(relationshipTypeDefinition.getProperties().values());
+ Either<List<PropertyDefinition>, TitanOperationStatus> validatePropertiesRes =
+ propertyOperation.validatePropertiesUniqueness(allPropertiesRes.left().value(), properties);
+ if (validatePropertiesRes.isRight()) {
+ error = validatePropertiesRes.right().value();
+ }
+ }
+ return error;
+ }
+
+ private Either<Map<String, PropertyDefinition>, TitanOperationStatus> getAllRelationshipTypePropertiesFromAllDerivedFrom(
+ String firstParentType) {
+ return propertyOperation.getAllTypePropertiesFromAllDerivedFrom(firstParentType, NodeTypeEnum.RelationshipType,
+ RelationshipTypeData.class);
+ }
+
+ public Either<RelationshipTypeDefinition, StorageOperationStatus> addRelationshipType(
+ RelationshipTypeDefinition relationshipTypeDefinition,
+ boolean inTransaction) {
+
+ Either<RelationshipTypeDefinition, StorageOperationStatus> result = null;
+
+ try {
+ Either<RelationshipTypeDefinition, StorageOperationStatus> validationRes =
+ validateUpdateProperties(relationshipTypeDefinition);
+ if (validationRes.isRight()) {
+ logger.error(
+ "#addRelationshipType - One or all properties of relationship type {} not valid. status is {}"
+ , relationshipTypeDefinition, validationRes.right().value());
+ return validationRes;
+ }
+
+ Either<RelationshipTypeData, StorageOperationStatus> eitherStatus =
+ addRelationshipTypeToGraph(relationshipTypeDefinition);
+
+ result = eitherStatus.left()
+ .map(RelationshipTypeData::getUniqueId)
+ .left()
+ .bind(uniqueId -> getRelationshipType(uniqueId, inTransaction));
+
+ if (result.isLeft()) {
+ logger.debug("#addRelationshipType - The returned RelationshipTypeDefinition is {}",
+ result.left().value());
+ }
+
+ return result;
+ } finally {
+ if (!inTransaction) {
+ if (result == null || result.isRight()) {
+ logger.error("#addRelationshipType - Going to execute rollback on graph.");
+ titanGenericDao.rollback();
+ } else {
+ logger.debug("#addRelationshipType - Going to execute commit on graph.");
+ titanGenericDao.commit();
+ }
+ }
+ }
+ }
+
+ public Either<RelationshipTypeDefinition, StorageOperationStatus> getRelationshipType(String uniqueId,
+ boolean inTransaction) {
+
+ Either<RelationshipTypeDefinition, StorageOperationStatus> result;
+ try {
+
+ Either<RelationshipTypeDefinition, TitanOperationStatus> ctResult = this.getRelationshipTypeByUid(uniqueId);
+
+ if (ctResult.isRight()) {
+ TitanOperationStatus status = ctResult.right().value();
+ if (status != TitanOperationStatus.NOT_FOUND) {
+ logger.error("Failed to retrieve information on relationship type {}. status is {}", uniqueId,
+ status);
+ }
+ result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value()));
+ return result;
+ }
+
+ result = Either.left(ctResult.left().value());
+
+ return result;
+ } finally {
+ if (!inTransaction) {
+ logger.debug("Going to execute commit on graph.");
+ titanGenericDao.commit();
+ }
+ }
+ }
+
+ private Either<RelationshipTypeData, StorageOperationStatus> addRelationshipTypeToGraph(
+ RelationshipTypeDefinition relationshipTypeDefinition) {
+
+ logger.debug("Got relationship type {}", relationshipTypeDefinition);
+
+ String ctUniqueId = UniqueIdBuilder.buildRelationshipTypeUid(relationshipTypeDefinition.getType());
+ RelationshipTypeData relationshipTypeData = buildRelationshipTypeData(relationshipTypeDefinition, ctUniqueId);
+
+ logger.debug("Before adding relationship type to graph. relationshipTypeData = {}", relationshipTypeData);
+ Either<RelationshipTypeData, TitanOperationStatus> createCTResult =
+ titanGenericDao.createNode(relationshipTypeData, RelationshipTypeData.class);
+ logger.debug("After adding relationship type to graph. status is = {}", createCTResult);
+
+ if (createCTResult.isRight()) {
+ TitanOperationStatus operationStatus = createCTResult.right().value();
+ logger.error("Failed to relationship type {} to graph. status is {}", relationshipTypeDefinition.getType(),
+ operationStatus);
+ return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus));
+ }
+
+ RelationshipTypeData resultCTD = createCTResult.left().value();
+ Map<String, PropertyDefinition> propertiesMap = relationshipTypeDefinition.getProperties();
+ Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToRelationshipType = propertyOperation
+ .addPropertiesToElementType(resultCTD.getUniqueId(), NodeTypeEnum.RelationshipType, propertiesMap);
+ if (addPropertiesToRelationshipType.isRight()) {
+ logger.error("Failed add properties {} to relationship {}", propertiesMap,
+ relationshipTypeDefinition.getType());
+ return Either.right(DaoStatusConverter
+ .convertTitanStatusToStorageStatus(addPropertiesToRelationshipType.right().value()));
+ }
+
+ return addDerivedFromRelation(relationshipTypeDefinition, ctUniqueId)
+ .left()
+ .map(updatedDerivedFrom -> createCTResult.left().value());
+
+
+ }
+
+ private RelationshipTypeData buildRelationshipTypeData(RelationshipTypeDefinition relationshipTypeDefinition,
+ String ctUniqueId) {
+
+ RelationshipTypeData relationshipTypeData = new RelationshipTypeData(relationshipTypeDefinition);
+
+ relationshipTypeData.getRelationshipTypeDataDefinition().setUniqueId(ctUniqueId);
+ Long creationDate = relationshipTypeData.getRelationshipTypeDataDefinition().getCreationTime();
+ if (creationDate == null) {
+ creationDate = System.currentTimeMillis();
+ }
+ relationshipTypeData.getRelationshipTypeDataDefinition().setCreationTime(creationDate);
+ relationshipTypeData.getRelationshipTypeDataDefinition().setModificationTime(creationDate);
+ return relationshipTypeData;
+ }
+
+ private Either<GraphRelation, StorageOperationStatus> addDerivedFromRelation(
+ RelationshipTypeDefinition relationshipTypeDefinition,
+ String relationshipTypeUniqueId) {
+ String derivedFrom = relationshipTypeDefinition.getDerivedFrom();
+ if (derivedFrom == null) {
+ return Either.left(null);
+ }
+ logger.debug(
+ "#addDerivedFromRelation - adding derived from relation between relationship type {} to its parent "
+ + "{}", relationshipTypeDefinition.getType(), derivedFrom);
+ return getRelationshipTypeByType(derivedFrom)
+ .right()
+ .map(DaoStatusConverter::convertTitanStatusToStorageStatus)
+ .left()
+ .bind(derivedFromRelationship -> derivedFromOperation.addDerivedFromRelation(relationshipTypeUniqueId,
+ derivedFromRelationship.getUniqueId(), NodeTypeEnum.RelationshipType));
+ }
+
+ private Either<RelationshipTypeDefinition, TitanOperationStatus> getRelationshipTypeByType(
+ String relationshipType) {
+ // Optimization: In case of Relationship Type its unique ID is the same as type
+ return getRelationshipTypeByUid(relationshipType);
+ }
+
+ public Either<RelationshipTypeDefinition, StorageOperationStatus> updateRelationshipType(
+ RelationshipTypeDefinition newRelationshipTypeDefinition,
+ RelationshipTypeDefinition oldRelationshipTypeDefinition, boolean inTransaction) {
+ logger.debug("updating relationship type {}", newRelationshipTypeDefinition.getType());
+ Either<RelationshipTypeDefinition, StorageOperationStatus> updateRelationshipEither = null;
+
+ try {
+ updateRelationshipEither =
+ updateRelationshipTypeOnGraph(newRelationshipTypeDefinition, oldRelationshipTypeDefinition);
+ } finally {
+ if (!inTransaction) {
+ if (updateRelationshipEither == null || updateRelationshipEither.isRight()) {
+ titanGenericDao.rollback();
+ } else {
+ titanGenericDao.commit();
+ }
+ }
+ }
+ return updateRelationshipEither;
+ }
+
+ private Either<RelationshipTypeDefinition, StorageOperationStatus> updateRelationshipTypeOnGraph(
+ RelationshipTypeDefinition newRelationshipTypeDefinition,
+ RelationshipTypeDefinition oldRelationshipTypeDefinition) {
+ updateRelationshipTypeData(newRelationshipTypeDefinition, oldRelationshipTypeDefinition);
+ return titanGenericDao
+ .updateNode(new RelationshipTypeData(newRelationshipTypeDefinition), RelationshipTypeData.class)
+ .right()
+ .map(DaoStatusConverter::convertTitanStatusToStorageStatus)
+ .left()
+ .bind(updatedNode -> updateRelationshipTypeProperties(newRelationshipTypeDefinition.getUniqueId(),
+ newRelationshipTypeDefinition.getProperties()))
+ .left()
+ .bind(updatedProperties -> updateRelationshipTypeDerivedFrom(newRelationshipTypeDefinition,
+ oldRelationshipTypeDefinition.getDerivedFrom()))
+ .left()
+ .map(updatedDerivedFrom -> newRelationshipTypeDefinition);
+ }
+
+ private Either<Map<String, PropertyData>, StorageOperationStatus> updateRelationshipTypeProperties(
+ String relationshipTypeId, Map<String, PropertyDefinition> properties) {
+ logger.debug(
+ "#updateRelationshipTypeProperties - updating relationship type properties for relationship type with "
+ + "id {}", relationshipTypeId);
+ return propertyOperation.deletePropertiesAssociatedToNode(NodeTypeEnum.RelationshipType, relationshipTypeId)
+ .left()
+ .bind(deleteProps -> addPropertiesToRelationshipType(relationshipTypeId, properties));
+ }
+
+ private Either<GraphRelation, StorageOperationStatus> updateRelationshipTypeDerivedFrom(
+ RelationshipTypeDefinition newRelationshipTypeDefinition, String currDerivedFromRelationshipType) {
+ String relationshipTypeId = newRelationshipTypeDefinition.getUniqueId();
+ logger.debug(
+ "#updateRelationshipTypeDerivedFrom - updating relationship derived from relation for relationship "
+ + "type with id {}. old derived type {}. new derived type {}", relationshipTypeId,
+ currDerivedFromRelationshipType, newRelationshipTypeDefinition.getDerivedFrom());
+ StorageOperationStatus deleteDerivedRelationStatus =
+ deleteDerivedFromRelationshipType(relationshipTypeId, currDerivedFromRelationshipType);
+ if (deleteDerivedRelationStatus != StorageOperationStatus.OK) {
+ return Either.right(deleteDerivedRelationStatus);
+ }
+ return addDerivedFromRelation(newRelationshipTypeDefinition, relationshipTypeId);
+ }
+
+ private void updateRelationshipTypeData(RelationshipTypeDefinition newRelationshipTypeDefinition,
+ RelationshipTypeDefinition oldRelationshipTypeDefinition) {
+ newRelationshipTypeDefinition.setUniqueId(oldRelationshipTypeDefinition.getUniqueId());
+ newRelationshipTypeDefinition.setCreationTime(oldRelationshipTypeDefinition.getCreationTime());
+ newRelationshipTypeDefinition.setModificationTime(System.currentTimeMillis());
+ }
+
+ private Either<Map<String, PropertyData>, StorageOperationStatus> addPropertiesToRelationshipType(
+ String relationshipTypeId, Map<String, PropertyDefinition> properties) {
+ logger.debug(
+ "#addPropertiesToRelationshipType - adding relationship type properties for relationship type with "
+ + "id {}", relationshipTypeId);
+ return propertyOperation
+ .addPropertiesToElementType(relationshipTypeId, NodeTypeEnum.RelationshipType, properties)
+ .right()
+ .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+ }
+
+ private StorageOperationStatus deleteDerivedFromRelationshipType(String relationshipTypeId,
+ String derivedFromType) {
+ if (derivedFromType == null) {
+ return StorageOperationStatus.OK;
+ }
+ logger.debug("#deleteDerivedFromRelationshipType - deleting derivedFrom relation for relationship type with id "
+ + "{} and its derived type {}", relationshipTypeId, derivedFromType);
+ return getRelationshipTypeByType(derivedFromType)
+ .either(derivedFromNode -> derivedFromOperation
+ .removeDerivedFromRelation(relationshipTypeId, derivedFromNode.getUniqueId(),
+ NodeTypeEnum.RelationshipType),
+ DaoStatusConverter::convertTitanStatusToStorageStatus);
+ }
+
+ public Either<Map<String, RelationshipTypeDefinition>, TitanOperationStatus> getAllRelationshipTypes() {
+
+ Map<String, RelationshipTypeDefinition> relationshipTypeDefinitionMap = new HashMap<>();
+ Either<Map<String, RelationshipTypeDefinition>, TitanOperationStatus> result = Either.left(relationshipTypeDefinitionMap);
+
+ Either<List<RelationshipTypeData>, TitanOperationStatus> getAllRelationshipTypes =
+ titanGenericDao.getByCriteria(NodeTypeEnum.RelationshipType, null, RelationshipTypeData.class);
+ if (getAllRelationshipTypes.isRight()) {
+ TitanOperationStatus status = getAllRelationshipTypes.right().value();
+ if (status != TitanOperationStatus.NOT_FOUND) {
+ return Either.right(status);
+ } else {
+ return result;
+ }
+ }
+
+ List<RelationshipTypeData> list = getAllRelationshipTypes.left().value();
+ if (list != null) {
+
+ logger.trace("Number of relationship types to load is {}", list.size());
+ //Set properties
+ Either<Map<String, RelationshipTypeDefinition>, TitanOperationStatus> status =
+ getMapTitanOperationStatusEither(relationshipTypeDefinitionMap, list);
+ if (status != null) {
+ return status;
+ }
+ }
+
+ return result;
+ }
+
+ private Either<Map<String, RelationshipTypeDefinition>, TitanOperationStatus> getMapTitanOperationStatusEither(
+ Map<String, RelationshipTypeDefinition> relationshipTypeDefinitionMap,
+ List<RelationshipTypeData> list) {
+ for (RelationshipTypeData relationshipTypeData : list) {
+
+ logger.trace("Going to fetch relationship type {}. uid is {}",
+ relationshipTypeData.getRelationshipTypeDataDefinition().getType(),
+ relationshipTypeData.getUniqueId());
+ Either<RelationshipTypeDefinition, TitanOperationStatus> relationshipTypesByUid =
+ getAndAddPropertiesANdDerivedFrom(relationshipTypeData.getUniqueId(), relationshipTypeDefinitionMap);
+ if (relationshipTypesByUid.isRight()) {
+ TitanOperationStatus status = relationshipTypesByUid.right().value();
+ if (status == TitanOperationStatus.NOT_FOUND) {
+ status = TitanOperationStatus.INVALID_ID;
+ }
+ return Either.right(status);
+ }
+ }
+ return null;
+ }
+
+ private Either<RelationshipTypeDefinition, TitanOperationStatus> getAndAddPropertiesANdDerivedFrom(
+ String uniqueId, Map<String, RelationshipTypeDefinition> relationshipTypeDefinitionMap) {
+ if (relationshipTypeDefinitionMap.containsKey(uniqueId)) {
+ return Either.left(relationshipTypeDefinitionMap.get(uniqueId));
+ }
+
+ Either<RelationshipTypeData, TitanOperationStatus> relationshipTypesRes =
+ titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RelationshipType), uniqueId,
+ RelationshipTypeData.class);
+
+ if (relationshipTypesRes.isRight()) {
+ TitanOperationStatus status = relationshipTypesRes.right().value();
+ logger.debug(RELATIONSHIP_TYPE_CANNOT_BE_FOUND_IN_GRAPH_STATUS_IS, uniqueId, status);
+ return Either.right(status);
+ }
+
+ RelationshipTypeData ctData = relationshipTypesRes.left().value();
+ RelationshipTypeDefinition relationshipTypeDefinition =
+ new RelationshipTypeDefinition(ctData.getRelationshipTypeDataDefinition());
+
+ Either<Map<String, PropertyDefinition>, TitanOperationStatus> propertiesStatus =
+ OperationUtils.fillProperties(uniqueId, propertyOperation, NodeTypeEnum.RelationshipType);
+ if (propertiesStatus.isRight() && propertiesStatus.right().value() != TitanOperationStatus.OK) {
+ logger.error(FAILED_TO_FETCH_PROPERTIES_OF_RELATIONSHIP_TYPE, uniqueId);
+ return Either.right(propertiesStatus.right().value());
+ }
+
+ if (propertiesStatus.isLeft()) {
+ relationshipTypeDefinition.setProperties(propertiesStatus.left().value());
+ }
+
+ fillDerivedFrom(uniqueId, relationshipTypeDefinition);
+
+ relationshipTypeDefinitionMap.put(relationshipTypeDefinition.getType(), relationshipTypeDefinition);
+
+ return Either.left(relationshipTypeDefinition);
+ }
+
+ private void fillDerivedFrom(String uniqueId,
+ RelationshipTypeDefinition relationshipType) {
+ logger.debug("#fillDerivedFrom - fetching relationship type {} derived node", relationshipType.getType());
+ derivedFromOperation.getDerivedFromChild(uniqueId, NodeTypeEnum.RelationshipType, RelationshipTypeData.class)
+ .right()
+ .bind(this::handleDerivedFromNotExist)
+ .left()
+ .map(derivedFrom -> setDerivedFrom(relationshipType, derivedFrom));
+
+ }
+
+ private Either<RelationshipTypeData, StorageOperationStatus> handleDerivedFromNotExist(StorageOperationStatus err) {
+ if (err == StorageOperationStatus.NOT_FOUND) {
+ return Either.left(null);
+ }
+ return Either.right(err);
+ }
+
+ private RelationshipTypeData setDerivedFrom(RelationshipTypeDefinition relationshipTypeDefinition, RelationshipTypeData derivedFrom) {
+ if (derivedFrom != null) {
+ relationshipTypeDefinition.setDerivedFrom(derivedFrom.getRelationshipTypeDataDefinition().getType());
+ }
+ return derivedFrom;
+ }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java
index 058e9de163..aa5ca81a31 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java
@@ -99,6 +99,10 @@ public class UniqueIdBuilder {
return type;
}
+ static String buildRelationshipTypeUid(String type) {
+ return type;
+ }
+
public static String buildAttributeUid(String resourceId, String attName) {
return buildTypeUid(NodeTypeEnum.Attribute.getName(), resourceId, attName);
}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/utils/TypeCompareUtils.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/utils/TypeCompareUtils.java
index 298cae0da5..e0e02ae121 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/utils/TypeCompareUtils.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/utils/TypeCompareUtils.java
@@ -71,6 +71,22 @@ public class TypeCompareUtils {
SetUtils.isEqualSet(ct1.getValidSourceTypes(), ct2.getValidSourceTypes()) &&
propertiesEquals(ct1.getProperties(), ct2.getProperties());
}
+
+ public static boolean isRelationshipTypesEquals(RelationshipTypeDefinition rs1, RelationshipTypeDefinition rs2) {
+ if (rs1 == rs2) {
+ return true;
+ }
+
+ if (rs1 == null || rs2 == null) {
+ return false;
+ }
+
+ return Objects.equals(rs1.getType(), rs2.getType()) &&
+ Objects.equals(rs1.getDerivedFrom(), rs2.getDerivedFrom()) &&
+ Objects.equals(rs1.getDescription(), rs2.getDescription()) &&
+ SetUtils.isEqualSet(rs1.getValidSourceTypes(), rs2.getValidSourceTypes()) &&
+ propertiesEquals(rs1.getProperties(), rs2.getProperties());
+ }
private static boolean propertiesEquals(Map<String, PropertyDefinition> props1, Map<String, PropertyDefinition> props2) {
if (props1 == props2) {
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeTypeTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeTypeTest.java
index aae9d6f2a0..493cb74a25 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeTypeTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/datamodel/NodeTypeTest.java
@@ -91,7 +91,7 @@ public class NodeTypeTest {
// default test
testSubject = createTestSubject();
- result = testSubject.getCapabilties();
+ result = testSubject.getCapabilities();
}
@@ -102,7 +102,7 @@ public class NodeTypeTest {
// default test
testSubject = createTestSubject();
- testSubject.setCapabilties(capabilties);
+ testSubject.setCapabilities(capabilties);
}
@@ -135,7 +135,7 @@ public class NodeTypeTest {
// default test
testSubject = createTestSubject();
- result = testSubject.getCapabiltiesProperties();
+ result = testSubject.getCapabilitiesProperties();
}
@@ -146,7 +146,7 @@ public class NodeTypeTest {
// default test
testSubject = createTestSubject();
- testSubject.setCapabiltiesProperties(capabiltiesProperties);
+ testSubject.setCapabilitiesProperties(capabiltiesProperties);
}
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/RelationshipTypeOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/RelationshipTypeOperationTest.java
new file mode 100644
index 0000000000..6f8c7ea629
--- /dev/null
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/RelationshipTypeOperationTest.java
@@ -0,0 +1,474 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.be.model.operations.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import fj.data.Either;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
+import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.RelationshipInstDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.model.ModelTestBase;
+import org.openecomp.sdc.be.model.PropertyConstraint;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.RelationshipTypeDefinition;
+import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.tosca.ToscaType;
+import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint;
+import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint;
+import org.openecomp.sdc.be.resources.data.RelationshipTypeData;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("classpath:application-context-test.xml")
+public class RelationshipTypeOperationTest extends ModelTestBase {
+
+ private static final String PROP = "prop";
+
+ @Mock
+ TitanGenericDao titanGenericDao;
+
+ @Mock
+ PropertyOperation propertyOperation;
+
+ @Mock
+ DerivedFromOperation derivedFromOperation;
+
+ @InjectMocks
+ @Spy
+ private RelationshipTypeOperation relationshipTypeOperation;
+
+ private RelationshipTypeDefinition relationshipTypeDefinition = new RelationshipTypeDefinition();
+
+ {
+ relationshipTypeDefinition.setDescription("desc1");
+ relationshipTypeDefinition.setType("tosca.relationships.Container1");
+ relationshipTypeDefinition.setDerivedFrom("tosca.relationships.Root");
+ relationshipTypeDefinition.setProperties(createPropertyData("prop1"));
+ relationshipTypeDefinition.setUniqueId("tosca.relationships.Container1");
+ }
+
+ @BeforeClass
+ public static void setupBeforeClass() {
+ ModelTestBase.init();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ Mockito.doReturn(TitanOperationStatus.OK).when(titanGenericDao).commit();
+ Mockito.doReturn(TitanOperationStatus.OK).when(titanGenericDao).rollback();
+ }
+
+ @Test
+ public void getRelationshipTypeByNameNotCreated() {
+ Mockito.doReturn(Either.right(TitanOperationStatus.NOT_CREATED))
+ .when(relationshipTypeOperation).getRelationshipTypeByUid(Mockito.anyString());
+
+ Either<RelationshipTypeDefinition, TitanOperationStatus> either =
+ relationshipTypeOperation.getRelationshipTypeByName("name");
+ assertTrue(either.isRight());
+ }
+
+ @Test
+ public void testDummy() {
+ assertNotNull(relationshipTypeOperation);
+ }
+
+ @Test
+ public void testAddRelationshipTypeValidationFailStatusNullInTransactionFalse() {
+ Mockito.doReturn(Either.right(TitanOperationStatus.NOT_CONNECTED))
+ .when(propertyOperation)
+ .getAllTypePropertiesFromAllDerivedFrom(Mockito.anyString(), Mockito.any(), Mockito.any());
+
+
+ Either<RelationshipTypeDefinition, StorageOperationStatus> addRelationshipType =
+ relationshipTypeOperation.addRelationshipType(relationshipTypeDefinition, false);
+
+ assertTrue(addRelationshipType.isRight());
+ }
+
+ @Test
+ public void testAddRelationshipTypeValidationFailStatusPropertiesReturnedInTransactionFalse() {
+ Mockito.doReturn(Either.left(Collections.singletonMap("prop1", new PropertyDefinition()))).when(propertyOperation)
+ .getAllTypePropertiesFromAllDerivedFrom(Mockito.anyString(), Mockito.any(), Mockito.any());
+ Mockito.doReturn(Either.right(TitanOperationStatus.NOT_FOUND)).when(propertyOperation)
+ .validatePropertiesUniqueness(Mockito.any(), Mockito.any());
+
+ Either<RelationshipTypeDefinition, StorageOperationStatus> addRelationshipType =
+ relationshipTypeOperation.addRelationshipType(relationshipTypeDefinition, false);
+
+ assertTrue(addRelationshipType.isRight());
+ }
+
+ @Test
+ public void testGetAllRelationshipTypesNotFound() {
+ Mockito.doReturn(Either.right(TitanOperationStatus.NOT_FOUND)).when(titanGenericDao).getByCriteria(NodeTypeEnum.RelationshipType, null,
+ RelationshipTypeData.class);
+ Either<Map<String, RelationshipTypeDefinition>, TitanOperationStatus> either = relationshipTypeOperation.getAllRelationshipTypes();
+
+ assertTrue(either.isLeft() && MapUtils.isEmpty(either.left().value()));
+ }
+
+ @Test
+ public void testGetAllRelationshipTypesNotConnnected() {
+ Mockito.doReturn(Either.right(TitanOperationStatus.NOT_CONNECTED)).when(titanGenericDao).getByCriteria(NodeTypeEnum.RelationshipType, null,
+ RelationshipTypeData.class);
+ Either<Map<String, RelationshipTypeDefinition>, TitanOperationStatus> either = relationshipTypeOperation.getAllRelationshipTypes();
+
+ assertTrue(either.isRight() && TitanOperationStatus.NOT_CONNECTED == either.right().value());
+ }
+
+ @Test
+ public void testGetAllRelationshipTypesSuccess() {
+ List<RelationshipTypeData> relationshipTypeDataList = new ArrayList<>();
+
+ RelationshipTypeData relationshipTypeData1 = new RelationshipTypeData();
+ RelationshipInstDataDefinition relationshipInstDataDefinition1 = new RelationshipInstDataDefinition();
+ relationshipInstDataDefinition1.setUniqueId("tosca.relationships.Root1");
+ relationshipInstDataDefinition1.setType("tosca.relationships.Root1");
+ relationshipTypeData1.setRelationshipTypeDataDefinition(relationshipInstDataDefinition1);
+
+ relationshipTypeDataList.add(relationshipTypeData1);
+
+ Mockito.doReturn(Either.left(relationshipTypeDataList))
+ .when(titanGenericDao).getByCriteria(NodeTypeEnum.RelationshipType, null,
+ RelationshipTypeData.class);
+
+ Mockito.doReturn(Either.left(relationshipTypeData1)).when(titanGenericDao)
+ .getNode(Mockito.anyString(), Mockito.anyString(), Mockito.eq(RelationshipTypeData.class));
+
+ Mockito.doReturn(Either.left(createPropertyData("prop1"))).when(propertyOperation)
+ .findPropertiesOfNode(NodeTypeEnum.RelationshipType, "tosca.relationships.Root1");
+
+ RelationshipInstDataDefinition derivedFromRelationshipTypeDefinition = new RelationshipInstDataDefinition();
+ derivedFromRelationshipTypeDefinition.setUniqueId("tosca.relationships.Root1");
+ derivedFromRelationshipTypeDefinition.setType("tosca.relationships.Parent");
+
+ Mockito.doReturn(Either.left(new RelationshipTypeData(derivedFromRelationshipTypeDefinition)))
+ .when(derivedFromOperation)
+ .getDerivedFromChild("tosca.relationships.Root1", NodeTypeEnum.RelationshipType, RelationshipTypeData.class);
+
+ Either<Map<String, RelationshipTypeDefinition>, TitanOperationStatus> either =
+ relationshipTypeOperation.getAllRelationshipTypes();
+
+ assertTrue(either.isLeft());
+ RelationshipTypeDefinition relationshipTypeDefinition = either.left().value().get("tosca.relationships.Root1");
+ assertEquals("tosca.relationships.Parent", relationshipTypeDefinition.getDerivedFrom());
+ }
+
+ public RelationshipTypeDefinition createRelationship(String relationshipTypeName) {
+
+ RelationshipTypeDefinition relationshipTypeDefinition = new RelationshipTypeDefinition();
+ relationshipTypeDefinition.setDescription("desc1");
+ relationshipTypeDefinition.setType(relationshipTypeName);
+
+ Map<String, PropertyDefinition> properties = new HashMap<>();
+
+ String propName1 = "disk_size";
+ String propName2 = "num_cpus";
+
+ PropertyDefinition property1 = buildProperty1();
+
+ properties.put(propName1, property1);
+
+ PropertyDefinition property2 = buildProperty2();
+
+ properties.put(propName2, property2);
+
+ relationshipTypeDefinition.setProperties(properties);
+
+ Either<RelationshipTypeDefinition, StorageOperationStatus> addRelationshipType1 =
+ relationshipTypeOperation.addRelationshipType(relationshipTypeDefinition, true);
+
+ RelationshipTypeDefinition relationshipTypeDefinitionCreated = addRelationshipType1.left().value();
+ Either<RelationshipTypeDefinition, StorageOperationStatus> relationshipType =
+ relationshipTypeOperation.getRelationshipType(relationshipTypeDefinitionCreated.getUniqueId(), true);
+ assertTrue("check relationship type fetched", relationshipType.isLeft());
+ RelationshipTypeDefinition fetchedCTD = relationshipType.left().value();
+
+ Map<String, PropertyDefinition> fetchedProps = fetchedCTD.getProperties();
+
+ compareProperties(fetchedProps, properties);
+
+ return fetchedCTD;
+
+ }
+
+ private void compareProperties(Map<String, PropertyDefinition> first, Map<String, PropertyDefinition> second) {
+
+ assertTrue("check properties are full or empty",
+ ((first == null && second == null) || (first != null && second != null)));
+ if (first != null) {
+ assertEquals("check properties size", first.size(), second.size());
+
+ for (Entry<String, PropertyDefinition> entry : first.entrySet()) {
+
+ String propName = entry.getKey();
+ PropertyDefinition secondPD = second.get(propName);
+ assertNotNull("Cannot find property " + propName + " in " + second, secondPD);
+
+ PropertyDefinition firstPD = entry.getValue();
+
+ comparePropertyDefinition(firstPD, secondPD);
+ }
+
+ }
+
+ }
+
+ private void comparePropertyDefinition(PropertyDefinition first, PropertyDefinition second) {
+
+ assertTrue("check objects are full or empty",
+ ((first == null && second == null) || (first != null && second != null)));
+ if (first != null) {
+ assertTrue("check property description", compareValue(first.getDescription(), second.getDescription()));
+ assertTrue("check property default value", compareValue((String) first.getDefaultValue(),
+ (String) second.getDefaultValue()));
+ assertTrue("check property type", compareValue(first.getType(), second.getType()));
+ compareList(first.getConstraints(), second.getConstraints());
+ }
+
+ }
+
+ private void compareList(List<PropertyConstraint> first, List<PropertyConstraint> second) {
+
+ assertTrue("check lists are full or empty",
+ ((first == null && second == null) || (first != null && second != null)));
+ if (first != null) {
+ assertEquals("check list size", first.size(), second.size());
+ }
+ }
+
+ private PropertyDefinition buildProperty2() {
+ PropertyDefinition property2 = new PropertyDefinition();
+ property2.setDefaultValue("2");
+ property2.setDescription("Number of (actual or virtual) CPUs associated with the Compute node.");
+ property2.setType(ToscaType.INTEGER.name().toLowerCase());
+ List<PropertyConstraint> constraints3 = new ArrayList<>();
+ List<String> range = new ArrayList<>();
+ range.add("4");
+ range.add("1");
+ InRangeConstraint propertyConstraint3 = new InRangeConstraint(range);
+ constraints3.add(propertyConstraint3);
+ property2.setConstraints(constraints3);
+ return property2;
+ }
+
+ private PropertyDefinition buildProperty1() {
+ PropertyDefinition property1 = new PropertyDefinition();
+ property1.setDefaultValue("10");
+ property1.setDescription("Size of the local disk, in Gigabytes (GB), "
+ + "available to applications running on the Compute node.");
+ property1.setType(ToscaType.INTEGER.name().toLowerCase());
+ List<PropertyConstraint> constraints = new ArrayList<>();
+ GreaterThanConstraint propertyConstraint1 = new GreaterThanConstraint("0");
+ constraints.add(propertyConstraint1);
+
+ LessOrEqualConstraint propertyConstraint2 = new LessOrEqualConstraint("10");
+ constraints.add(propertyConstraint2);
+
+ property1.setConstraints(constraints);
+ return property1;
+ }
+
+ private boolean compareValue(String first, String second) {
+
+ if (first == null && second == null) {
+ return true;
+ }
+ if (first != null) {
+ return first.equals(second);
+ } else {
+ return false;
+ }
+ }
+
+ public void setOperations(RelationshipTypeOperation relationshipTypeOperation) {
+ this.relationshipTypeOperation = relationshipTypeOperation;
+ }
+
+ @Test
+ public void testAddRelationshipType() {
+
+ RelationshipTypeData relationshipTypeData = new RelationshipTypeData();
+ RelationshipInstDataDefinition relationshipInstDataDefinition1 = new RelationshipInstDataDefinition();
+ relationshipInstDataDefinition1.setUniqueId("tosca.relationships.Root");
+ relationshipInstDataDefinition1.setType("tosca.relationships.Root");
+ relationshipTypeData.setRelationshipTypeDataDefinition(relationshipInstDataDefinition1);
+
+ RelationshipTypeDefinition relationshipTypeDefinition = new RelationshipTypeDefinition(relationshipTypeData);
+ relationshipTypeDefinition.setProperties(createPropertyData("prop1"));
+ relationshipTypeDefinition.setDerivedFrom("tosca.relationships.Root");
+
+ Mockito.doReturn(Either.left(Collections.singletonMap("prop1", new PropertyDefinition()))).when(propertyOperation)
+ .getAllTypePropertiesFromAllDerivedFrom(Mockito.anyString(), Mockito.any(), Mockito.any());
+
+ Mockito.doReturn(Either.left(new ArrayList<>(relationshipTypeDefinition.getProperties().values()))).when(propertyOperation)
+ .validatePropertiesUniqueness(Mockito.any(), Mockito.any());
+
+ Mockito.doReturn(Either.left(relationshipTypeData)).when(titanGenericDao)
+ .createNode(Mockito.any(), Mockito.eq(RelationshipTypeData.class));
+
+ Mockito.doReturn(Either.left(new HashMap())).when(propertyOperation)
+ .addPropertiesToElementType(Mockito.anyString(), Mockito.any(), Mockito.anyMap());
+
+ Mockito.doReturn(Either.left(relationshipTypeDefinition))
+ .when(relationshipTypeOperation).getRelationshipTypeByUid(Mockito.anyString());
+
+ Mockito.doReturn(Either.left(new GraphRelation()))
+ .when(derivedFromOperation)
+ .addDerivedFromRelation(Mockito.anyString(), Mockito.anyString(), Mockito.any());
+
+ Mockito.doReturn(Either.left(relationshipTypeDefinition))
+ .when(relationshipTypeOperation).getRelationshipType(Mockito.anyString(), Mockito.anyBoolean());
+
+ Either<RelationshipTypeDefinition, StorageOperationStatus> either =
+ relationshipTypeOperation.addRelationshipType(relationshipTypeDefinition, true);
+
+ assertTrue(either.isLeft());
+ }
+
+ @Test
+ public void testGetRelationshipTypeNotConnected() {
+ Mockito.doReturn(Either.right(TitanOperationStatus.NOT_CONNECTED))
+ .when(relationshipTypeOperation).getRelationshipTypeByUid(Mockito.anyString());
+
+ Either<RelationshipTypeDefinition, StorageOperationStatus> either =
+ relationshipTypeOperation.getRelationshipType(Mockito.anyString(), Mockito.anyBoolean());
+
+ assertTrue(either.isRight());
+ }
+
+ @Test
+ public void testGetRelationshipTypeSuccess() {
+ Mockito.doReturn(Either.left(relationshipTypeDefinition))
+ .when(relationshipTypeOperation).getRelationshipTypeByUid(Mockito.anyString());
+
+ Either<RelationshipTypeDefinition, StorageOperationStatus> either =
+ relationshipTypeOperation.getRelationshipType(Mockito.anyString(), Mockito.anyBoolean());
+
+ assertTrue(either.isLeft());
+ }
+
+ @Test
+ public void testUpdateRelationshipType() {
+ RelationshipTypeDefinition newRelationshipTypeDefinition = new RelationshipTypeDefinition();
+ newRelationshipTypeDefinition.setUniqueId("tosca.relationships.Container2");
+ newRelationshipTypeDefinition.setDescription("desc2");
+ newRelationshipTypeDefinition.setType("tosca.relationships.Container2");
+ newRelationshipTypeDefinition.setDerivedFrom("tosca.relationships.Root");
+ newRelationshipTypeDefinition.setProperties(createPropertyData("prop1"));
+
+ Mockito.doReturn(Either.left(new RelationshipTypeData(newRelationshipTypeDefinition))).when(titanGenericDao)
+ .updateNode(Mockito.any(), Mockito.eq(RelationshipTypeData.class));
+
+ Mockito.doReturn(Either.left(newRelationshipTypeDefinition.getProperties()))
+ .when(propertyOperation).deletePropertiesAssociatedToNode(Mockito.any(), Mockito.anyString());
+
+ Mockito.doReturn(Either.left(newRelationshipTypeDefinition.getProperties()))
+ .when(propertyOperation).addPropertiesToElementType(Mockito.anyString(), Mockito.any(), Mockito.anyMap());
+
+ Mockito.doReturn(Either.left(newRelationshipTypeDefinition)).when(relationshipTypeOperation)
+ .getRelationshipTypeByUid(Mockito.anyString());
+
+ Mockito.doReturn(StorageOperationStatus.OK).when(derivedFromOperation)
+ .removeDerivedFromRelation(Mockito.anyString(), Mockito.anyString(), Mockito.any());
+
+ Mockito.doReturn(Either.left(new GraphRelation()))
+ .when(derivedFromOperation)
+ .addDerivedFromRelation(Mockito.anyString(), Mockito.anyString(), Mockito.any());
+
+ Either<RelationshipTypeDefinition, StorageOperationStatus> either =
+ relationshipTypeOperation.updateRelationshipType(relationshipTypeDefinition,
+ newRelationshipTypeDefinition, false);
+
+ assertTrue(either.isLeft());
+ }
+
+ @Test
+ public void testGetRelationshipTypeByUid() {
+ RelationshipTypeData relationshipTypeData = new RelationshipTypeData(relationshipTypeDefinition);
+
+ Mockito.doReturn(Either.left(relationshipTypeData)).when(titanGenericDao)
+ .getNode(Mockito.anyString(), Mockito.any(), Mockito.eq(RelationshipTypeData.class));
+
+ Mockito.doReturn(Either.left(relationshipTypeDefinition.getProperties()))
+ .when(propertyOperation).findPropertiesOfNode(Mockito.any(), Mockito.anyString());
+
+ RelationshipTypeDefinition childRelationshipTypeDefinition = new RelationshipTypeDefinition();
+ childRelationshipTypeDefinition.setType("tosca.relationships.ContainerChild");
+
+ Mockito.doReturn(Either.left(new ImmutablePair(new RelationshipTypeData(childRelationshipTypeDefinition), null))).when(titanGenericDao)
+ .getChild(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.any(),
+ Mockito.eq(RelationshipTypeData.class));
+
+ Either<RelationshipTypeDefinition, TitanOperationStatus> either =
+ relationshipTypeOperation.getRelationshipTypeByUid("tosca.relationships.Container1");
+
+ assertTrue(either.isLeft()
+ && "tosca.relationships.ContainerChild".equals(either.left().value().getDerivedFrom()));
+ }
+
+ private Map<String, PropertyDefinition> createPropertyData(String value) {
+ PropertyDefinition propertyDefinition = new PropertyDefinition();
+ propertyDefinition.setDefaultValue(value);
+ propertyDefinition.setDescription(PROP + "_" + value);
+ propertyDefinition.setType(ToscaType.INTEGER.name().toLowerCase());
+ List<PropertyConstraint> constraints = new ArrayList<>();
+ List<String> range = new ArrayList<>();
+ range.add("1");
+ range.add("4");
+ InRangeConstraint propertyConstraint = new InRangeConstraint(range);
+ constraints.add(propertyConstraint);
+ propertyDefinition.setConstraints(constraints);
+ Map<String, PropertyDefinition> propertiesMap = new HashMap<>();
+ propertiesMap.put(PROP, propertyDefinition);
+ return propertiesMap;
+ }
+
+}
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ToscaElementLifecycleOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ToscaElementLifecycleOperationTest.java
index 88bb5142aa..c70e41b2f1 100644
--- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ToscaElementLifecycleOperationTest.java
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ToscaElementLifecycleOperationTest.java
@@ -59,10 +59,6 @@ import org.openecomp.sdc.common.util.ValidationUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
import java.util.*;
import static org.junit.Assert.assertEquals;
@@ -147,7 +143,7 @@ public class ToscaElementLifecycleOperationTest extends ModelTestBase {
cap1.setDescription("create");
cap1.setUniqueId(UniqueIdBuilder.buildCapabilityUid(id, "cap1"));
- status = nodeTypeOperation.addToscaDataToToscaElement(id, EdgeLabelEnum.CAPABILITIES, VertexTypeEnum.CAPABILTIES, cap1, JsonPresentationFields.NAME);
+ status = nodeTypeOperation.addToscaDataToToscaElement(id, EdgeLabelEnum.CAPABILITIES, VertexTypeEnum.CAPABILITIES, cap1, JsonPresentationFields.NAME);
assertSame(status, StorageOperationStatus.OK);
res = lifecycleOperation.checkinToscaELement(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, id, ownerVertex.getUniqueId(), ownerVertex.getUniqueId());
@@ -164,7 +160,7 @@ public class ToscaElementLifecycleOperationTest extends ModelTestBase {
cap1.setDescription("update");
- status = nodeTypeOperation.updateToscaDataOfToscaElement(id, EdgeLabelEnum.CAPABILITIES, VertexTypeEnum.CAPABILTIES, cap1, JsonPresentationFields.NAME);
+ status = nodeTypeOperation.updateToscaDataOfToscaElement(id, EdgeLabelEnum.CAPABILITIES, VertexTypeEnum.CAPABILITIES, cap1, JsonPresentationFields.NAME);
assertSame(status, StorageOperationStatus.OK);
PropertyDataDefinition prop66 = new PropertyDataDefinition();
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CapabilityDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CapabilityDataDefinition.java
index fdd1386e48..2612e6f888 100644
--- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CapabilityDataDefinition.java
+++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CapabilityDataDefinition.java
@@ -32,7 +32,7 @@ import java.util.List;
*/
public class CapabilityDataDefinition extends ToscaDataDefinition {
- public static final String MIN_OCCURRENCES = "1";
+ public static final String MIN_OCCURRENCES = "0";
public static final String MAX_OCCURRENCES = "UNBOUNDED";
/**
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RelationshipInstDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RelationshipInstDataDefinition.java
index 72d9c36bf6..2f995fd844 100644
--- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RelationshipInstDataDefinition.java
+++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RelationshipInstDataDefinition.java
@@ -32,6 +32,7 @@ public class RelationshipInstDataDefinition extends ToscaDataDefinition {
this.setDescription(cdt.getDescription());
this.setType(cdt.getType());
this.setValidSourceTypes(cdt.getValidSourceTypes());
+ this.setValidTargetTypes(cdt.getValidTargetTypes());
this.setVersion(cdt.getVersion());
this.setOriginUI(cdt.isOriginUI());
this.setCreationTime(cdt.getCreationTime());
@@ -54,11 +55,11 @@ public class RelationshipInstDataDefinition extends ToscaDataDefinition {
return (String) getToscaPresentationValue(JsonPresentationFields.REQUIREMENT);
}
public void setCapability(String capability) {
- setToscaPresentationValue(JsonPresentationFields.CAPAPILITY, capability);
+ setToscaPresentationValue(JsonPresentationFields.CAPABILITY, capability);
}
public String getCapability() {
- return (String) getToscaPresentationValue(JsonPresentationFields.CAPAPILITY);
+ return (String) getToscaPresentationValue(JsonPresentationFields.CAPABILITY);
}
public void setToId(Object toId) {
setToscaPresentationValue(JsonPresentationFields.TO_ID, toId);
@@ -144,6 +145,14 @@ public class RelationshipInstDataDefinition extends ToscaDataDefinition {
setToscaPresentationValue(JsonPresentationFields.VALID_SOURCE_TYPES, validSourceTypes);
}
+ public List<String> getValidTargetTypes() {
+ return (List<String>) getToscaPresentationValue(JsonPresentationFields.VALID_TARGET_TYPES);
+ }
+
+ public void setValidTargetTypes(List<String> validTargetTypes) {
+ setToscaPresentationValue(JsonPresentationFields.VALID_TARGET_TYPES, validTargetTypes);
+ }
+
public String getVersion() {
return (String) getToscaPresentationValue(JsonPresentationFields.VERSION);
}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementDataDefinition.java
index 4ede93eaa6..0df5ba500d 100644
--- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementDataDefinition.java
+++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementDataDefinition.java
@@ -31,7 +31,7 @@ import java.util.List;
*/
public class RequirementDataDefinition extends ToscaDataDefinition {
- public static final String MIN_OCCURRENCES = "1";
+ public static final String MIN_OCCURRENCES = "0";
public static final String MAX_OCCURRENCES = "UNBOUNDED";
public static final String MAX_DEFAULT_OCCURRENCES = "1";
@@ -107,11 +107,11 @@ public class RequirementDataDefinition extends ToscaDataDefinition {
*/
public String getCapability() {
- return (String) getToscaPresentationValue(JsonPresentationFields.CAPAPILITY);
+ return (String) getToscaPresentationValue(JsonPresentationFields.CAPABILITY);
}
public void setCapability(String capability) {
- setToscaPresentationValue(JsonPresentationFields.CAPAPILITY, capability);
+ setToscaPresentationValue(JsonPresentationFields.CAPABILITY, capability);
}
/**
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/JsonPresentationFields.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/JsonPresentationFields.java
index 7a4c3d4af7..a72984ab7d 100644
--- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/JsonPresentationFields.java
+++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/JsonPresentationFields.java
@@ -129,10 +129,11 @@ public enum JsonPresentationFields {
SOURCE("source", null),
//Requirement
- CAPAPILITY("capability", null),
+ CAPABILITY("capability", null),
NODE("node", null),
RELATIONSHIP("relationship", null),
VALID_SOURCE_TYPES("validSourceTypes", null),
+ VALID_TARGET_TYPES("validTargetTypes", null),
REQUIREMENT_ID("requirementId", null),
PARENT_NAME("parentName", null),
PREVIOUS_NAME("previousName", null),
diff --git a/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/api/Urls.java b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/api/Urls.java
index ba35ac3d33..1f1c90764b 100644
--- a/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/api/Urls.java
+++ b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/api/Urls.java
@@ -408,4 +408,16 @@ public interface Urls {
final String UPDATE_INTERFACE_OPERATIONS = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/%s/%s/interfaceOperations";
final String GET_INTERFACE_OPERATIONS = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/%s/%s/interfaces/%s/operations/%s";
final String DELETE_INTERFACE_OPERATIONS = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/%s/%s/interfaces/%s/operations/%s";
+
+ //Requirements
+ String CREATE_REQUIREMENT = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/%s/%s/requirements";
+ String UPDATE_REQUIREMENT = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/%s/%s/requirements";
+ String DELETE_REQUIREMENT = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/%s/%s/requirements/%s";
+ String GET_REQUIREMENT = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/%s/%s/requirements/%s";
+ //Capabilities
+ String CREATE_CAPABILITY = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/%s/%s/capabilities";
+ String UPDATE_CAPABILITY = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/%s/%s/capabilities";
+ String DELETE_CAPABILITY = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/%s/%s/capabilities/%s";
+ String GET_CAPABILITY = SDC_HTTP_METHOD + "://%s:%s/sdc2/rest/v1/catalog/%s/%s/capabilities/%s";
+
}
diff --git a/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/capability/CapabilitiesTest.java b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/capability/CapabilitiesTest.java
new file mode 100644
index 0000000000..ecdb48619b
--- /dev/null
+++ b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/capability/CapabilitiesTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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.ci.tests.capability;
+
+import org.junit.Rule;
+import org.junit.rules.TestName;
+import org.openecomp.sdc.be.model.Service;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.ci.tests.api.ComponentBaseTest;
+import org.openecomp.sdc.ci.tests.datatypes.CapabilityDetails;
+import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails;
+import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum;
+import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse;
+import org.openecomp.sdc.ci.tests.utils.general.ElementFactory;
+import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils;
+import org.openecomp.sdc.ci.tests.utils.rest.CapabilityRestUtils;
+import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils;
+import org.testng.Assert;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils.getServiceObject;
+
+public class CapabilitiesTest extends ComponentBaseTest {
+ @Rule
+ public static final TestName name = new TestName();
+
+ private ServiceReqDetails component;
+ private User user = null;
+
+ public CapabilitiesTest() {
+ super(name, CapabilitiesTest.class.getName());
+ }
+
+ @BeforeTest
+ public void init() throws Exception {
+ user = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER);
+ component = ElementFactory.getDefaultService();
+ component.setName("comp_cap" + Math.random());
+ ServiceRestUtils.createService(component, user);
+ }
+
+ @Test
+ public void createCapabilityTest() throws Exception {
+
+ CapabilityDetails capability = createCapability();
+ RestResponse restResponse = CapabilityRestUtils.createCapability(component.getUniqueId(),
+ Collections.singletonList(capability), user);
+ logger.info("createCapability Response Code:" + restResponse.getErrorCode());
+ Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+ }
+
+
+
+ @Test(dependsOnMethods = "createCapabilityTest")
+ public void updateCapabilityTest() throws Exception {
+
+ CapabilityDetails capability = createCapability();
+ capability.setMaxOccurrences("10");
+ capability.setMinOccurrences("4");
+ RestResponse restResponse = CapabilityRestUtils.updateCapability(component.getUniqueId(),
+ Collections.singletonList(capability), user);
+ logger.info("updateCapability Response Code:" + restResponse.getErrorCode());
+ Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+ }
+
+ @Test(dependsOnMethods = "updateCapabilityTest")
+ public void getCapabilityTest() throws Exception {
+ Service service = getServiceObject(component.getUniqueId());
+
+ List<org.openecomp.sdc.be.model.CapabilityDefinition> capabilityDefinitionList = service.getCapabilities().values()
+ .stream().flatMap(Collection::stream).collect(Collectors.toList());
+
+ RestResponse restResponse = CapabilityRestUtils.getCapability(component.getUniqueId(),
+ capabilityDefinitionList.get(0).getUniqueId(), user);
+ logger.info("getCapabilityTest Response Code:" + restResponse.getErrorCode());
+ Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+ }
+
+ @Test(dependsOnMethods = "getCapabilityTest")
+ public void deleteCapabilityTest() throws Exception {
+ Service service = getServiceObject(component.getUniqueId());
+
+ List<org.openecomp.sdc.be.model.CapabilityDefinition> capabilityDefinitionList = service.getCapabilities().values()
+ .stream().flatMap(Collection::stream).collect(Collectors.toList());
+
+ RestResponse restResponse = CapabilityRestUtils.deleteCapability(component.getUniqueId(),
+ capabilityDefinitionList.get(0).getUniqueId(), user);
+ logger.info("deleteCapabilityTest Response Code:" + restResponse.getErrorCode());
+ Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+ }
+
+ private CapabilityDetails createCapability() {
+ CapabilityDetails capabilityDetails = new CapabilityDetails();
+ capabilityDetails.setName("cap" + Math.random());
+ capabilityDetails.setType("tosca.capabilities.network.Bindable");
+
+ return capabilityDetails;
+ }
+}
diff --git a/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/CapabilityDetails.java b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/CapabilityDetails.java
new file mode 100644
index 0000000000..954a16a63d
--- /dev/null
+++ b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/CapabilityDetails.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.ci.tests.datatypes;
+
+public class CapabilityDetails {
+ private String name;
+ private String type;
+ private String maxOccurrences;
+ private String minOccurrences;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getMaxOccurrences() {
+ return maxOccurrences;
+ }
+
+ public void setMaxOccurrences(String maxOccurrences) {
+ this.maxOccurrences = maxOccurrences;
+ }
+
+ public String getMinOccurrences() {
+ return minOccurrences;
+ }
+
+ public void setMinOccurrences(String minOccurrences) {
+ this.minOccurrences = minOccurrences;
+ }
+}
diff --git a/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/RequirementDetails.java b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/RequirementDetails.java
new file mode 100644
index 0000000000..a720786d83
--- /dev/null
+++ b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/RequirementDetails.java
@@ -0,0 +1,74 @@
+/*
+ * 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.ci.tests.datatypes;
+
+public class RequirementDetails {
+ private String capability;
+ private String name;
+ private String node;
+ private String relationship;
+ private String maxOccurrences;
+ private String minOccurrences;
+
+ public String getCapability() {
+ return capability;
+ }
+
+ public void setCapability(String capability) {
+ this.capability = capability;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getNode() {
+ return node;
+ }
+
+ public void setNode(String node) {
+ this.node = node;
+ }
+
+ public String getRelationship() {
+ return relationship;
+ }
+
+ public void setRelationship(String relationship) {
+ this.relationship = relationship;
+ }
+
+ public String getMaxOccurrences() {
+ return maxOccurrences;
+ }
+
+ public void setMaxOccurrences(String maxOccurrences) {
+ this.maxOccurrences = maxOccurrences;
+ }
+
+ public String getMinOccurrences() {
+ return minOccurrences;
+ }
+
+ public void setMinOccurrences(String minOccurrences) {
+ this.minOccurrences = minOccurrences;
+ }
+}
diff --git a/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/requirements/RequirementsTest.java b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/requirements/RequirementsTest.java
new file mode 100644
index 0000000000..51894e7ec1
--- /dev/null
+++ b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/requirements/RequirementsTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.ci.tests.requirements;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.rules.TestName;
+import org.openecomp.sdc.be.model.RequirementDefinition;
+import org.openecomp.sdc.be.model.Service;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.ci.tests.api.ComponentBaseTest;
+import org.openecomp.sdc.ci.tests.datatypes.RequirementDetails;
+import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails;
+import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum;
+import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse;
+import org.openecomp.sdc.ci.tests.utils.general.ElementFactory;
+import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils;
+import org.openecomp.sdc.ci.tests.utils.rest.RequirementsUtils;
+import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils.getServiceObject;
+
+public class RequirementsTest extends ComponentBaseTest {
+ @Rule
+ public static final TestName name = new TestName();
+
+ private ServiceReqDetails component;
+ private User user = null;
+
+ public RequirementsTest() {
+ super(name, RequirementsTest.class.getName());
+ }
+
+ @BeforeTest
+ public void init() throws Exception {
+ user = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER);
+ component = ElementFactory.getDefaultService();
+ component.setName("comp_req" + Math.random());
+ ServiceRestUtils.createService(component, user);
+ }
+
+ @Test
+ public void createRequirementTest() throws Exception {
+
+ RequirementDetails requirement = createRequirement();
+ RestResponse restResponse = RequirementsUtils.createRequirement(component.getUniqueId(),
+ Collections.singletonList(requirement), user);
+ logger.info("createRequirement Response Code:" + restResponse.getErrorCode());
+ Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+ }
+
+ @Test(dependsOnMethods = "createRequirementTest")
+ public void updateRequirementTest() throws Exception {
+
+ RequirementDetails requirement = createRequirement();
+ requirement.setMaxOccurrences("10");
+ requirement.setMinOccurrences("4");
+ RestResponse restResponse = RequirementsUtils.updateRequirement(component.getUniqueId(),
+ Collections.singletonList(requirement), user);
+ logger.info("updateRequirement Response Code:" + restResponse.getErrorCode());
+ Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+ }
+
+ @Test(dependsOnMethods = "updateRequirementTest")
+ public void getRequirementTest() throws Exception {
+ Service service = getServiceObject(component.getUniqueId());
+
+ List<RequirementDefinition> requirementDefinitionList = service.getRequirements().values()
+ .stream().flatMap(Collection::stream).collect(Collectors.toList());
+
+ RestResponse restResponse = RequirementsUtils.getRequirement(component.getUniqueId(),
+ requirementDefinitionList.get(0).getUniqueId(), user);
+ logger.info("getRequirementTest Response Code:" + restResponse.getErrorCode());
+ Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+ }
+
+ @Test(dependsOnMethods = "getRequirementTest")
+ public void deleteRequirementTest() throws Exception {
+ Service service = getServiceObject(component.getUniqueId());
+
+ List<RequirementDefinition> requirementDefinitionList = service.getRequirements().values()
+ .stream().flatMap(Collection::stream).collect(Collectors.toList());
+
+ RestResponse restResponse = RequirementsUtils.deleteRequirement(component.getUniqueId(),
+ requirementDefinitionList.get(0).getUniqueId(), user);
+ logger.info("deleteRequirementTest Response Code:" + restResponse.getErrorCode());
+ Assert.assertEquals((int) restResponse.getErrorCode(), BaseRestUtils.STATUS_CODE_SUCCESS);
+ }
+
+ private RequirementDetails createRequirement() {
+ RequirementDetails requirementDetails = new RequirementDetails();
+ requirementDetails.setName("req" + Math.random());
+ requirementDetails.setCapability("tosca.capabilities.network.Bindable");
+
+ return requirementDetails;
+ }
+}
diff --git a/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/CapabilityRestUtils.java b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/CapabilityRestUtils.java
new file mode 100644
index 0000000000..1959aa8b9a
--- /dev/null
+++ b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/CapabilityRestUtils.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openecomp.sdc.ci.tests.utils.rest;
+
+import com.google.gson.Gson;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.ci.tests.api.Urls;
+import org.openecomp.sdc.ci.tests.config.Config;
+import org.openecomp.sdc.ci.tests.datatypes.CapabilityDetails;
+import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse;
+
+import java.util.List;
+
+public class CapabilityRestUtils extends BaseRestUtils {
+ private static Gson gson = new Gson();
+ private static final String COMPONENT_TYPE = "services";
+
+ public static RestResponse createCapability(String componentId,
+ List<CapabilityDetails> capabilityDetailsList,
+ User user) throws Exception{
+ Config config = Config.instance();
+ String url = String.format(Urls.CREATE_CAPABILITY, config.getCatalogBeHost(), config.getCatalogBePort(),
+ COMPONENT_TYPE, componentId);
+
+ String data = "{ \"capabilities\" : {" + "\"" +capabilityDetailsList.get(0).getType()+ "\"" +" : "
+ + gson.toJson(capabilityDetailsList) + " } }";
+
+ return sendPost(url, data , user.getUserId(), acceptHeaderData);
+ }
+
+ public static RestResponse updateCapability(String componentId,
+ List<CapabilityDetails> capabilityDetailsList,
+ User user) throws Exception{
+ Config config = Config.instance();
+ String url = String.format(Urls.UPDATE_CAPABILITY, config.getCatalogBeHost(), config.getCatalogBePort(),
+ COMPONENT_TYPE, componentId);
+
+ String data = "{ \"capabilities\" : {" + "\"" +capabilityDetailsList.get(0).getType()+ "\"" +" : "
+ + gson.toJson(capabilityDetailsList) + " } }";
+
+ return sendPost(url, data , user.getUserId(), acceptHeaderData);
+ }
+
+ public static RestResponse deleteCapability(String componentId,
+ String requirementId,
+ User user) throws Exception{
+ Config config = Config.instance();
+ String url = String.format(Urls.DELETE_CAPABILITY, config.getCatalogBeHost(), config.getCatalogBePort(),
+ COMPONENT_TYPE, componentId, requirementId);
+ return sendDelete(url, user.getUserId());
+ }
+
+ public static RestResponse getCapability(String componentId,
+ String requirementId,
+ User user) throws Exception{
+ Config config = Config.instance();
+ String url = String.format(Urls.GET_CAPABILITY, config.getCatalogBeHost(), config.getCatalogBePort(),
+ COMPONENT_TYPE, componentId, requirementId);
+ return sendDelete(url, user.getUserId());
+ }
+
+}
diff --git a/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/RequirementsUtils.java b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/RequirementsUtils.java
new file mode 100644
index 0000000000..4be1d941ce
--- /dev/null
+++ b/test-apis-ci/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/RequirementsUtils.java
@@ -0,0 +1,75 @@
+/*
+ * 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.ci.tests.utils.rest;
+
+import com.google.gson.Gson;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.ci.tests.api.Urls;
+import org.openecomp.sdc.ci.tests.config.Config;
+import org.openecomp.sdc.ci.tests.datatypes.RequirementDetails;
+import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse;
+
+import java.util.List;
+
+public class RequirementsUtils extends BaseRestUtils {
+ private static Gson gson = new Gson();
+ private static final String COMPONENT_TYPE = "services";
+
+ public static RestResponse createRequirement(String componentId,
+ List<RequirementDetails> requirementDefinitionList,
+ User user) throws Exception{
+ Config config = Config.instance();
+ String url = String.format(Urls.CREATE_REQUIREMENT, config.getCatalogBeHost(), config.getCatalogBePort(),
+ COMPONENT_TYPE, componentId);
+
+ String data = "{ \"requirements\" : {" + "\"" +requirementDefinitionList.get(0).getCapability()+ "\"" +" : "
+ + gson.toJson(requirementDefinitionList) + " } }";
+
+ return sendPost(url, data , user.getUserId(), acceptHeaderData);
+ }
+
+ public static RestResponse updateRequirement(String componentId,
+ List<RequirementDetails> requirementDefinitionList,
+ User user) throws Exception{
+ Config config = Config.instance();
+ String url = String.format(Urls.UPDATE_REQUIREMENT, config.getCatalogBeHost(), config.getCatalogBePort(),
+ COMPONENT_TYPE, componentId);
+
+ String data = "{ \"requirements\" : {" + "\"" +requirementDefinitionList.get(0).getCapability()+ "\"" +" : "
+ + gson.toJson(requirementDefinitionList) + " } }";
+
+ return sendPost(url, data , user.getUserId(), acceptHeaderData);
+ }
+
+ public static RestResponse deleteRequirement(String componentId,
+ String requirementId,
+ User user) throws Exception{
+ Config config = Config.instance();
+ String url = String.format(Urls.DELETE_REQUIREMENT, config.getCatalogBeHost(), config.getCatalogBePort(),
+ COMPONENT_TYPE, componentId, requirementId);
+ return sendDelete(url, user.getUserId());
+ }
+
+ public static RestResponse getRequirement(String componentId,
+ String requirementId,
+ User user) throws Exception{
+ Config config = Config.instance();
+ String url = String.format(Urls.GET_REQUIREMENT, config.getCatalogBeHost(), config.getCatalogBePort(),
+ COMPONENT_TYPE, componentId, requirementId);
+ return sendDelete(url, user.getUserId());
+ }
+}
diff --git a/test-apis-ci/src/main/resources/ci/testSuites/cap_req.xml b/test-apis-ci/src/main/resources/ci/testSuites/cap_req.xml
new file mode 100644
index 0000000000..8298af2da5
--- /dev/null
+++ b/test-apis-ci/src/main/resources/ci/testSuites/cap_req.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<suite name="Cap_Req" >
+ <test name="Cap_Req">
+ <classes>
+ <class name="org.openecomp.sdc.ci.tests.requirements.RequirementsTest"/>
+ <class name="org.openecomp.sdc.ci.tests.capability.CapabilitiesTest"/>
+ </classes>
+ </test>
+</suite> <!-- Artifacts -->