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") @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") @FormDataParam("model") String modelName,
161 @Parameter(description = "includeToModelImport") @FormDataParam("includeToModelImport") boolean includeToModelDefaultImports) {
162 return uploadElementTypeServletLogic(
163 this::createRelationshipTypes, file, request, creator, NodeTypeEnum.RelationshipType.getName(), 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") @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") @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") @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") @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") @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);
335 if (responseWrapper.isEmpty()) {
336 createElementsMethod.accept(responseWrapper, yamlStringWrapper.getInnerElement(), modelName, includeToModelDefaultImports);
338 return responseWrapper.getInnerElement();
339 } catch (final Exception e) {
340 log.debug(CREATE_FAILED_WITH_EXCEPTION, elementTypeName, e);
341 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName);
342 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
346 private Response uploadElementTypeServletLogicYaml(final ConsumerFourParam<Wrapper<Response>, String, String, Boolean> createElementsMethod,
347 final File file, final HttpServletRequest request, final String creator,
348 final String elementTypeName, final String modelName,
349 final boolean includeToModelDefaultImports) {
351 final String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER);
353 final String url = request.getMethod() + " " + request.getRequestURI();
354 log.debug(START_HANDLE_REQUEST_OF, url);
355 final Wrapper<Response> responseWrapper = doUploadTypeValidations(request, userId, file);
356 if (responseWrapper.isEmpty()) {
357 final String yamlAsString = getFileAsString(file);
358 log.debug("received yaml: {}", yamlAsString);
359 createElementsMethod.accept(responseWrapper, yamlAsString, modelName, includeToModelDefaultImports);
361 return responseWrapper.getInnerElement();
362 } catch (final Exception e) {
363 log.debug(CREATE_FAILED_WITH_EXCEPTION, elementTypeName, e);
364 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName);
365 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
370 private String getFileAsString(File file) throws IOException {
371 try (final FileInputStream fl = new FileInputStream(file)) {
372 byte[] arr = new byte[(int) file.length()];
373 int read = fl.read(arr);
375 return new String(arr, StandardCharsets.UTF_8);
377 throw new IOException(String.format("Failed to read bytes from '%s'", file.getName()));
382 private Wrapper<Response> doUploadTypeValidations(final HttpServletRequest request, String userId, File file) {
383 Wrapper<Response> responseWrapper = new Wrapper<>();
384 Wrapper<User> userWrapper = new Wrapper<>();
385 String url = request.getMethod() + " " + request.getRequestURI();
386 log.debug(START_HANDLE_REQUEST_OF, url);
387 validateUserExist(responseWrapper, userWrapper, userId);
388 if (responseWrapper.isEmpty()) {
389 validateUserRole(responseWrapper, userWrapper.getInnerElement());
391 if (responseWrapper.isEmpty()) {
392 validateDataNotNull(responseWrapper, file);
394 return responseWrapper;
397 private Response uploadTypesWithMetaData(ConsumerFourParam<Wrapper<Response>, ToscaTypeImportData, String, Boolean> createElementsMethod,
398 Map<String, ToscaTypeMetadata> typesMetaData, File file, final HttpServletRequest request,
399 String creator, String elementTypeName, String modelName, final boolean includeToModelDefaultImports) {
401 String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER);
402 Wrapper<String> yamlStringWrapper = new Wrapper<>();
404 Wrapper<Response> responseWrapper = doUploadTypeValidations(request, userId, file);
405 if (responseWrapper.isEmpty()) {
406 fillZipContents(yamlStringWrapper, file);
408 if (responseWrapper.isEmpty()) {
409 ToscaTypeImportData toscaTypeImportData = new ToscaTypeImportData(yamlStringWrapper.getInnerElement(), typesMetaData);
410 createElementsMethod.accept(responseWrapper, toscaTypeImportData, modelName, includeToModelDefaultImports);
412 return responseWrapper.getInnerElement();
413 } catch (Exception e) {
414 log.debug(CREATE_FAILED_WITH_EXCEPTION, elementTypeName, e);
415 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName);
416 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
420 private <T> void createElementsType(Wrapper<Response> responseWrapper, Supplier<Either<T, ResponseFormat>> elementsCreater) {
421 Either<T, ResponseFormat> eitherResult = elementsCreater.get();
422 if (eitherResult.isRight()) {
423 responseWrapper.setInnerElement(buildErrorResponse(eitherResult.right().value()));
426 Response response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED),
427 RepresentationUtils.toRepresentation(eitherResult.left().value()));
428 responseWrapper.setInnerElement(response);
429 } catch (Exception e) {
430 responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
431 log.error("#createElementsType - json serialization failed with error: ", e);
437 private void createDataTypes(Wrapper<Response> responseWrapper, String dataTypesYml, final String modelName,
438 final boolean includeToModelDefaultImports) {
439 final Supplier<Either<List<ImmutablePair<DataTypeDefinition, Boolean>>, ResponseFormat>> generateElementTypeFromYml = () ->
440 dataTypeImportManager.createDataTypes(dataTypesYml, modelName, includeToModelDefaultImports);
441 buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, ActionStatus.DATA_TYPE_ALREADY_EXIST,
442 NodeTypeEnum.DataType.name());
446 private void createGroupTypes(Wrapper<Response> responseWrapper, ToscaTypeImportData toscaTypeImportData, String modelName,
447 final boolean includeToModelDefaultImports) {
448 final Supplier<Either<List<ImmutablePair<GroupTypeDefinition, Boolean>>, ResponseFormat>> generateElementTypeFromYml = () ->
449 groupTypeImportManager.createGroupTypes(toscaTypeImportData, modelName, includeToModelDefaultImports);
450 buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, ActionStatus.GROUP_TYPE_ALREADY_EXIST,
451 NodeTypeEnum.GroupType.name());
455 private void createPolicyTypes(Wrapper<Response> responseWrapper, ToscaTypeImportData toscaTypeImportData, String modelName,
456 final boolean includeToModelDefaultImports) {
457 final Supplier<Either<List<ImmutablePair<PolicyTypeDefinition, Boolean>>, ResponseFormat>> generateElementTypeFromYml = () ->
458 policyTypeImportManager.createPolicyTypes(toscaTypeImportData, modelName, includeToModelDefaultImports);
459 buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, ActionStatus.POLICY_TYPE_ALREADY_EXIST,
460 NodeTypeEnum.PolicyType.name());
464 private <T extends ToscaDataDefinition> void buildStatusForElementTypeCreate(Wrapper<Response> responseWrapper,
465 Supplier<Either<List<ImmutablePair<T, Boolean>>, ResponseFormat>> generateElementTypeFromYml,
466 ActionStatus alreadyExistStatus, String elementTypeName) {
467 Either<List<ImmutablePair<T, Boolean>>, ResponseFormat> eitherResult = generateElementTypeFromYml.get();
468 if (eitherResult.isRight()) {
469 responseWrapper.setInnerElement(buildErrorResponse(eitherResult.right().value()));
473 final List<ImmutablePair<T, Boolean>> list = eitherResult.left().value();
474 ActionStatus status = ActionStatus.OK;
476 // Group result by the right value - true or false.
477 // I.e., get the number of data types which are new and which are old.
478 final Map<Boolean, List<ImmutablePair<T, Boolean>>> collect =
479 list.stream().collect(Collectors.groupingBy(ImmutablePair<T, Boolean>::getRight));
480 if (collect != null) {
481 Set<Boolean> keySet = collect.keySet();
482 if (keySet.size() == 1) {
483 Boolean isNew = keySet.iterator().next();
484 if (Boolean.TRUE.equals(isNew)) {
485 // all data types created at the first time
486 status = ActionStatus.CREATED;
488 // All data types already exists
489 status = alreadyExistStatus;
494 final Object representation = RepresentationUtils.toRepresentation(eitherResult.left().value());
495 responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(status), representation));
496 } catch (IOException e) {
497 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName);
498 log.debug("failed to convert {} to json", elementTypeName, e);
499 responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)));
504 // relationship types
505 private void createRelationshipTypes(final Wrapper<Response> responseWrapper,
506 final String relationshipTypesYml,
507 final String modelName,
508 final boolean includeToModelDefaultImports) {
509 final Supplier<Either<List<ImmutablePair<RelationshipTypeDefinition, Boolean>>, ResponseFormat>> generateElementTypeFromYml = () -> relationshipTypeImportManager
510 .createRelationshipTypes(relationshipTypesYml, modelName, includeToModelDefaultImports);
511 buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, ActionStatus.RELATIONSHIP_TYPE_ALREADY_EXIST,
512 NodeTypeEnum.RelationshipType.name());