summaryrefslogtreecommitdiffstats
path: root/catalog-be/src/main/java/org
diff options
context:
space:
mode:
authoraribeiro <anderson.ribeiro@est.tech>2021-10-19 09:11:16 +0100
committerAndr� Schmid <andre.schmid@est.tech>2021-11-02 18:11:49 +0000
commit2b55a906b7115ff2b156b35a4ff66811157111ee (patch)
tree2ba977ca1e12eacc3cf300c3d63ed08737abf10b /catalog-be/src/main/java/org
parentdb7e56a11d52e3f89039add0b209eedb9552ac5a (diff)
Support for adding artifact types
Issue-ID: SDC-3763 Change-Id: Ideb63cbb3eb4e383adebaa11de49e91414a2c9a7 Signed-off-by: aribeiro <anderson.ribeiro@est.tech>
Diffstat (limited to 'catalog-be/src/main/java/org')
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactTypeImportManager.java100
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java14
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java27
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java61
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java25
5 files changed, 208 insertions, 19 deletions
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<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 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 <R> Either<Boolean, R> ifTrue(boolean predicate, Supplier<Either<Boolean, R>> ifTrue) {
@@ -4263,4 +4268,11 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic {
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 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<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 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
@@ -178,6 +181,26 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
}
@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)))),