From 2b55a906b7115ff2b156b35a4ff66811157111ee Mon Sep 17 00:00:00 2001 From: aribeiro Date: Tue, 19 Oct 2021 09:11:16 +0100 Subject: Support for adding artifact types Issue-ID: SDC-3763 Change-Id: Ideb63cbb3eb4e383adebaa11de49e91414a2c9a7 Signed-off-by: aribeiro --- .../components/impl/ArtifactTypeImportManager.java | 100 +++++++++++++++++++++ .../be/components/impl/ArtifactsBusinessLogic.java | 14 ++- .../org/openecomp/sdc/be/impl/ComponentsUtils.java | 27 ++++++ .../sdc/be/servlets/TypesFetchServlet.java | 61 +++++++++---- .../sdc/be/servlets/TypesUploadServlet.java | 25 +++++- 5 files changed, 208 insertions(+), 19 deletions(-) create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactTypeImportManager.java (limited to 'catalog-be/src/main/java/org/openecomp') 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 0000000000..e6ff100fc1 --- /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, ResponseFormat> createArtifactTypes(final String artifactTypesYml, + final String modelName, + final boolean includeToModelDefaultImports) { + if (StringUtils.isNotEmpty(modelName)) { + artifactTypeOperation.validateModel(modelName); + } + final Either, ActionStatus> artifactTypes = createArtifactTypeFromYml(artifactTypesYml, modelName); + if (artifactTypes.isRight()) { + return Either.right(componentsUtils.getResponseFormat(artifactTypes.right().value())); + } + final List elementTypes = createArtifactTypesByDao(artifactTypes.left().value()); + if (includeToModelDefaultImports) { + commonImportManager.addTypesToDefaultImports(ElementTypeEnum.ARTIFACT_TYPE, artifactTypesYml, modelName); + } + return Either.left(elementTypes); + } + + private Either, ActionStatus> createArtifactTypeFromYml( + final String artifactTypesYml, final String modelName) { + final Either, ActionStatus> artifactTypes = + commonImportManager.createElementTypesFromYml(artifactTypesYml, this::createArtifactTypeDefinition); + if (artifactTypes.isLeft()) { + artifactTypes.left().value().forEach(artifactType -> artifactType.setModel(modelName)); + return artifactTypes; + } + return artifactTypes; + } + + private List createArtifactTypesByDao( + final List artifactTypes) { + final List createdTypes = new ArrayList<>(); + artifactTypes.forEach(type -> createdTypes.add(artifactTypeOperation.createArtifactType(type))); + return createdTypes; + } + + private ArtifactTypeDefinition createArtifactTypeDefinition(final String type, + final Map 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 a566d6c73d..7b21484a7b 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.NodeTypeEnum; 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.IGroupTypeOperation; 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 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { 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 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { 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 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { this.lifecycleBusinessLogic = lifecycleBusinessLogic; this.userBusinessLogic = userBusinessLogic; this.artifactsResolver = artifactsResolver; + this.artifactTypeOperation = artifactTypeOperation; } public static Either ifTrue(boolean predicate, Supplier> ifTrue) { @@ -4263,4 +4268,11 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { return operation == CREATE || operation == LINK; } } + + public Map 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 af05825545..5c2faccd77 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 @@ public class ComponentsUtils { 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 097398455f..7a229c88aa 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.QueryParam; 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.dao.api.ActionStatus; 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.model.User; 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 @@ public class TypesFetchServlet extends AbstractValidationsServlet { 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 @@ public class TypesFetchServlet extends AbstractValidationsServlet { } } + @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, Response> getComponent(ComponentBusinessLogic resourceBL, boolean isAbstract, String userId) { Either, ResponseFormat> actionResponse; List 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 06738a88c5..fbd480169a 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.MediaType; 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 @@ public class TypesUploadServlet extends AbstractValidationsServlet { 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 @@ public class TypesUploadServlet extends AbstractValidationsServlet { 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 @@ public class TypesUploadServlet extends AbstractValidationsServlet { this.groupTypeImportManager = groupTypeImportManager; this.policyTypeImportManager = policyTypeImportManager; this.relationshipTypeImportManager = relationshipTypeImportManager; + this.artifactTypeImportManager = artifactTypeImportManager; } @POST @@ -177,6 +180,26 @@ public class TypesUploadServlet extends AbstractValidationsServlet { return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, "Interface Types"); } + @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, 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 = { -- cgit 1.2.3-korg