2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.be.servlets;
22 import com.google.gson.reflect.TypeToken;
23 import com.jcabi.aspects.Loggable;
24 import fj.data.Either;
25 import io.swagger.v3.oas.annotations.Operation;
26 import io.swagger.v3.oas.annotations.Parameter;
27 import io.swagger.v3.oas.annotations.media.ArraySchema;
28 import io.swagger.v3.oas.annotations.media.Content;
29 import io.swagger.v3.oas.annotations.media.Schema;
30 import io.swagger.v3.oas.annotations.responses.ApiResponse;
31 import io.swagger.v3.oas.annotations.servers.Server;
32 import io.swagger.v3.oas.annotations.tags.Tag;
34 import java.io.FileInputStream;
35 import java.io.IOException;
36 import java.nio.charset.StandardCharsets;
37 import java.util.List;
40 import java.util.function.Supplier;
41 import java.util.stream.Collectors;
42 import javax.inject.Inject;
43 import javax.servlet.http.HttpServletRequest;
44 import javax.ws.rs.Consumes;
45 import javax.ws.rs.HeaderParam;
46 import javax.ws.rs.POST;
47 import javax.ws.rs.Path;
48 import javax.ws.rs.Produces;
49 import javax.ws.rs.core.Context;
50 import javax.ws.rs.core.MediaType;
51 import javax.ws.rs.core.Response;
52 import org.apache.commons.lang3.tuple.ImmutablePair;
53 import org.glassfish.jersey.media.multipart.FormDataParam;
54 import org.jetbrains.annotations.NotNull;
55 import org.openecomp.sdc.be.components.impl.ArtifactTypeImportManager;
56 import org.openecomp.sdc.be.components.impl.CapabilityTypeImportManager;
57 import org.openecomp.sdc.be.components.impl.CategoriesImportManager;
58 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
59 import org.openecomp.sdc.be.components.impl.DataTypeImportManager;
60 import org.openecomp.sdc.be.components.impl.GroupTypeImportManager;
61 import org.openecomp.sdc.be.components.impl.InterfaceLifecycleTypeImportManager;
62 import org.openecomp.sdc.be.components.impl.PolicyTypeImportManager;
63 import org.openecomp.sdc.be.components.impl.RelationshipTypeImportManager;
64 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
65 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
66 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
67 import org.openecomp.sdc.be.components.impl.model.ToscaTypeImportData;
68 import org.openecomp.sdc.be.config.BeEcompErrorManager;
69 import org.openecomp.sdc.be.dao.api.ActionStatus;
70 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
71 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
72 import org.openecomp.sdc.be.impl.ComponentsUtils;
73 import org.openecomp.sdc.be.impl.ServletUtils;
74 import org.openecomp.sdc.be.model.DataTypeDefinition;
75 import org.openecomp.sdc.be.model.GroupTypeDefinition;
76 import org.openecomp.sdc.be.model.PolicyTypeDefinition;
77 import org.openecomp.sdc.be.model.RelationshipTypeDefinition;
78 import org.openecomp.sdc.be.model.User;
79 import org.openecomp.sdc.be.model.normatives.ToscaTypeMetadata;
80 import org.openecomp.sdc.common.api.Constants;
81 import org.openecomp.sdc.common.datastructure.FunctionalInterfaces.ConsumerFourParam;
82 import org.openecomp.sdc.common.datastructure.FunctionalInterfaces.ConsumerTwoParam;
83 import org.openecomp.sdc.common.datastructure.Wrapper;
84 import org.openecomp.sdc.common.log.wrappers.Logger;
85 import org.openecomp.sdc.exception.ResponseFormat;
86 import org.springframework.stereotype.Controller;
88 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
89 @Path("/v1/catalog/uploadType")
90 @Consumes(MediaType.MULTIPART_FORM_DATA)
91 @Produces(MediaType.APPLICATION_JSON)
92 @Tag(name = "SDCE-2 APIs")
93 @Server(url = "/sdc2/rest")
95 public class TypesUploadServlet extends AbstractValidationsServlet {
97 private static final String CREATE = "Create ";
98 private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
99 private static final String CREATE_FAILED_WITH_EXCEPTION = "create {} failed with exception:";
100 private static final Logger log = Logger.getLogger(TypesUploadServlet.class);
101 private final CapabilityTypeImportManager capabilityTypeImportManager;
102 private final InterfaceLifecycleTypeImportManager interfaceLifecycleTypeImportManager;
103 private final CategoriesImportManager categoriesImportManager;
104 private final DataTypeImportManager dataTypeImportManager;
105 private final GroupTypeImportManager groupTypeImportManager;
106 private final PolicyTypeImportManager policyTypeImportManager;
107 private final RelationshipTypeImportManager relationshipTypeImportManager;
108 private final ArtifactTypeImportManager artifactTypeImportManager;
111 public TypesUploadServlet(ComponentInstanceBusinessLogic componentInstanceBL,
112 ComponentsUtils componentsUtils, ServletUtils servletUtils, ResourceImportManager resourceImportManager,
113 CapabilityTypeImportManager capabilityTypeImportManager,
114 InterfaceLifecycleTypeImportManager interfaceLifecycleTypeImportManager,
115 CategoriesImportManager categoriesImportManager, DataTypeImportManager dataTypeImportManager,
116 GroupTypeImportManager groupTypeImportManager, PolicyTypeImportManager policyTypeImportManager,
117 RelationshipTypeImportManager relationshipTypeImportManager, ArtifactTypeImportManager artifactTypeImportManager) {
118 super(componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
119 this.capabilityTypeImportManager = capabilityTypeImportManager;
120 this.interfaceLifecycleTypeImportManager = interfaceLifecycleTypeImportManager;
121 this.categoriesImportManager = categoriesImportManager;
122 this.dataTypeImportManager = dataTypeImportManager;
123 this.groupTypeImportManager = groupTypeImportManager;
124 this.policyTypeImportManager = policyTypeImportManager;
125 this.relationshipTypeImportManager = relationshipTypeImportManager;
126 this.artifactTypeImportManager = artifactTypeImportManager;
131 @Operation(description = "Create Capability Type from yaml", method = "POST", summary = "Returns created Capability Type", responses = {
132 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
133 @ApiResponse(responseCode = "201", description = "Capability Type created"),
134 @ApiResponse(responseCode = "403", description = "Restricted operation"),
135 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
136 @ApiResponse(responseCode = "409", description = "Capability Type already exist")})
137 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
138 public Response uploadCapabilityType(@Parameter(description = "FileInputStream") @FormDataParam("capabilityTypeZip") File file,
139 @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
140 @Parameter(description = "model name") @FormDataParam("model") String modelName,
141 @Parameter(description = "includeToModelImport") @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
142 ConsumerFourParam<Wrapper<Response>, String, String, Boolean> createElementsMethod = (responseWrapper, ymlPayload, model, includeToModelImport) ->
143 createElementsType(responseWrapper, () -> capabilityTypeImportManager.createCapabilityTypes(ymlPayload, modelName,
144 includeToModelDefaultImports));
145 return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, NodeTypeEnum.CapabilityType.name(), modelName,
146 includeToModelDefaultImports);
150 @Path("/relationship")
151 @Operation(description = "Create Relationship Type from yaml", method = "POST", summary = "Returns created Relationship Type", responses = {
152 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
153 @ApiResponse(responseCode = "201", description = "Relationship Type created"),
154 @ApiResponse(responseCode = "403", description = "Restricted operation"),
155 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
156 @ApiResponse(responseCode = "409", description = "Relationship Type already exist")})
157 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
158 public Response uploadRelationshipType(@Parameter(description = "FileInputStream") @FormDataParam("relationshipTypeZip") File file,
159 @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
160 @Parameter(description = "model name") @FormDataParam("model") String modelName,
161 @Parameter(description = "includeToModelImport") @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
162 return uploadElementTypeServletLogic(this::createRelationshipTypes, file, request, creator, NodeTypeEnum.RelationshipType.getName(),
163 modelName, includeToModelDefaultImports);
167 @Path("/interfaceLifecycle")
168 @Operation(description = "Create Interface Lyfecycle Type from yaml", method = "POST", summary = "Returns created Interface Lifecycle Type", responses = {
169 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
170 @ApiResponse(responseCode = "201", description = "Interface Lifecycle Type created"),
171 @ApiResponse(responseCode = "403", description = "Restricted operation"),
172 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
173 @ApiResponse(responseCode = "409", description = "Interface Lifecycle Type already exist")})
174 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
175 public Response uploadInterfaceLifecycleType(@Parameter(description = "FileInputStream") @FormDataParam("interfaceLifecycleTypeZip") File file,
176 @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
177 @Parameter(description = "model name") @FormDataParam("model") String modelName,
178 @Parameter(description = "includeToModelImport") @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
179 ConsumerTwoParam<Wrapper<Response>, String> createElementsMethod = (responseWrapper, ymlPayload) ->
180 createElementsType(responseWrapper, () -> interfaceLifecycleTypeImportManager.createLifecycleTypes(ymlPayload, modelName,
181 includeToModelDefaultImports));
182 return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, "Interface Types");
186 @Path("/artifactTypes")
187 @Operation(description = "Create Tosca Artifact types from yaml", method = "POST", summary = "Returns created Tosca artifact types", responses = {
188 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
189 @ApiResponse(responseCode = "201", description = "Tosca Artifact types created"),
190 @ApiResponse(responseCode = "403", description = "Restricted operation"),
191 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
192 @ApiResponse(responseCode = "409", description = "Tosca Artifact Type already exist")})
193 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
194 public Response uploadArtifactTypes(@Parameter(description = "Zip file containing a yaml with the TOSCA artifact types definition")
195 @FormDataParam("artifactsZip") File file,
196 @Parameter(description = "model name") @FormDataParam("model") String modelName,
197 @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
198 @Parameter(description = "A flag to add types to the default imports")
199 @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
200 final ConsumerTwoParam<Wrapper<Response>, String> createElementsMethod = (responseWrapper, ymlPayload) ->
201 createElementsType(responseWrapper,
202 () -> artifactTypeImportManager.createArtifactTypes(ymlPayload, modelName, includeToModelDefaultImports));
203 return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, NodeTypeEnum.ArtifactType.getName());
208 @Operation(description = "Create Categories from yaml", method = "POST", summary = "Returns created categories", responses = {
209 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
210 @ApiResponse(responseCode = "201", description = "Categories created"),
211 @ApiResponse(responseCode = "403", description = "Restricted operation"),
212 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
213 @ApiResponse(responseCode = "409", description = "Category already exist")})
214 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
215 public Response uploadCategories(@Parameter(description = "FileInputStream") @FormDataParam("categoriesZip") File file,
216 @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) {
217 ConsumerTwoParam<Wrapper<Response>, String> createElementsMethod = (responseWrapper, ymlPayload) ->
218 createElementsType(responseWrapper, () -> categoriesImportManager.createCategories(ymlPayload));
219 return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, "categories");
224 @Operation(description = "Create Data Types from zip", method = "POST", summary = "Returns created data types", responses = {
225 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
226 @ApiResponse(responseCode = "201", description = "Data types created"),
227 @ApiResponse(responseCode = "403", description = "Restricted operation"),
228 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
229 @ApiResponse(responseCode = "409", description = "Data types already exist")})
230 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
231 public Response uploadDataTypes(@Parameter(description = "FileInputStream") @FormDataParam("dataTypesZip") File file,
232 @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
233 @Parameter(description = "model name") @FormDataParam("model") String modelName,
234 @Parameter(description = "includeToModelImport") @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
235 return uploadElementTypeServletLogic(this::createDataTypes, file, request, creator, NodeTypeEnum.DataType.getName(), modelName,
236 includeToModelDefaultImports);
240 @Path("/datatypesyaml")
241 @Operation(description = "Create Data Types from yaml", method = "POST", summary = "Returns created data types", responses = {
242 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
243 @ApiResponse(responseCode = "201", description = "Data types created"),
244 @ApiResponse(responseCode = "403", description = "Restricted operation"),
245 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
246 @ApiResponse(responseCode = "409", description = "Data types already exist")})
247 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
248 public Response uploadDataTypesYaml(@Parameter(description = "FileInputStream") @FormDataParam("dataTypesYaml") File file,
249 @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
250 @Parameter(description = "model name") @FormDataParam("model") String modelName,
251 @Parameter(description = "includeToModelImport") @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
252 return uploadElementTypeServletLogicYaml(this::createDataTypes, file, request, creator, NodeTypeEnum.DataType.getName(), modelName,
253 includeToModelDefaultImports);
258 @Operation(description = "Create GroupTypes from yaml", method = "POST", summary = "Returns created group types", responses = {
259 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
260 @ApiResponse(responseCode = "201", description = "group types created"),
261 @ApiResponse(responseCode = "403", description = "Restricted operation"),
262 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
263 @ApiResponse(responseCode = "409", description = "group types already exist")})
264 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
265 public Response uploadGroupTypes(@Parameter(description = "toscaTypeMetadata") @FormDataParam("toscaTypeMetadata") String toscaTypesMetaData,
266 @Parameter(description = "model name") @FormDataParam("model") String modelName,
267 @Parameter(description = "FileInputStream") @FormDataParam("groupTypesZip") File file,
268 @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
269 @Parameter(description = "includeToModelImport") @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
270 Map<String, ToscaTypeMetadata> typesMetadata = getTypesMetadata(toscaTypesMetaData);
271 return uploadTypesWithMetaData(this::createGroupTypes, typesMetadata, file, request, creator, NodeTypeEnum.GroupType.getName(), modelName,
272 includeToModelDefaultImports);
276 @Path("/policytypes")
277 @Operation(description = "Create PolicyTypes from yaml", method = "POST", summary = "Returns created policy types", responses = {
278 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
279 @ApiResponse(responseCode = "201", description = "policy types created"),
280 @ApiResponse(responseCode = "403", description = "Restricted operation"),
281 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
282 @ApiResponse(responseCode = "409", description = "policy types already exist")})
283 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
284 public Response uploadPolicyTypes(@Parameter(description = "toscaTypeMetadata") @FormDataParam("toscaTypeMetadata") String toscaTypesMetaData,
285 @Parameter(description = "model name") @FormDataParam("model") String modelName,
286 @Parameter(description = "FileInputStream") @FormDataParam("policyTypesZip") File file,
287 @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
288 @Parameter(description = "includeToModelImport") @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
289 Map<String, ToscaTypeMetadata> typesMetadata = getTypesMetadata(toscaTypesMetaData);
290 return uploadTypesWithMetaData(this::createPolicyTypes, typesMetadata, file, request, creator, NodeTypeEnum.PolicyType.getName(), modelName,
291 includeToModelDefaultImports);
294 private Map<String, ToscaTypeMetadata> getTypesMetadata(String toscaTypesMetaData) {
295 return gson.fromJson(toscaTypesMetaData, new TypeToken<Map<String, ToscaTypeMetadata>>() {
299 private Response uploadElementTypeServletLogic(ConsumerTwoParam<Wrapper<Response>, String> createElementsMethod, File file,
300 final HttpServletRequest request, String creator, String elementTypeName) {
302 String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER);
304 Wrapper<String> yamlStringWrapper = new Wrapper<>();
305 String url = request.getMethod() + " " + request.getRequestURI();
306 log.debug(START_HANDLE_REQUEST_OF, url);
307 Wrapper<Response> responseWrapper = doUploadTypeValidations(request, userId, file);
308 if (responseWrapper.isEmpty()) {
309 fillZipContents(yamlStringWrapper, file);
311 if (responseWrapper.isEmpty()) {
312 createElementsMethod.accept(responseWrapper, yamlStringWrapper.getInnerElement());
314 return responseWrapper.getInnerElement();
315 } catch (Exception e) {
316 log.debug(CREATE_FAILED_WITH_EXCEPTION, elementTypeName, e);
317 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName);
318 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
322 private Response uploadElementTypeServletLogic(final ConsumerFourParam<Wrapper<Response>, String, String, Boolean> createElementsMethod,
323 final File file, final HttpServletRequest request, final String creator,
324 final String elementTypeName, final String modelName, final boolean includeToModelDefaultImports) {
326 final String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER);
328 final Wrapper<String> yamlStringWrapper = new Wrapper<>();
329 final String url = request.getMethod() + " " + request.getRequestURI();
330 log.debug(START_HANDLE_REQUEST_OF, url);
331 final Wrapper<Response> responseWrapper = doUploadTypeValidations(request, userId, file);
332 if (responseWrapper.isEmpty()) {
333 fillZipContents(yamlStringWrapper, file);
334 createElementsMethod.accept(responseWrapper, yamlStringWrapper.getInnerElement(), modelName, includeToModelDefaultImports);
336 return responseWrapper.getInnerElement();
337 } catch (final Exception e) {
338 log.debug(CREATE_FAILED_WITH_EXCEPTION, elementTypeName, e);
339 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName);
340 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
344 private Response uploadElementTypeServletLogicYaml(final ConsumerFourParam<Wrapper<Response>, String, String, Boolean> createElementsMethod,
345 final File file, final HttpServletRequest request, final String creator,
346 final String elementTypeName, final String modelName,
347 final boolean includeToModelDefaultImports) {
349 final String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER);
351 final String url = request.getMethod() + " " + request.getRequestURI();
352 log.debug(START_HANDLE_REQUEST_OF, url);
353 final Wrapper<Response> responseWrapper = doUploadTypeValidations(request, userId, file);
354 final String yamlAsString = getFileAsString(file);
355 if (responseWrapper.isEmpty()) {
356 log.debug("received yaml: {}", yamlAsString);
357 createElementsMethod.accept(responseWrapper, yamlAsString, modelName, includeToModelDefaultImports);
360 return responseWrapper.getInnerElement();
361 } catch (final Exception e) {
362 log.debug(CREATE_FAILED_WITH_EXCEPTION, elementTypeName, e);
363 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName);
364 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
369 private String getFileAsString(File file) throws IOException {
370 try (final FileInputStream fl = new FileInputStream(file)) {
371 byte[] arr = new byte[(int) file.length()];
372 int read = fl.read(arr);
374 return new String(arr, StandardCharsets.UTF_8);
376 throw new IOException(String.format("Failed to read bytes from '%s'", file.getName()));
381 private Wrapper<Response> doUploadTypeValidations(final HttpServletRequest request, String userId, File file) {
382 Wrapper<Response> responseWrapper = new Wrapper<>();
383 Wrapper<User> userWrapper = new Wrapper<>();
384 String url = request.getMethod() + " " + request.getRequestURI();
385 log.debug(START_HANDLE_REQUEST_OF, url);
386 validateUserExist(responseWrapper, userWrapper, userId);
387 if (responseWrapper.isEmpty()) {
388 validateUserRole(responseWrapper, userWrapper.getInnerElement());
390 if (responseWrapper.isEmpty()) {
391 validateDataNotNull(responseWrapper, file);
393 return responseWrapper;
396 private Response uploadTypesWithMetaData(ConsumerFourParam<Wrapper<Response>, ToscaTypeImportData, String, Boolean> createElementsMethod,
397 Map<String, ToscaTypeMetadata> typesMetaData, File file, final HttpServletRequest request,
398 String creator, String elementTypeName, String modelName, final boolean includeToModelDefaultImports) {
400 String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER);
401 Wrapper<String> yamlStringWrapper = new Wrapper<>();
403 Wrapper<Response> responseWrapper = doUploadTypeValidations(request, userId, file);
404 if (responseWrapper.isEmpty()) {
405 fillZipContents(yamlStringWrapper, file);
407 if (responseWrapper.isEmpty()) {
408 ToscaTypeImportData toscaTypeImportData = new ToscaTypeImportData(yamlStringWrapper.getInnerElement(), typesMetaData);
409 createElementsMethod.accept(responseWrapper, toscaTypeImportData, modelName, includeToModelDefaultImports);
411 return responseWrapper.getInnerElement();
412 } catch (Exception e) {
413 log.debug(CREATE_FAILED_WITH_EXCEPTION, elementTypeName, e);
414 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName);
415 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
419 private <T> void createElementsType(Wrapper<Response> responseWrapper, Supplier<Either<T, ResponseFormat>> elementsCreater) {
420 Either<T, ResponseFormat> eitherResult = elementsCreater.get();
421 if (eitherResult.isRight()) {
422 responseWrapper.setInnerElement(buildErrorResponse(eitherResult.right().value()));
425 Response response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED),
426 RepresentationUtils.toRepresentation(eitherResult.left().value()));
427 responseWrapper.setInnerElement(response);
428 } catch (Exception e) {
429 responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
430 log.error("#createElementsType - json serialization failed with error: ", e);
436 private void createDataTypes(Wrapper<Response> responseWrapper, String dataTypesYml, final String modelName,
437 final boolean includeToModelDefaultImports) {
438 final Supplier<Either<List<ImmutablePair<DataTypeDefinition, Boolean>>, ResponseFormat>> generateElementTypeFromYml = () ->
439 dataTypeImportManager.createDataTypes(dataTypesYml, modelName, includeToModelDefaultImports);
440 buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, ActionStatus.DATA_TYPE_ALREADY_EXIST,
441 NodeTypeEnum.DataType.name());
445 private void createGroupTypes(Wrapper<Response> responseWrapper, ToscaTypeImportData toscaTypeImportData, String modelName,
446 final boolean includeToModelDefaultImports) {
447 final Supplier<Either<List<ImmutablePair<GroupTypeDefinition, Boolean>>, ResponseFormat>> generateElementTypeFromYml = () ->
448 groupTypeImportManager.createGroupTypes(toscaTypeImportData, modelName, includeToModelDefaultImports);
449 buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, ActionStatus.GROUP_TYPE_ALREADY_EXIST,
450 NodeTypeEnum.GroupType.name());
454 private void createPolicyTypes(Wrapper<Response> responseWrapper, ToscaTypeImportData toscaTypeImportData, String modelName,
455 final boolean includeToModelDefaultImports) {
456 final Supplier<Either<List<ImmutablePair<PolicyTypeDefinition, Boolean>>, ResponseFormat>> generateElementTypeFromYml = () ->
457 policyTypeImportManager.createPolicyTypes(toscaTypeImportData, modelName, includeToModelDefaultImports);
458 buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, ActionStatus.POLICY_TYPE_ALREADY_EXIST,
459 NodeTypeEnum.PolicyType.name());
463 private <T extends ToscaDataDefinition> void buildStatusForElementTypeCreate(Wrapper<Response> responseWrapper,
464 Supplier<Either<List<ImmutablePair<T, Boolean>>, ResponseFormat>> generateElementTypeFromYml,
465 ActionStatus alreadyExistStatus, String elementTypeName) {
466 Either<List<ImmutablePair<T, Boolean>>, ResponseFormat> eitherResult = generateElementTypeFromYml.get();
467 if (eitherResult.isRight()) {
468 responseWrapper.setInnerElement(buildErrorResponse(eitherResult.right().value()));
472 final List<ImmutablePair<T, Boolean>> list = eitherResult.left().value();
473 ActionStatus status = ActionStatus.OK;
475 // Group result by the right value - true or false.
476 // I.e., get the number of data types which are new and which are old.
477 final Map<Boolean, List<ImmutablePair<T, Boolean>>> collect =
478 list.stream().collect(Collectors.groupingBy(ImmutablePair<T, Boolean>::getRight));
479 if (collect != null) {
480 Set<Boolean> keySet = collect.keySet();
481 if (keySet.size() == 1) {
482 Boolean isNew = keySet.iterator().next();
483 if (Boolean.TRUE.equals(isNew)) {
484 // all data types created at the first time
485 status = ActionStatus.CREATED;
487 // All data types already exists
488 status = alreadyExistStatus;
493 final Object representation = RepresentationUtils.toRepresentation(eitherResult.left().value());
494 responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(status), representation));
495 } catch (IOException e) {
496 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName);
497 log.debug("failed to convert {} to json", elementTypeName, e);
498 responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
503 // relationship types
504 private void createRelationshipTypes(final Wrapper<Response> responseWrapper,
505 final String relationshipTypesYml,
506 final String modelName,
507 final boolean includeToModelDefaultImports) {
508 final Supplier<Either<List<ImmutablePair<RelationshipTypeDefinition, Boolean>>, ResponseFormat>> generateElementTypeFromYml = () -> relationshipTypeImportManager
509 .createRelationshipTypes(relationshipTypesYml, modelName, includeToModelDefaultImports);
510 buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, ActionStatus.RELATIONSHIP_TYPE_ALREADY_EXIST,
511 NodeTypeEnum.RelationshipType.name());