Fix Blocker Bug reported by Sonar
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / TypesUploadServlet.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20 package org.openecomp.sdc.be.servlets;
21
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;
33 import java.io.File;
34 import java.io.FileInputStream;
35 import java.io.IOException;
36 import java.nio.charset.StandardCharsets;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Set;
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;
87
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")
94 @Controller
95 public class TypesUploadServlet extends AbstractValidationsServlet {
96
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;
109
110     @Inject
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;
127     }
128
129     @POST
130     @Path("/capability")
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);
147     }
148
149     @POST
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);
164     }
165
166     @POST
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");
183     }
184
185     @POST
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());
204     }
205
206     @POST
207     @Path("/categories")
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");
220     }
221
222     @POST
223     @Path("/datatypes")
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);
237     }
238
239     @POST
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);
254     }
255
256     @POST
257     @Path("/grouptypes")
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);
273     }
274
275     @POST
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);
292     }
293
294     private Map<String, ToscaTypeMetadata> getTypesMetadata(String toscaTypesMetaData) {
295         return gson.fromJson(toscaTypesMetaData, new TypeToken<Map<String, ToscaTypeMetadata>>() {
296         }.getType());
297     }
298
299     private Response uploadElementTypeServletLogic(ConsumerTwoParam<Wrapper<Response>, String> createElementsMethod, File file,
300                                                    final HttpServletRequest request, String creator, String elementTypeName) {
301         init();
302         String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER);
303         try {
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);
310             }
311             if (responseWrapper.isEmpty()) {
312                 createElementsMethod.accept(responseWrapper, yamlStringWrapper.getInnerElement());
313             }
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));
319         }
320     }
321
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) {
325         init();
326         final String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER);
327         try {
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             }
335             if (responseWrapper.isEmpty()) {
336                 createElementsMethod.accept(responseWrapper, yamlStringWrapper.getInnerElement(), modelName, includeToModelDefaultImports);
337             }
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));
343         }
344     }
345
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) {
350         init();
351         final String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER);
352         try {
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);
360             }
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));
366         }
367     }
368
369     @NotNull
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);
374             if (read > 0) {
375                 return new String(arr, StandardCharsets.UTF_8);
376             } else {
377                 throw new IOException(String.format("Failed to read bytes from '%s'", file.getName()));
378             }
379         }
380     }
381
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());
390         }
391         if (responseWrapper.isEmpty()) {
392             validateDataNotNull(responseWrapper, file);
393         }
394         return responseWrapper;
395     }
396
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) {
400         init();
401         String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER);
402         Wrapper<String> yamlStringWrapper = new Wrapper<>();
403         try {
404             Wrapper<Response> responseWrapper = doUploadTypeValidations(request, userId, file);
405             if (responseWrapper.isEmpty()) {
406                 fillZipContents(yamlStringWrapper, file);
407             }
408             if (responseWrapper.isEmpty()) {
409                 ToscaTypeImportData toscaTypeImportData = new ToscaTypeImportData(yamlStringWrapper.getInnerElement(), typesMetaData);
410                 createElementsMethod.accept(responseWrapper, toscaTypeImportData, modelName, includeToModelDefaultImports);
411             }
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));
417         }
418     }
419
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()));
424         } else {
425             try {
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);
432             }
433         }
434     }
435
436     // data types
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());
443     }
444
445     // group types
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());
452     }
453
454     // policy types
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());
461     }
462
463     // data types
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()));
470         } else {
471
472             try {
473                 final List<ImmutablePair<T, Boolean>> list = eitherResult.left().value();
474                 ActionStatus status = ActionStatus.OK;
475                 if (list != null) {
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;
487                             } else {
488                                 // All data types already exists
489                                 status = alreadyExistStatus;
490                             }
491                         }
492                     }
493                 }
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)));
500             }
501         }
502     }
503
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());
513     }
514 }