Support for adding artifact types
Issue-ID: SDC-3763
Change-Id: Ideb63cbb3eb4e383adebaa11de49e91414a2c9a7
Signed-off-by: aribeiro <anderson.ribeiro@est.tech>
diff --git a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml
index cfde6b4..af517c5 100644
--- a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml
+++ b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml
@@ -2617,4 +2617,20 @@
code: 400,
message: "Invalid node_types TOSCA yaml",
messageId: "SVC4161"
+ }
+
+ #---------SVC4162-----------------------------
+ # %1 - The janusgraph status
+ FAILED_CREATE_ARTIFACTS_TYPES: {
+ code: 500,
+ message: "Failed to create artifact types with status '%1'.",
+ messageId: "SVC4162"
+ }
+
+ #---------SVC4163-----------------------------
+ # %1 - The janusgraph status
+ ARTIFACT_TYPE_ALREADY_EXIST: {
+ code: 409,
+ message: "Artifact type '%1' already exist.",
+ messageId: "SVC4163"
}
\ No newline at end of file
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactTypeImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactTypeImportManager.java
new file mode 100644
index 0000000..e6ff100
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactTypeImportManager.java
@@ -0,0 +1,100 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.be.components.impl;
+
+import fj.data.Either;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.impl.ComponentsUtils;
+import org.openecomp.sdc.be.model.ArtifactTypeDefinition;
+import org.openecomp.sdc.be.model.normatives.ElementTypeEnum;
+import org.openecomp.sdc.be.model.operations.impl.ArtifactTypeOperation;
+import org.openecomp.sdc.be.utils.TypeUtils;
+import org.openecomp.sdc.exception.ResponseFormat;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component("artifactTypeImportManager")
+public class ArtifactTypeImportManager {
+
+ private final ArtifactTypeOperation artifactTypeOperation;
+ private final ComponentsUtils componentsUtils;
+ private final CommonImportManager commonImportManager;;
+
+ @Autowired
+ public ArtifactTypeImportManager(final ArtifactTypeOperation artifactTypeOperation, final ComponentsUtils componentsUtils,
+ final CommonImportManager commonImportManager) {
+ this.artifactTypeOperation = artifactTypeOperation;
+ this.componentsUtils = componentsUtils;
+ this.commonImportManager = commonImportManager;
+ }
+
+ public Either<List<ArtifactTypeDefinition>, ResponseFormat> createArtifactTypes(final String artifactTypesYml,
+ final String modelName,
+ final boolean includeToModelDefaultImports) {
+ if (StringUtils.isNotEmpty(modelName)) {
+ artifactTypeOperation.validateModel(modelName);
+ }
+ final Either<List<ArtifactTypeDefinition>, ActionStatus> artifactTypes = createArtifactTypeFromYml(artifactTypesYml, modelName);
+ if (artifactTypes.isRight()) {
+ return Either.right(componentsUtils.getResponseFormat(artifactTypes.right().value()));
+ }
+ final List<ArtifactTypeDefinition> elementTypes = createArtifactTypesByDao(artifactTypes.left().value());
+ if (includeToModelDefaultImports) {
+ commonImportManager.addTypesToDefaultImports(ElementTypeEnum.ARTIFACT_TYPE, artifactTypesYml, modelName);
+ }
+ return Either.left(elementTypes);
+ }
+
+ private Either<List<ArtifactTypeDefinition>, ActionStatus> createArtifactTypeFromYml(
+ final String artifactTypesYml, final String modelName) {
+ final Either<List<ArtifactTypeDefinition>, ActionStatus> artifactTypes =
+ commonImportManager.createElementTypesFromYml(artifactTypesYml, this::createArtifactTypeDefinition);
+ if (artifactTypes.isLeft()) {
+ artifactTypes.left().value().forEach(artifactType -> artifactType.setModel(modelName));
+ return artifactTypes;
+ }
+ return artifactTypes;
+ }
+
+ private List<ArtifactTypeDefinition> createArtifactTypesByDao(
+ final List<ArtifactTypeDefinition> artifactTypes) {
+ final List<ArtifactTypeDefinition> createdTypes = new ArrayList<>();
+ artifactTypes.forEach(type -> createdTypes.add(artifactTypeOperation.createArtifactType(type)));
+ return createdTypes;
+ }
+
+ private ArtifactTypeDefinition createArtifactTypeDefinition(final String type,
+ final Map<String, Object> toscaJson) {
+ final ArtifactTypeDefinition artifactType = new ArtifactTypeDefinition();
+ artifactType.setType(type);
+ if (toscaJson != null) {
+ commonImportManager.setField(toscaJson, TypeUtils.ToscaTagNamesEnum.DESCRIPTION.getElementName(),
+ artifactType::setDescription);
+ commonImportManager.setField(toscaJson, TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName(),
+ artifactType::setDerivedFrom);
+ CommonImportManager.setProperties(toscaJson, artifactType::setProperties);
+ }
+ return artifactType;
+ }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java
index a566d6c..7b21484 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java
@@ -88,6 +88,7 @@
import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
import org.openecomp.sdc.be.info.ArtifactTemplateInfo;
import org.openecomp.sdc.be.model.ArtifactDefinition;
+import org.openecomp.sdc.be.model.ArtifactTypeDefinition;
import org.openecomp.sdc.be.model.Component;
import org.openecomp.sdc.be.model.ComponentInstance;
import org.openecomp.sdc.be.model.ComponentParametersView;
@@ -113,6 +114,7 @@
import org.openecomp.sdc.be.model.operations.api.IHeatParametersOperation;
import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.operations.impl.ArtifactTypeOperation;
import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
@@ -179,6 +181,7 @@
private IElementOperation elementOperation;
@javax.annotation.Resource
private IHeatParametersOperation heatParametersOperation;
+ private final ArtifactTypeOperation artifactTypeOperation;
private ArtifactCassandraDao artifactCassandraDao;
private ToscaExportHandler toscaExportUtils;
private CsarUtils csarUtils;
@@ -193,7 +196,8 @@
ArtifactsResolver artifactsResolver, IElementOperation elementDao, IGroupOperation groupOperation,
IGroupInstanceOperation groupInstanceOperation, IGroupTypeOperation groupTypeOperation,
InterfaceOperation interfaceOperation, InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
- ArtifactsOperations artifactToscaOperation) {
+ ArtifactsOperations artifactToscaOperation,
+ ArtifactTypeOperation artifactTypeOperation) {
super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
artifactToscaOperation);
this.artifactCassandraDao = artifactCassandraDao;
@@ -202,6 +206,7 @@
this.lifecycleBusinessLogic = lifecycleBusinessLogic;
this.userBusinessLogic = userBusinessLogic;
this.artifactsResolver = artifactsResolver;
+ this.artifactTypeOperation = artifactTypeOperation;
}
public static <R> Either<Boolean, R> ifTrue(boolean predicate, Supplier<Either<Boolean, R>> ifTrue) {
@@ -4263,4 +4268,11 @@
return operation == CREATE || operation == LINK;
}
}
+
+ public Map<String, ArtifactTypeDefinition> getAllToscaArtifacts(final String modelName) {
+ if (StringUtils.isNotEmpty(modelName)) {
+ artifactTypeOperation.validateModel(modelName);
+ }
+ return artifactTypeOperation.getAllArtifactTypes(modelName);
+ }
}
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 af05825..5c2facc 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
@@ -1564,4 +1564,31 @@
return allDataTypes.left().value();
}
+ public ActionStatus convertFromStorageResponseForArtifactType(final 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.ARTIFACT_TYPE_ALREADY_EXIST;
+ break;
+ case SCHEMA_VIOLATION:
+ responseEnum = ActionStatus.ARTIFACT_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/TypesFetchServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java
index 0973984..7a229c8 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
@@ -19,11 +19,22 @@
*/
package org.openecomp.sdc.be.servlets;
+import com.jcabi.aspects.Loggable;
+import fj.data.Either;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.ArraySchema;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.servers.Server;
+import io.swagger.v3.oas.annotations.servers.Servers;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.tags.Tags;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
-
import javax.inject.Inject;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
@@ -36,8 +47,8 @@
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-
import org.apache.commons.collections4.ListUtils;
+import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic;
import org.openecomp.sdc.be.components.impl.CapabilitiesBusinessLogic;
import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic;
import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
@@ -53,6 +64,7 @@
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.exception.BusinessException;
import org.openecomp.sdc.be.impl.ComponentsUtils;
import org.openecomp.sdc.be.impl.ServletUtils;
import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
@@ -64,25 +76,12 @@
import org.openecomp.sdc.be.user.UserBusinessLogic;
import org.openecomp.sdc.common.api.Constants;
import org.openecomp.sdc.common.datastructure.Wrapper;
+import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
import org.openecomp.sdc.common.log.wrappers.Logger;
import org.openecomp.sdc.common.util.ValidationUtils;
import org.openecomp.sdc.exception.ResponseFormat;
import org.springframework.stereotype.Controller;
-import com.jcabi.aspects.Loggable;
-
-import fj.data.Either;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.media.ArraySchema;
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.servers.Server;
-import io.swagger.v3.oas.annotations.servers.Servers;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.tags.Tags;
-
@Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
@Path("/v1/catalog")
@Tags({@Tag(name = "SDCE-2 APIs")})
@@ -97,18 +96,21 @@
private final CapabilitiesBusinessLogic capabilitiesBusinessLogic;
private final InterfaceOperationBusinessLogic interfaceOperationBusinessLogic;
private final ResourceBusinessLogic resourceBusinessLogic;
+ private final ArtifactsBusinessLogic artifactsBusinessLogic;
@Inject
public TypesFetchServlet(UserBusinessLogic userBusinessLogic, ComponentInstanceBusinessLogic componentInstanceBL, ComponentsUtils componentsUtils,
ServletUtils servletUtils, ResourceImportManager resourceImportManager, PropertyBusinessLogic propertyBusinessLogic,
RelationshipTypeBusinessLogic relationshipTypeBusinessLogic, CapabilitiesBusinessLogic capabilitiesBusinessLogic,
- InterfaceOperationBusinessLogic interfaceOperationBusinessLogic, ResourceBusinessLogic resourceBusinessLogic) {
+ InterfaceOperationBusinessLogic interfaceOperationBusinessLogic, ResourceBusinessLogic resourceBusinessLogic,
+ ArtifactsBusinessLogic artifactsBusinessLogic) {
super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
this.propertyBusinessLogic = propertyBusinessLogic;
this.relationshipTypeBusinessLogic = relationshipTypeBusinessLogic;
this.capabilitiesBusinessLogic = capabilitiesBusinessLogic;
this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic;
this.resourceBusinessLogic = resourceBusinessLogic;
+ this.artifactsBusinessLogic = artifactsBusinessLogic;
}
@GET
@@ -313,6 +315,31 @@
}
}
+ @GET
+ @Path("/artifactTypes")
+ @Operation(description = "Get Tosca ArtifactTypes", method = "GET", summary = "Returns tosca artifact types", responses = {
+ @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
+ @ApiResponse(responseCode = "200", description = "Listing successful"),
+ @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
+ @ApiResponse(responseCode = "403", description = "Restricted operation"),
+ @ApiResponse(responseCode = "404", description = "Tosca Artifact Types not found")})
+ @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
+ public Response getAllToscaArtifactTypes(@Parameter(description = "Model name") @QueryParam("model") String model,
+ @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) {
+ try {
+ return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), artifactsBusinessLogic.getAllToscaArtifacts(model));
+ } catch (final BusinessException e) {
+ throw e;
+ } catch (final Exception e) {
+ final var errorMsg = "Unexpected error while listing the Tosca Artifact types";
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError(errorMsg);
+ log.error(EcompLoggerErrorCode.UNKNOWN_ERROR, this.getClass().getName(), errorMsg, e);
+ return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+ }
+
+ }
+
+
private Either<Map<String, Component>, Response> getComponent(ComponentBusinessLogic resourceBL, boolean isAbstract, String userId) {
Either<List<Component>, ResponseFormat> actionResponse;
List<Component> componentList;
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 06738a8..fbd4801 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
@@ -49,6 +49,7 @@
import javax.ws.rs.core.Response;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.glassfish.jersey.media.multipart.FormDataParam;
+import org.openecomp.sdc.be.components.impl.ArtifactTypeImportManager;
import org.openecomp.sdc.be.components.impl.CapabilityTypeImportManager;
import org.openecomp.sdc.be.components.impl.CategoriesImportManager;
import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
@@ -102,6 +103,7 @@
private final GroupTypeImportManager groupTypeImportManager;
private final PolicyTypeImportManager policyTypeImportManager;
private final RelationshipTypeImportManager relationshipTypeImportManager;
+ private final ArtifactTypeImportManager artifactTypeImportManager;
@Inject
public TypesUploadServlet(UserBusinessLogic userBusinessLogic, ComponentInstanceBusinessLogic componentInstanceBL,
@@ -110,7 +112,7 @@
InterfaceLifecycleTypeImportManager interfaceLifecycleTypeImportManager,
CategoriesImportManager categoriesImportManager, DataTypeImportManager dataTypeImportManager,
GroupTypeImportManager groupTypeImportManager, PolicyTypeImportManager policyTypeImportManager,
- RelationshipTypeImportManager relationshipTypeImportManager) {
+ RelationshipTypeImportManager relationshipTypeImportManager, ArtifactTypeImportManager artifactTypeImportManager) {
super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
this.capabilityTypeImportManager = capabilityTypeImportManager;
this.interfaceLifecycleTypeImportManager = interfaceLifecycleTypeImportManager;
@@ -119,6 +121,7 @@
this.groupTypeImportManager = groupTypeImportManager;
this.policyTypeImportManager = policyTypeImportManager;
this.relationshipTypeImportManager = relationshipTypeImportManager;
+ this.artifactTypeImportManager = artifactTypeImportManager;
}
@POST
@@ -178,6 +181,26 @@
}
@POST
+ @Path("/artifactTypes")
+ @Operation(description = "Create Tosca Artifact types from yaml", method = "POST", summary = "Returns created Tosca artifact types", responses = {
+ @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
+ @ApiResponse(responseCode = "201", description = "Tosca Artifact types created"),
+ @ApiResponse(responseCode = "403", description = "Restricted operation"),
+ @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
+ @ApiResponse(responseCode = "409", description = "Tosca Artifact Type already exist")})
+ @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
+ public Response uploadArtifactTypes(@Parameter(description = "Zip file containing a yaml with the TOSCA artifact types definition")
+ @FormDataParam("artifactsZip") File file,
+ @Parameter(description = "model name") @FormDataParam("model") String modelName,
+ @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
+ @Parameter(description = "A flag to add types to the default imports")
+ @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
+ final ConsumerTwoParam<Wrapper<Response>, String> createElementsMethod = (responseWrapper, ymlPayload) ->
+ createElementsType(responseWrapper, () -> artifactTypeImportManager.createArtifactTypes(ymlPayload, modelName, includeToModelDefaultImports));
+ return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, NodeTypeEnum.ArtifactType.getName());
+ }
+
+ @POST
@Path("/categories")
@Operation(description = "Create Categories from yaml", method = "POST", summary = "Returns created categories", responses = {
@ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactBusinessLogicTest.java
index f1a1aaa..616d9e4 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactBusinessLogicTest.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactBusinessLogicTest.java
@@ -20,6 +20,17 @@
package org.openecomp.sdc.be.components.impl;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.HEAT_ENV_NAME;
+import static org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.HEAT_VF_ENV_NAME;
+
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -28,6 +39,12 @@
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import fj.data.Either;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.Optional;
import org.junit.Before;
import org.junit.Test;
@@ -38,10 +55,10 @@
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import org.openecomp.sdc.be.components.ArtifactsResolver;
-import org.openecomp.sdc.be.config.ArtifactConfigManager;
import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
import org.openecomp.sdc.be.components.utils.ArtifactBuilder;
import org.openecomp.sdc.be.components.utils.ObjectGenerator;
+import org.openecomp.sdc.be.config.ArtifactConfigManager;
import org.openecomp.sdc.be.config.ArtifactConfiguration;
import org.openecomp.sdc.be.config.ComponentType;
import org.openecomp.sdc.be.dao.api.ActionStatus;
@@ -65,6 +82,7 @@
import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.operations.impl.ArtifactTypeOperation;
import org.openecomp.sdc.be.resources.data.DAOArtifactData;
import org.openecomp.sdc.be.servlets.RepresentationUtils;
import org.openecomp.sdc.be.tosca.CsarUtils;
@@ -74,24 +92,6 @@
import org.openecomp.sdc.common.api.ArtifactTypeEnum;
import org.openecomp.sdc.exception.ResponseFormat;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.HEAT_ENV_NAME;
-import static org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.HEAT_VF_ENV_NAME;
-
@RunWith(MockitoJUnitRunner.class)
public class ArtifactBusinessLogicTest extends BaseBusinessLogicMock{
@@ -122,10 +122,6 @@
JanusGraphDao janusGraphDao;
@Mock
private IInterfaceLifecycleOperation interfaceLifecycleOperation;
-
- // public static final InformationDeployedArtifactsBusinessLogic
- // informationDeployedArtifactsBusinessLogic =
- // Mockito.mock(InformationDeployedArtifactsBusinessLogic.class);
@Mock
private ToscaExportHandler toscaExportHandler;
@Mock
@@ -134,13 +130,15 @@
private LifecycleBusinessLogic lifecycleBusinessLogic;
@Mock
private ArtifactsResolver artifactsResolver;
+ @Mock
+ private ArtifactTypeOperation artifactTypeOperation;
public static final Resource resource = Mockito.mock(Resource.class);
private Gson gson = new GsonBuilder().setPrettyPrinting().create();
@Before
public void initMocks() {
- MockitoAnnotations.initMocks(this);
+ MockitoAnnotations.openMocks(this);
when(userBusinessLogic.getUser(eq("jh0003"), anyBoolean())).thenReturn(USER);
when(resource.getResourceType()).thenReturn(ResourceTypeEnum.VFC);
}
@@ -536,16 +534,6 @@
assertThat(result.isLeft()).isTrue();
}
- private ArtifactsBusinessLogic getArtifactsBusinessLogic() {
- ArtifactsBusinessLogic artifactsBusinessLogic = new ArtifactsBusinessLogic(artifactCassandraDao,
- toscaExportHandler, csarUtils, lifecycleBusinessLogic,
- userBusinessLogic, artifactsResolver, elementDao, groupOperation, groupInstanceOperation,
- groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
- artifactsBusinessLogic.setGraphLockOperation(graphLockOperation);
- artifactsBusinessLogic.setToscaOperationFacade(toscaOperationFacade);
- return artifactsBusinessLogic;
- }
-
@Test
public void buildArtifactPayloadWhenShouldLockAndNotInTransaction() {
ArtifactDefinition artifactDefinition = new ArtifactDefinition();
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactTypeImportManagerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactTypeImportManagerTest.java
new file mode 100644
index 0000000..28a7e9c
--- /dev/null
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactTypeImportManagerTest.java
@@ -0,0 +1,73 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.sdc.be.components.impl;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.core.Is.is;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Optional;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.openecomp.sdc.be.model.Model;
+import org.openecomp.sdc.be.model.operations.impl.ArtifactTypeOperation;
+import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
+
+public class ArtifactTypeImportManagerTest {
+
+ @InjectMocks
+ private ArtifactTypeImportManager artifactTypeImportManager;
+ @Mock
+ private CommonImportManager commonImportManager;
+ @Mock
+ private ModelOperation modelOperation;
+ @Mock
+ private ArtifactTypeOperation artifactTypeOperation;
+
+ @BeforeEach
+ public void setUp() {
+ MockitoAnnotations.openMocks(this);
+ }
+
+ @Test
+ void createArtifactTypeFromYmlTest() throws IOException {
+ when(commonImportManager.createElementTypesFromYml(Mockito.anyString(), any())).thenCallRealMethod();
+ when(commonImportManager.createElementTypesFromToscaJsonMap(any(), any())).thenCallRealMethod();
+ when(artifactTypeOperation.createArtifactType(any())).thenCallRealMethod();
+ when(modelOperation.findModelByName("test")).thenReturn(Optional.of(new Model("test")));
+ final var result = artifactTypeImportManager
+ .createArtifactTypes(getArtifactsYml(), "test", false);
+ assertThat("The createElementTypesFromYml should be left", result.isLeft(), is(true));
+ final var artifactTypes = result.left().value();
+ assertThat("The artifact types list should have size", artifactTypes, hasSize(1));
+ }
+
+ private String getArtifactsYml() throws IOException {
+ return new String(Files.readAllBytes(Paths.get("src/test/resources/types/artifactTypes.yml")));
+ }
+}
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogicTest.java
index 1c680e5..14d00ef 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogicTest.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogicTest.java
@@ -128,6 +128,7 @@
import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
import org.openecomp.sdc.be.model.operations.impl.ArtifactOperation;
+import org.openecomp.sdc.be.model.operations.impl.ArtifactTypeOperation;
import org.openecomp.sdc.be.model.operations.impl.UserAdminOperation;
import org.openecomp.sdc.be.resources.data.DAOArtifactData;
import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
@@ -197,6 +198,9 @@
private ToscaExportHandler toscaExportHandler;
@Mock
private LifecycleBusinessLogic lifecycleBusinessLogic;
+ @Mock
+ private ArtifactTypeOperation artifactTypeOperation;
+
private Gson gson = new GsonBuilder().setPrettyPrinting().create();
private static List<ArtifactType> getAllTypes() {
@@ -2441,7 +2445,7 @@
toscaExportHandler, csarUtils, lifecycleBusinessLogic,
userBusinessLogic, artifactsResolver, elementDao, groupOperation, groupInstanceOperation,
groupTypeOperation,
- interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
+ interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation, artifactTypeOperation);
artifactsBusinessLogic.setComponentsUtils(componentsUtils);
return artifactsBusinessLogic;
}
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java
index 90c1864..0453dc7 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java
@@ -129,6 +129,7 @@
import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.operations.impl.ArtifactTypeOperation;
import org.openecomp.sdc.be.model.operations.impl.CsarOperation;
import org.openecomp.sdc.be.model.operations.impl.GraphLockOperation;
import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
@@ -214,6 +215,7 @@
private final ToscaExportHandler toscaExportHandler = Mockito.mock(ToscaExportHandler.class);
private final PolicyTypeOperation policyTypeOperation = Mockito.mock(PolicyTypeOperation.class);
private final PolicyBusinessLogic policyBusinessLogic = Mockito.mock(PolicyBusinessLogic.class);
+ private final ArtifactTypeOperation artifactTypeOperation = Mockito.mock(ArtifactTypeOperation.class);
private final DataTypeBusinessLogic dataTypeBusinessLogic = Mockito.mock(DataTypeBusinessLogic.class);
private final PolicyTypeBusinessLogic policyTypeBusinessLogic = Mockito.mock(PolicyTypeBusinessLogic.class);
@@ -231,7 +233,7 @@
ComponentsUtils componentsUtils = new ComponentsUtils(Mockito.mock(AuditingManager.class));
ArtifactsBusinessLogic artifactManager = new ArtifactsBusinessLogic(artifactCassandraDao, toscaExportHandler, csarUtils, lifecycleBl,
userBusinessLogic, artifactsResolver, elementDao, groupOperation, groupInstanceOperation, groupTypeOperation,
- interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
+ interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation, artifactTypeOperation);
CsarOperation csarOperation = Mockito.mock(CsarOperation.class);
@InjectMocks
CsarBusinessLogic csarBusinessLogic ;
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/TypesFetchServletTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/TypesFetchServletTest.java
index 2305cd3..ef4ec18 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/TypesFetchServletTest.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/TypesFetchServletTest.java
@@ -20,7 +20,13 @@
package org.openecomp.sdc.be.servlets;
+import static org.mockito.Mockito.mock;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Response;
import org.junit.Test;
+import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic;
import org.openecomp.sdc.be.components.impl.CapabilitiesBusinessLogic;
import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic;
@@ -32,12 +38,6 @@
import org.openecomp.sdc.be.impl.ServletUtils;
import org.openecomp.sdc.be.user.UserBusinessLogic;
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.core.Response;
-
-import static org.mockito.Mockito.mock;
-
public class TypesFetchServletTest {
private TypesFetchServlet createTestSubject() {
@@ -51,10 +51,11 @@
CapabilitiesBusinessLogic capabilitiesBusinessLogic = mock(CapabilitiesBusinessLogic.class);
InterfaceOperationBusinessLogic interfaceOperationBusinessLogic = mock(InterfaceOperationBusinessLogic.class);
ResourceBusinessLogic resourceBusinessLogic = mock(ResourceBusinessLogic.class);
+ ArtifactsBusinessLogic artifactsBusinessLogic = mock(ArtifactsBusinessLogic.class);
return new TypesFetchServlet(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils,
resourceImportManager, propertyBusinessLogic, relationshipTypeBusinessLogic, capabilitiesBusinessLogic,
- interfaceOperationBusinessLogic, resourceBusinessLogic);
+ interfaceOperationBusinessLogic, resourceBusinessLogic, artifactsBusinessLogic);
}
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 0373aa2..ed9b9a4 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
@@ -23,6 +23,8 @@
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
import fj.data.Either;
@@ -56,6 +58,7 @@
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import org.openecomp.sdc.be.components.impl.ArtifactTypeImportManager;
import org.openecomp.sdc.be.components.impl.CapabilityTypeImportManager;
import org.openecomp.sdc.be.components.impl.CategoriesImportManager;
import org.openecomp.sdc.be.components.impl.DataTypeImportManager;
@@ -124,6 +127,8 @@
private ComponentsUtils componentUtils;
@Mock
private ResponseFormat responseFormat;
+ @Mock
+ private ArtifactTypeImportManager artifactTypeImportManager;
@BeforeAll
public void setup() {
@@ -137,6 +142,7 @@
when(webApplicationContext.getBean(InterfaceLifecycleTypeImportManager.class)).thenReturn(interfaceLifecycleTypeImportManager);
when(webApplicationContext.getBean(GroupTypeImportManager.class)).thenReturn(groupTypeImportManager);
when(webApplicationContext.getBean(CategoriesImportManager.class)).thenReturn(categoriesImportManager);
+ when(webApplicationContext.getBean(ArtifactTypeImportManager.class)).thenReturn(artifactTypeImportManager);
when(webApplicationContext.getBean(ServletUtils.class)).thenReturn(servletUtils);
when(servletUtils.getComponentsUtils()).thenReturn(componentUtils);
when(servletUtils.getUserAdmin()).thenReturn(userAdmin);
@@ -164,7 +170,7 @@
void creatingCapabilityTypeSuccessTest() {
final ImmutablePair<CapabilityTypeDefinition, Boolean> immutablePair = new ImmutablePair<>(new CapabilityTypeDefinition(), true);
final Either<List<ImmutablePair<CapabilityTypeDefinition, Boolean>>, ResponseFormat> either = Either.left(Arrays.asList(immutablePair));
- when(capabilityTypeImportManager.createCapabilityTypes(Mockito.anyString(), Mockito.isNull(), Mockito.anyBoolean())).thenReturn(either);
+ when(capabilityTypeImportManager.createCapabilityTypes(anyString(), Mockito.isNull(), Mockito.anyBoolean())).thenReturn(either);
final FileDataBodyPart filePart = new FileDataBodyPart("capabilityTypeZip", new File("src/test/resources/types/capabilityTypes.zip"));
MultiPart multipartEntity = new FormDataMultiPart();
multipartEntity.bodyPart(filePart);
@@ -178,7 +184,7 @@
@Test
void creatingCapabilityType_Either_isRight_FailedTest() {
final Either<List<ImmutablePair<CapabilityTypeDefinition, Boolean>>, ResponseFormat> either = Either.right(new ResponseFormat(500));
- when(capabilityTypeImportManager.createCapabilityTypes(Mockito.anyString(), Mockito.isNull(), Mockito.anyBoolean())).thenReturn(either);
+ when(capabilityTypeImportManager.createCapabilityTypes(anyString(), Mockito.isNull(), Mockito.anyBoolean())).thenReturn(either);
final FileDataBodyPart filePart = new FileDataBodyPart("capabilityTypeZip", new File("src/test/resources/types/capabilityTypes.zip"));
MultiPart multipartEntity = new FormDataMultiPart();
multipartEntity.bodyPart(filePart);
@@ -193,7 +199,7 @@
void creatingCapabilityTypeWithModelSuccessTest() {
final ImmutablePair<CapabilityTypeDefinition, Boolean> immutablePair = new ImmutablePair<>(new CapabilityTypeDefinition(), true);
final Either<List<ImmutablePair<CapabilityTypeDefinition, Boolean>>, ResponseFormat> either = Either.left(Arrays.asList(immutablePair));
- when(capabilityTypeImportManager.createCapabilityTypes(Mockito.anyString(), Mockito.eq("testModel"), Mockito.anyBoolean())).thenReturn(
+ when(capabilityTypeImportManager.createCapabilityTypes(anyString(), Mockito.eq("testModel"), Mockito.anyBoolean())).thenReturn(
either);
final FileDataBodyPart filePart = new FileDataBodyPart("capabilityTypeZip", new File("src/test/resources/types/capabilityTypes.zip"));
FormDataMultiPart multipartEntity = new FormDataMultiPart();
@@ -210,7 +216,7 @@
void creatingDataTypeSuccessTest() {
final ImmutablePair<DataTypeDefinition, Boolean> immutablePair = new ImmutablePair<>(new DataTypeDefinition(), true);
final Either<List<ImmutablePair<DataTypeDefinition, Boolean>>, ResponseFormat> either = Either.left(Arrays.asList(immutablePair));
- when(dataTypeImportManager.createDataTypes(Mockito.anyString(), Mockito.isNull(), Mockito.anyBoolean())).thenReturn(either);
+ when(dataTypeImportManager.createDataTypes(anyString(), Mockito.isNull(), Mockito.anyBoolean())).thenReturn(either);
final FileDataBodyPart filePart = new FileDataBodyPart("dataTypesZip", new File("src/test/resources/types/datatypes.zip"));
MultiPart multipartEntity = new FormDataMultiPart();
multipartEntity.bodyPart(filePart);
@@ -224,7 +230,7 @@
@Test
void creatingDataType_Either_isRight_FailedTest() {
final Either<List<ImmutablePair<DataTypeDefinition, Boolean>>, ResponseFormat> either = Either.right(new ResponseFormat(500));
- when(dataTypeImportManager.createDataTypes(Mockito.anyString(), Mockito.isNull(), Mockito.anyBoolean())).thenReturn(either);
+ when(dataTypeImportManager.createDataTypes(anyString(), Mockito.isNull(), Mockito.anyBoolean())).thenReturn(either);
final FileDataBodyPart filePart = new FileDataBodyPart("dataTypesZip", new File("src/test/resources/types/datatypes.zip"));
MultiPart multipartEntity = new FormDataMultiPart();
multipartEntity.bodyPart(filePart);
@@ -239,7 +245,7 @@
void creatingDataType_AlreadyExists_FailedTest() {
final ImmutablePair<DataTypeDefinition, Boolean> immutablePair = new ImmutablePair<>(new DataTypeDefinition(), false);
final Either<List<ImmutablePair<DataTypeDefinition, Boolean>>, ResponseFormat> either = Either.left(Arrays.asList(immutablePair));
- when(dataTypeImportManager.createDataTypes(Mockito.anyString(), Mockito.isNull(), Mockito.anyBoolean())).thenReturn(either);
+ when(dataTypeImportManager.createDataTypes(anyString(), Mockito.isNull(), Mockito.anyBoolean())).thenReturn(either);
final FileDataBodyPart filePart = new FileDataBodyPart("dataTypesZip", new File("src/test/resources/types/datatypes.zip"));
MultiPart multipartEntity = new FormDataMultiPart();
multipartEntity.bodyPart(filePart);
@@ -254,7 +260,7 @@
void creatingDataTypeWithModelSuccessTest() {
final ImmutablePair<DataTypeDefinition, Boolean> immutablePair = new ImmutablePair<>(new DataTypeDefinition(), true);
final Either<List<ImmutablePair<DataTypeDefinition, Boolean>>, ResponseFormat> either = Either.left(Arrays.asList(immutablePair));
- when(dataTypeImportManager.createDataTypes(Mockito.anyString(), Mockito.eq("testModel"), Mockito.anyBoolean())).thenReturn(either);
+ when(dataTypeImportManager.createDataTypes(anyString(), Mockito.eq("testModel"), Mockito.anyBoolean())).thenReturn(either);
final FileDataBodyPart filePart = new FileDataBodyPart("dataTypesZip", new File("src/test/resources/types/datatypes.zip"));
FormDataMultiPart multipartEntity = new FormDataMultiPart();
multipartEntity.bodyPart(filePart);
@@ -270,7 +276,7 @@
void creatingRelationshipTypeSuccessTest() {
final ImmutablePair<RelationshipTypeDefinition, Boolean> immutablePair = new ImmutablePair<>(new RelationshipTypeDefinition(), true);
final Either<List<ImmutablePair<RelationshipTypeDefinition, Boolean>>, ResponseFormat> either = Either.left(Arrays.asList(immutablePair));
- when(relationshipTypeImportManager.createRelationshipTypes(Mockito.anyString(), Mockito.isNull(), Mockito.anyBoolean())).thenReturn(either);
+ when(relationshipTypeImportManager.createRelationshipTypes(anyString(), Mockito.isNull(), Mockito.anyBoolean())).thenReturn(either);
final FileDataBodyPart filePart = new FileDataBodyPart("relationshipTypeZip", new File("src/test/resources/types/relationship.zip"));
MultiPart multipartEntity = new FormDataMultiPart();
multipartEntity.bodyPart(filePart);
@@ -285,7 +291,7 @@
void creatingRelationshipType_AlreadyExists_FailedTest() {
final ImmutablePair<RelationshipTypeDefinition, Boolean> immutablePair = new ImmutablePair<>(new RelationshipTypeDefinition(), false);
final Either<List<ImmutablePair<RelationshipTypeDefinition, Boolean>>, ResponseFormat> either = Either.left(Arrays.asList(immutablePair));
- when(relationshipTypeImportManager.createRelationshipTypes(Mockito.anyString(), Mockito.isNull(), Mockito.anyBoolean())).thenReturn(either);
+ when(relationshipTypeImportManager.createRelationshipTypes(anyString(), Mockito.isNull(), Mockito.anyBoolean())).thenReturn(either);
final FileDataBodyPart filePart = new FileDataBodyPart("relationshipTypeZip", new File("src/test/resources/types/relationship.zip"));
MultiPart multipartEntity = new FormDataMultiPart();
multipartEntity.bodyPart(filePart);
@@ -300,7 +306,7 @@
void creatingRelationshipTypeWithModelSuccessTest() {
final ImmutablePair<RelationshipTypeDefinition, Boolean> immutablePair = new ImmutablePair<>(new RelationshipTypeDefinition(), true);
final Either<List<ImmutablePair<RelationshipTypeDefinition, Boolean>>, ResponseFormat> either = Either.left(Arrays.asList(immutablePair));
- when(relationshipTypeImportManager.createRelationshipTypes(Mockito.anyString(), Mockito.eq("testModel"), Mockito.anyBoolean())).thenReturn(
+ when(relationshipTypeImportManager.createRelationshipTypes(anyString(), Mockito.eq("testModel"), Mockito.anyBoolean())).thenReturn(
either);
final FileDataBodyPart filePart = new FileDataBodyPart("relationshipTypeZip", new File("src/test/resources/types/relationship.zip"));
FormDataMultiPart multipartEntity = new FormDataMultiPart();
@@ -366,7 +372,7 @@
void creatingInterfaceLifecycleTypeSuccessTest() {
final ImmutablePair<InterfaceDefinition, Boolean> immutablePair = new ImmutablePair<>(new InterfaceDefinition(), true);
final Either<List<InterfaceDefinition>, ResponseFormat> either = Either.left(emptyList());
- when(interfaceLifecycleTypeImportManager.createLifecycleTypes(Mockito.anyString(), Mockito.isNull(), Mockito.anyBoolean()))
+ when(interfaceLifecycleTypeImportManager.createLifecycleTypes(anyString(), Mockito.isNull(), Mockito.anyBoolean()))
.thenReturn(either);
final FileDataBodyPart filePart = new FileDataBodyPart("interfaceLifecycleTypeZip",
new File("src/test/resources/types/interfaceLifecycleTypes.zip"));
@@ -382,7 +388,7 @@
@Test
void creatingInterfaceLifecycleType_Either_isRight_FailedTest() {
final Either<List<InterfaceDefinition>, ResponseFormat> either = Either.right(new ResponseFormat(500));
- when(interfaceLifecycleTypeImportManager.createLifecycleTypes(Mockito.anyString(), Mockito.isNull(), Mockito.anyBoolean()))
+ when(interfaceLifecycleTypeImportManager.createLifecycleTypes(anyString(), Mockito.isNull(), Mockito.anyBoolean()))
.thenReturn(either);
final FileDataBodyPart filePart = new FileDataBodyPart("interfaceLifecycleTypeZip",
new File("src/test/resources/types/interfaceLifecycleTypes.zip"));
@@ -399,7 +405,7 @@
void creatingInterfaceLifecycleTypeWithModelSuccessTest() {
final ImmutablePair<InterfaceDefinition, Boolean> immutablePair = new ImmutablePair<>(new InterfaceDefinition(), true);
final Either<List<InterfaceDefinition>, ResponseFormat> either = Either.left(emptyList());
- when(interfaceLifecycleTypeImportManager.createLifecycleTypes(Mockito.anyString(), Mockito.eq("testModel"), Mockito.anyBoolean()))
+ when(interfaceLifecycleTypeImportManager.createLifecycleTypes(anyString(), Mockito.eq("testModel"), Mockito.anyBoolean()))
.thenReturn(either);
final FileDataBodyPart filePart = new FileDataBodyPart("interfaceLifecycleTypeZip",
new File("src/test/resources/types/interfaceLifecycleTypes.zip"));
@@ -465,7 +471,7 @@
@Test
void creatingCategoriesTypeSuccessTest() {
final Either<Map<String, List<CategoryDefinition>>, ResponseFormat> either = Either.left(emptyMap());
- when(categoriesImportManager.createCategories(Mockito.anyString())).thenReturn(either);
+ when(categoriesImportManager.createCategories(anyString())).thenReturn(either);
final FileDataBodyPart filePart = new FileDataBodyPart("categoriesZip", new File("src/test/resources/types/categoryTypes.zip"));
MultiPart multipartEntity = new FormDataMultiPart();
multipartEntity.bodyPart(filePart);
@@ -476,6 +482,30 @@
assertEquals(HttpStatus.CREATED_201, response.getStatus());
}
+ @Test
+ void creatingArtifactTypeSuccessTest() {
+ when(artifactTypeImportManager.createArtifactTypes(anyString(), anyString(), anyBoolean()))
+ .thenReturn(Either.left(emptyList()));
+ final FileDataBodyPart filePart = new FileDataBodyPart("artifactsZip", new File("src/test/resources/types/artifactTypes.zip"));
+ final FormDataMultiPart multipartEntity = new FormDataMultiPart();
+ multipartEntity.bodyPart(filePart);
+ multipartEntity.field("model", "testModel");
+ final Response response = target().path("/v1/catalog/uploadType/artifactTypes").request(MediaType.APPLICATION_JSON)
+ .post(Entity.entity(multipartEntity, MediaType.MULTIPART_FORM_DATA), Response.class);
+ assertEquals(HttpStatus.CREATED_201, response.getStatus());
+ }
+
+ @Test
+ void creatingArtifactTypeFailTest() {
+ when(artifactTypeImportManager.createArtifactTypes(anyString(), anyString(), anyBoolean()))
+ .thenReturn(Either.right(new ResponseFormat(500)));
+ final FormDataMultiPart multipartEntity = new FormDataMultiPart();
+ multipartEntity.field("model", "testModel");
+ final Response response = target().path("/v1/catalog/uploadType/artifactTypes").request(MediaType.APPLICATION_JSON)
+ .post(Entity.entity(multipartEntity, MediaType.MULTIPART_FORM_DATA), Response.class);
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR_500, response.getStatus());
+ }
+
@Override
protected void configureClient(ClientConfig config) {
config.register(MultiPartFeature.class);
@@ -489,7 +519,7 @@
final TypesUploadServlet typesUploadServlet = new TypesUploadServlet(null, null, componentUtils,
servletUtils, null, capabilityTypeImportManager, interfaceLifecycleTypeImportManager,
categoriesImportManager, dataTypeImportManager,
- groupTypeImportManager, policyTypeImportManager, relationshipTypeImportManager);
+ groupTypeImportManager, policyTypeImportManager, relationshipTypeImportManager, artifactTypeImportManager);
final ResourceConfig resourceConfig = new ResourceConfig().register(typesUploadServlet);
resourceConfig.register(MultiPartFeature.class);
diff --git a/catalog-be/src/test/resources/types/artifactTypes.yml b/catalog-be/src/test/resources/types/artifactTypes.yml
new file mode 100644
index 0000000..9d21830
--- /dev/null
+++ b/catalog-be/src/test/resources/types/artifactTypes.yml
@@ -0,0 +1,10 @@
+tosca.artifacts.Implementation.nfv.artifactTest:
+ derived_from: tosca.artifacts.Implementation
+ description: artifacts for Mistral workflows
+ mime_type: application/x-yaml
+ file_ext: [ yaml ]
+ properties:
+ prop_A:
+ type: string
+ prop_B:
+ type: string
diff --git a/catalog-be/src/test/resources/types/artifactTypes.zip b/catalog-be/src/test/resources/types/artifactTypes.zip
new file mode 100644
index 0000000..2e3ed3b
--- /dev/null
+++ b/catalog-be/src/test/resources/types/artifactTypes.zip
Binary files differ
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 800fc67..1862f85 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
@@ -126,7 +126,8 @@
ABSTRACT, NORMAL,
//including default imports in CSAR related
CSAR_TOSCA_IMPORTS_ERROR,
+ //ArtifactType
+ ARTIFACT_TYPE_ALREADY_EXIST, FAILED_CREATE_ARTIFACTS_TYPES,
//TOSCA node types
INVALID_NODE_TYPES_YAML
-
}
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 1c500e7..11de2a3 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
@@ -20,6 +20,7 @@
package org.openecomp.sdc.be.dao.graph;
import java.util.Map;
+
import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum;
import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
@@ -29,6 +30,7 @@
import org.openecomp.sdc.be.resources.data.AdditionalInfoParameterData;
import org.openecomp.sdc.be.resources.data.AnnotationTypeData;
import org.openecomp.sdc.be.resources.data.ArtifactData;
+import org.openecomp.sdc.be.resources.data.ArtifactTypeData;
import org.openecomp.sdc.be.resources.data.AttributeData;
import org.openecomp.sdc.be.resources.data.AttributeValueData;
import org.openecomp.sdc.be.resources.data.CapabilityData;
@@ -260,6 +262,9 @@
case Model:
element = clazz.cast(new ModelData(properties));
break;
+ case ArtifactType:
+ element = clazz.cast(new ArtifactTypeData(properties));
+ break;
default:
break;
}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/ArtifactTypeData.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/ArtifactTypeData.java
new file mode 100644
index 0000000..e138016
--- /dev/null
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/ArtifactTypeData.java
@@ -0,0 +1,75 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.sdc.be.resources.data;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
+import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
+import org.openecomp.sdc.be.datatypes.elements.ArtifactTypeDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+
+public class ArtifactTypeData extends GraphNode {
+
+ private ArtifactTypeDataDefinition artifactTypeDefinition;
+
+ public ArtifactTypeData() {
+ super(NodeTypeEnum.Interface);
+ artifactTypeDefinition = new ArtifactTypeDataDefinition();
+ }
+
+ public ArtifactTypeData(ArtifactTypeDataDefinition artifactTypeDefinition) {
+ super(NodeTypeEnum.ArtifactType);
+ this.artifactTypeDefinition = artifactTypeDefinition;
+ }
+
+ public ArtifactTypeData(Map<String, Object> properties) {
+ this();
+ artifactTypeDefinition.setUniqueId((String) properties.get(GraphPropertiesDictionary.UNIQUE_ID.getProperty()));
+ artifactTypeDefinition.setType((String) properties.get(GraphPropertiesDictionary.TYPE.getProperty()));
+ artifactTypeDefinition.setDescription((String) properties.get(GraphPropertiesDictionary.DESCRIPTION.getProperty()));
+ artifactTypeDefinition.setCreationDate((Long) properties.get(GraphPropertiesDictionary.CREATION_DATE.getProperty()));
+ artifactTypeDefinition.setLastUpdated((Long) properties.get(GraphPropertiesDictionary.LAST_UPDATE_DATE.getProperty()));
+ }
+
+ public ArtifactTypeDataDefinition getArtifactTypeDataDefinition() {
+ return artifactTypeDefinition;
+ }
+
+ public void setArtifactTypeDataDefinition(ArtifactTypeDataDefinition artifactTypeDefinition) {
+ this.artifactTypeDefinition = artifactTypeDefinition;
+ }
+
+ @Override
+ public String getUniqueId() {
+ return artifactTypeDefinition.getUniqueId();
+ }
+
+ @Override
+ public Map<String, Object> toGraphMap() {
+ Map<String, Object> map = new HashMap<>();
+ addIfExists(map, GraphPropertiesDictionary.UNIQUE_ID, artifactTypeDefinition.getUniqueId());
+ addIfExists(map, GraphPropertiesDictionary.TYPE, artifactTypeDefinition.getType());
+ addIfExists(map, GraphPropertiesDictionary.CREATION_DATE, artifactTypeDefinition.getCreationDate());
+ addIfExists(map, GraphPropertiesDictionary.LAST_UPDATE_DATE, artifactTypeDefinition.getLastUpdated());
+ addIfExists(map, GraphPropertiesDictionary.DESCRIPTION, artifactTypeDefinition.getDescription());
+ return map;
+ }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactTypeDefinition.java
new file mode 100644
index 0000000..692e9b9
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactTypeDefinition.java
@@ -0,0 +1,51 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.sdc.be.model;
+
+import java.util.List;
+
+import org.openecomp.sdc.be.datatypes.elements.ArtifactTypeDataDefinition;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@ToString
+public class ArtifactTypeDefinition extends ArtifactTypeDataDefinition {
+
+ private List<PropertyDefinition> properties;
+
+ public ArtifactTypeDefinition(final ArtifactTypeDataDefinition artifactTypeDataDefinition) {
+ super(artifactTypeDataDefinition);
+ }
+
+ public ArtifactTypeDefinition(final ArtifactTypeDefinition artifactTypeDataDefinition) {
+ super(artifactTypeDataDefinition);
+ this.setName(artifactTypeDataDefinition.getName());
+ this.setDerivedFrom(artifactTypeDataDefinition.getDerivedFrom());
+ this.setUniqueId(artifactTypeDataDefinition.getUniqueId());
+ this.setDescription(artifactTypeDataDefinition.getDescription());
+ this.setModel(artifactTypeDataDefinition.getModel());
+ }
+
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/normatives/ElementTypeEnum.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/normatives/ElementTypeEnum.java
index 57ca559..e421e61 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/normatives/ElementTypeEnum.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/normatives/ElementTypeEnum.java
@@ -32,7 +32,8 @@
DATA_TYPE("data_types"),
CAPABILITY_TYPE("capability_types"),
INTERFACE_LIFECYCLE_TYPE("interface_types"),
- RELATIONSHIP_TYPE("relationship_types");
+ RELATIONSHIP_TYPE("relationship_types"),
+ ARTIFACT_TYPE("artifact_types");
private final String toscaEntryName;
}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IArtifactTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IArtifactTypeOperation.java
new file mode 100644
index 0000000..22e6f00
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IArtifactTypeOperation.java
@@ -0,0 +1,33 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.sdc.be.model.operations.api;
+
+import java.util.Map;
+
+import org.openecomp.sdc.be.model.ArtifactTypeDefinition;
+
+public interface IArtifactTypeOperation {
+
+ ArtifactTypeDefinition createArtifactType(final ArtifactTypeDefinition artifactType);
+
+ ArtifactTypeDefinition createArtifactType(final ArtifactTypeDefinition artifactType, final boolean inTransaction);
+
+ Map<String, ArtifactTypeDefinition> getAllArtifactTypes(final String model);
+
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ArtifactTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ArtifactTypeOperation.java
new file mode 100644
index 0000000..4b1dcfb
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ArtifactTypeOperation.java
@@ -0,0 +1,356 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.be.model.operations.impl;
+
+import fj.data.Either;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
+import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao;
+import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
+import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
+import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.be.model.ArtifactTypeDefinition;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.ModelOperationExceptionSupplier;
+import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.OperationException;
+import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
+import org.openecomp.sdc.be.model.operations.api.IArtifactTypeOperation;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.resources.data.ArtifactTypeData;
+import org.openecomp.sdc.be.resources.data.ModelData;
+import org.openecomp.sdc.be.resources.data.PropertyData;
+import org.openecomp.sdc.be.resources.data.UniqueIdData;
+import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * This class is responsible for handling all operations for the TOSCA artifact types
+ */
+@Component("artifact-type-operation")
+public class ArtifactTypeOperation implements IArtifactTypeOperation {
+
+ private static final Logger LOGGER = Logger.getLogger(ArtifactTypeOperation.class.getName());
+
+ private final JanusGraphGenericDao janusGraphGenericDao;
+ private final PropertyOperation propertyOperation;
+ private final DerivedFromOperation derivedFromOperation;
+ private final ModelOperation modelOperation;
+
+ @Autowired
+ public ArtifactTypeOperation(final JanusGraphGenericDao janusGraphGenericDao,
+ final PropertyOperation propertyOperation,
+ final DerivedFromOperation derivedFromOperation,
+ final ModelOperation modelOperation) {
+ this.janusGraphGenericDao = janusGraphGenericDao;
+ this.propertyOperation = propertyOperation;
+ this.derivedFromOperation = derivedFromOperation;
+ this.modelOperation = modelOperation;
+ }
+
+ /**
+ * Creates a TOSCA artifact types
+ * @param artifactType the TOSCA artifact types definition to be created
+ * @return the created TOSCA artifact types definition
+ */
+ @Override
+ public ArtifactTypeDefinition createArtifactType(final ArtifactTypeDefinition artifactType) {
+ return createArtifactType(artifactType, false);
+ }
+
+ @Override
+ public ArtifactTypeDefinition createArtifactType(final ArtifactTypeDefinition artifactType,
+ final boolean inTransaction) {
+ Either<ArtifactTypeData, JanusGraphOperationStatus> createNodeResult = null;
+ try {
+ artifactType.setUniqueId(UniqueIdBuilder.buildArtifactTypeUid(artifactType.getModel(), artifactType.getType()));
+ final ArtifactTypeData artifactTypeData = new ArtifactTypeData(artifactType);
+ final Either<ArtifactTypeData, JanusGraphOperationStatus> existArtifact = janusGraphGenericDao
+ .getNode(artifactTypeData.getUniqueIdKey(), artifactTypeData.getUniqueId(), ArtifactTypeData.class);
+ if (!existArtifact.isLeft()) {
+ createNodeResult = janusGraphGenericDao.createNode(artifactTypeData, ArtifactTypeData.class);
+ if (createNodeResult.isRight()) {
+ final JanusGraphOperationStatus operationStatus = createNodeResult.right().value();
+ LOGGER.error(EcompLoggerErrorCode.DATA_ERROR,
+ "Failed to add artifact type {} to graph. Operation status {}", artifactType.getType(), operationStatus);
+ throw new OperationException(ActionStatus.GENERAL_ERROR,
+ String.format("Failed to create artifact type %s with status %s", artifactType.getType(),
+ DaoStatusConverter.convertJanusGraphStatusToStorageStatus(operationStatus)));
+ }
+ addPropertiesToArtifactType(artifactType);
+ addModelRelation(artifactType);
+ addDerivedFromRelation(artifactType);
+ return convertArtifactDataDefinition(createNodeResult.left().value());
+ } else {
+ LOGGER.debug("Artifact type already exist {}", artifactType);
+ return convertArtifactDataDefinition(existArtifact.left().value());
+ }
+ } finally {
+ if (!inTransaction) {
+ if (createNodeResult == null || createNodeResult.isRight()) {
+ LOGGER.debug("Rollback on graph.");
+ janusGraphGenericDao.rollback();
+ } else {
+ janusGraphGenericDao.commit();
+ }
+ }
+ }
+ }
+
+ /**
+ * Finds all TOSCA artifact types applicable to the given model name
+ * @param model model name
+ * @return all the TOSCA artifact types found
+ */
+ @Override
+ public Map<String, ArtifactTypeDefinition> getAllArtifactTypes(final String model) {
+ final Either<List<ArtifactTypeData>, JanusGraphOperationStatus> artifactTypes =
+ janusGraphGenericDao.getByCriteriaForModel(NodeTypeEnum.ArtifactType, Collections.emptyMap(), model, ArtifactTypeData.class);
+ if (artifactTypes.isRight()) {
+ if (JanusGraphOperationStatus.NOT_FOUND == artifactTypes.right().value()) {
+ return Collections.emptyMap();
+ }
+ throw new OperationException(ActionStatus.GENERAL_ERROR,
+ String.format("Failed to find artifact on JanusGraph with status %s",
+ DaoStatusConverter.convertJanusGraphStatusToStorageStatus(artifactTypes.right().value())));
+ }
+ final Map<String, ArtifactTypeDefinition> artifactTypeDefinitionTypes = new HashMap<>();
+ final List<ArtifactTypeDefinition> artifactTypeList = artifactTypes.left().value().stream()
+ .map(this::convertArtifactDataDefinition)
+ .filter(artifactTypeDefinition -> artifactTypeDefinition.getUniqueId().equalsIgnoreCase(UniqueIdBuilder
+ .buildArtifactTypeUid(artifactTypeDefinition.getModel(), artifactTypeDefinition.getType())))
+ .collect(Collectors.toList());
+ for (final ArtifactTypeDefinition type : artifactTypeList) {
+ artifactTypeDefinitionTypes.put(type.getUniqueId(), type);
+ }
+ return artifactTypeDefinitionTypes;
+ }
+
+ /**
+ * Coverts the given artifact type data into a TOSCA artifact types definition
+ * @param artifactTypeData artifact type data representation
+ * @return the TOSCA artifact types definition
+ */
+ private ArtifactTypeDefinition convertArtifactDataDefinition(final ArtifactTypeData artifactTypeData) {
+ LOGGER.debug("The object returned after create tosca artifact type is {}", artifactTypeData);
+ final ArtifactTypeDefinition artifactType = new ArtifactTypeDefinition(artifactTypeData.getArtifactTypeDataDefinition());
+ final var modelAssociatedToArtifactOptional = getModelAssociatedToArtifact(artifactTypeData.getUniqueId());
+ if (!modelAssociatedToArtifactOptional.isEmpty()) {
+ artifactType.setModel(modelAssociatedToArtifactOptional.get());
+ }
+ artifactType.setType(artifactTypeData.getArtifactTypeDataDefinition().getType());
+ final ArtifactTypeData derivedFromNode = fillDerivedFrom(artifactType);
+ fillProperties(artifactType, derivedFromNode);
+ return artifactType;
+ }
+
+ /**
+ * Finds an artifact type data on JanusGraph based on the given parameters
+ * @param type the artifact type derived from
+ * @param model the model name
+ * @return the optional artifact type data found
+ */
+ private Optional<ArtifactTypeData> getLatestArtifactTypeByType(final String type, final String model) {
+ final Map<String, Object> mapCriteria = new HashMap<>();
+ mapCriteria.put(GraphPropertiesDictionary.TYPE.getProperty(), type);
+ final Either<List<ArtifactTypeData>, JanusGraphOperationStatus> result = janusGraphGenericDao.getByCriteriaForModel(NodeTypeEnum.ArtifactType,
+ mapCriteria, model, ArtifactTypeData.class);
+ if (result.isRight()) {
+ final JanusGraphOperationStatus status = result.right().value();
+ if (JanusGraphOperationStatus.NOT_FOUND == status) {
+ return Optional.empty();
+ }
+ throw new OperationException(ActionStatus.GENERAL_ERROR,
+ String.format("Failed to find artifact by type on JanusGraph with status %s",
+ DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)));
+ }
+ return Optional.of(result.left().value().get(0));
+ }
+
+ /**
+ * Creates the derivedFrom relation for the given TOSCA artifact types
+ * @param artifactType the TOSCA artifact types definition
+ */
+ private void addDerivedFromRelation(final ArtifactTypeDefinition artifactType) {
+ final String derivedFrom = artifactType.getDerivedFrom();
+ final String artifactId = artifactType.getUniqueId();
+ if (derivedFrom.isEmpty()) {
+ return;
+ }
+ final var getArtifactTypeOptional = getLatestArtifactTypeByType(derivedFrom, artifactType.getModel());
+ if (getArtifactTypeOptional.isPresent()) {
+ if (derivedFromOperation.addDerivedFromRelation(artifactId, getArtifactTypeOptional.get().getUniqueId(),
+ NodeTypeEnum.ArtifactType).isRight()) {
+ throw new OperationException(ActionStatus.GENERAL_ERROR,
+ String.format("Failed creating derivedFrom relation for artifact type %s", artifactType.getType()));
+ }
+ }
+ }
+
+ /**
+ * Adds a property definition to the given TOSCA artifact types definition
+ * @param artifactType the TOSCA artifact types
+ */
+ private void addPropertiesToArtifactType(final ArtifactTypeDefinition artifactType) {
+ final List<PropertyDefinition> properties = artifactType.getProperties();
+ final Either<Map<String, PropertyData>, JanusGraphOperationStatus> addPropertiesToArtifactType =
+ propertyOperation.addPropertiesToElementType(artifactType.getUniqueId(), NodeTypeEnum.ArtifactType, properties);
+ if (addPropertiesToArtifactType.isRight()) {
+ throw new OperationException(ActionStatus.GENERAL_ERROR,
+ String.format("Failed creating properties for artifact type %s with status %s",
+ artifactType.getType(), DaoStatusConverter.convertJanusGraphStatusToStorageStatus(addPropertiesToArtifactType.right().value())));
+ }
+ }
+
+ /**
+ * Creates an edge between the given TOSCA artifact types and it`s model
+ * @param artifactType the TOSCA artifact types
+ */
+ private void addModelRelation(final ArtifactTypeDefinition artifactType) {
+ final String model = artifactType.getModel();
+ if (StringUtils.isNotEmpty(model)) {
+ final GraphNode from = new UniqueIdData(NodeTypeEnum.Model, UniqueIdBuilder.buildModelUid(model));
+ final GraphNode to = new UniqueIdData(NodeTypeEnum.ArtifactType, artifactType.getUniqueId());
+ LOGGER.info("Connecting model {} to type {}", from, to);
+ final Either<GraphRelation, JanusGraphOperationStatus> status = janusGraphGenericDao.createRelation(from,
+ to, GraphEdgeLabels.MODEL_ELEMENT, Collections.emptyMap());
+ if (status.isRight()) {
+ throw new OperationException(ActionStatus.GENERAL_ERROR,
+ String.format("Failed creating relation between model %s and artifact type %s with status %s",
+ model, artifactType.getType(), DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status.right().value())));
+ }
+ }
+ }
+
+ /**
+ * Finds a model associated to the given artifact type unique id
+ * @param uid the TOSCA artifact types unique id
+ * @return
+ */
+ private Optional<String> getModelAssociatedToArtifact(final String uid) {
+ final Either<ImmutablePair<ModelData, GraphEdge>, JanusGraphOperationStatus> model =
+ janusGraphGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), uid,
+ GraphEdgeLabels.MODEL_ELEMENT, NodeTypeEnum.Model, ModelData.class);
+ if (model.isLeft()) {
+ return Optional.ofNullable(model.left().value().getLeft().getName());
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Finds the derived from for teh given TOSCA artifact types
+ * @param artifactType
+ * @return
+ */
+ private ArtifactTypeData fillDerivedFrom(final ArtifactTypeDefinition artifactType) {
+ final Either<ArtifactTypeData, StorageOperationStatus> result = derivedFromOperation
+ .getDerivedFromChild(artifactType.getUniqueId(), NodeTypeEnum.ArtifactType, ArtifactTypeData.class)
+ .right().bind(this::handleDerivedFromNotExist).left()
+ .map(derivedFrom -> setDerivedFrom(artifactType, derivedFrom));
+ if (result.isRight()) {
+ throw new OperationException(ActionStatus.GENERAL_ERROR,
+ String.format("Failed fetching derivedFrom for artifact type %s with status %s",
+ artifactType.getType(), result.right().value()));
+ }
+ return result.left().value();
+ }
+
+ private Either<ArtifactTypeData, StorageOperationStatus> handleDerivedFromNotExist(final StorageOperationStatus storageOperationStatus) {
+ if (storageOperationStatus == StorageOperationStatus.NOT_FOUND) {
+ return Either.left(null);
+ }
+ return Either.right(storageOperationStatus);
+ }
+
+ private ArtifactTypeData setDerivedFrom(final ArtifactTypeDefinition artifactType, final ArtifactTypeData derivedFrom) {
+ if (derivedFrom != null) {
+ artifactType.setDerivedFrom(derivedFrom.getArtifactTypeDataDefinition().getType());
+ }
+ return derivedFrom;
+ }
+
+ /**
+ * Finds all properties for the given TOSCA artifact types
+ * @param artifactType the TOSCA artifact types
+ * @param derivedFromNode the TOSCA artifact types derived from
+ */
+ private void fillProperties(final ArtifactTypeDefinition artifactType, final ArtifactTypeData derivedFromNode) {
+ final Either<List<PropertyDefinition>, StorageOperationStatus> result =
+ propertyOperation.findPropertiesOfNode(NodeTypeEnum.ArtifactType, artifactType.getUniqueId()).right()
+ .bind(this::handleNoProperties).left().bind(propsMap -> fillDerivedFromProperties(artifactType,
+ derivedFromNode, new ArrayList<>(propsMap.values())));
+ if (result.isRight()) {
+ throw new OperationException(ActionStatus.GENERAL_ERROR,
+ String.format("Failed fetching properties for artifact type %s with status %s",
+ artifactType.getType(), result.right().value()));
+ }
+ }
+
+ private Either<Map<String, PropertyDefinition>, StorageOperationStatus> handleNoProperties(
+ final JanusGraphOperationStatus janusGraphOperationStatus) {
+ if (janusGraphOperationStatus == JanusGraphOperationStatus.NOT_FOUND) {
+ return Either.left(new HashMap<>());
+ }
+ return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(janusGraphOperationStatus));
+ }
+
+ private Either<List<PropertyDefinition>, StorageOperationStatus> fillDerivedFromProperties(final ArtifactTypeDefinition artifactType,
+ final ArtifactTypeData derivedFromNode,
+ final List<PropertyDefinition> artifactTypeProperties)
+ {
+ if (derivedFromNode == null) {
+ artifactType.setProperties(artifactTypeProperties);
+ return Either.left(artifactTypeProperties);
+ }
+ return propertyOperation
+ .getAllPropertiesRec(derivedFromNode.getUniqueId(), NodeTypeEnum.ArtifactType, ArtifactTypeData.class)
+ .left().map(derivedFromProps -> {
+ artifactTypeProperties.addAll(derivedFromProps);
+ return artifactTypeProperties;
+ }).left().map(allProps -> {
+ artifactType.setProperties(allProps);
+ return allProps;
+ });
+ }
+
+ /**
+ * The Model field is an optional entry when uploading a resource. If the field is present, it validates if the Model name exists.
+ * @param modelName Model names declared on the resource json representation
+ */
+ public void validateModel(final String modelName) {
+ if (modelOperation.findModelByName(modelName).isEmpty()) {
+ LOGGER.error(EcompLoggerErrorCode.DATA_ERROR,"Could not find model name {}", modelName);
+ throw ModelOperationExceptionSupplier.invalidModel(modelName).get();
+ }
+ }
+}
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 8f1cbae..225fe6c 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
@@ -218,4 +218,8 @@
public static String buildModelUid(final String modelName) {
return NodeTypeEnum.Model.getName() + DOT + modelName;
}
+
+ public static String buildArtifactTypeUid(final String modelName, final String name) {
+ return StringUtils.isEmpty(modelName) ? name + DOT + "artifactype" : modelName + DOT + name + DOT + "artifactype";
+ }
}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ArtifactTypeDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ArtifactTypeDataDefinition.java
new file mode 100644
index 0000000..576c60b
--- /dev/null
+++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ArtifactTypeDataDefinition.java
@@ -0,0 +1,50 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.openecomp.sdc.be.datatypes.elements;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@ToString
+public class ArtifactTypeDataDefinition extends ToscaDataDefinition {
+
+ private String name;
+ private String uniqueId;
+ private String derivedFrom;
+ private String description;
+ private String model;
+ private Long creationDate;
+ private Long lastUpdated;
+
+ public ArtifactTypeDataDefinition(ArtifactTypeDataDefinition p) {
+ this.name = p.name;
+ this.uniqueId = p.uniqueId;
+ this.derivedFrom = p.derivedFrom;
+ this.description = p.description;
+ this.creationDate = p.creationDate;
+ this.lastUpdated = p.lastUpdated;
+ this.model = p.model;
+ }
+}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/NodeTypeEnum.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/NodeTypeEnum.java
index 2a927b8..1711e7f 100644
--- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/NodeTypeEnum.java
+++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/NodeTypeEnum.java
@@ -64,7 +64,8 @@
GroupInstance("groupInstance"),
AnnotationType("annotationType"),
Component("component"),
- Model("model");
+ Model("model"),
+ ArtifactType("artifactType");
// @formatter:on
private final String name;