2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021 Nordix Foundation
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
19 package org.openecomp.sdc.be.servlets;
21 import com.googlecode.jmapper.JMapper;
22 import com.jcabi.aspects.Loggable;
23 import io.swagger.v3.oas.annotations.Operation;
24 import io.swagger.v3.oas.annotations.Parameter;
25 import io.swagger.v3.oas.annotations.media.ArraySchema;
26 import io.swagger.v3.oas.annotations.media.Content;
27 import io.swagger.v3.oas.annotations.media.Schema;
28 import io.swagger.v3.oas.annotations.responses.ApiResponse;
29 import io.swagger.v3.oas.annotations.servers.Server;
30 import io.swagger.v3.oas.annotations.tags.Tag;
31 import java.io.InputStream;
32 import java.util.Arrays;
33 import javax.inject.Inject;
34 import javax.validation.Valid;
35 import javax.validation.constraints.NotNull;
36 import javax.ws.rs.Consumes;
37 import javax.ws.rs.HeaderParam;
38 import javax.ws.rs.POST;
39 import javax.ws.rs.PUT;
40 import javax.ws.rs.Path;
41 import javax.ws.rs.Produces;
42 import javax.ws.rs.core.MediaType;
43 import javax.ws.rs.core.Response;
44 import javax.ws.rs.core.Response.Status;
45 import org.glassfish.jersey.media.multipart.FormDataParam;
46 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
47 import org.openecomp.sdc.be.components.impl.ModelBusinessLogic;
48 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
49 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
50 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
51 import org.openecomp.sdc.be.components.validation.UserValidations;
52 import org.openecomp.sdc.be.config.BeEcompErrorManager;
53 import org.openecomp.sdc.be.dao.api.ActionStatus;
54 import org.openecomp.sdc.be.exception.BusinessException;
55 import org.openecomp.sdc.be.impl.ComponentsUtils;
56 import org.openecomp.sdc.be.impl.ServletUtils;
57 import org.openecomp.sdc.be.model.Model;
58 import org.openecomp.sdc.be.ui.model.ModelCreateRequest;
59 import org.openecomp.sdc.be.user.Role;
60 import org.openecomp.sdc.be.user.UserBusinessLogic;
61 import org.openecomp.sdc.common.api.Constants;
62 import org.openecomp.sdc.common.util.ValidationUtils;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
65 import org.springframework.stereotype.Controller;
68 * Root resource (exposed at "/" path)
70 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
72 @Tag(name = "SDCE-2 APIs")
73 @Server(url = "/sdc2/rest")
75 public class ModelServlet extends AbstractValidationsServlet {
77 private static final Logger log = LoggerFactory.getLogger(ModelServlet.class);
78 private final ModelBusinessLogic modelBusinessLogic;
79 private final UserValidations userValidations;
82 public ModelServlet(final UserBusinessLogic userBusinessLogic, final ComponentInstanceBusinessLogic componentInstanceBL,
83 final ComponentsUtils componentsUtils, final ServletUtils servletUtils, final ResourceImportManager resourceImportManager,
84 final ModelBusinessLogic modelBusinessLogic, final UserValidations userValidations) {
85 super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
86 this.modelBusinessLogic = modelBusinessLogic;
87 this.userValidations = userValidations;
92 @Consumes(MediaType.MULTIPART_FORM_DATA)
93 @Produces(MediaType.APPLICATION_JSON)
94 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
95 @Operation(description = "Create a TOSCA model, along with its imports files", method = "POST", summary = "Create a TOSCA model", responses = {
96 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
97 @ApiResponse(responseCode = "201", description = "Model created"),
98 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
99 @ApiResponse(responseCode = "403", description = "Restricted operation"),
100 @ApiResponse(responseCode = "409", description = "Model already exists")})
101 public Response createModel(@Parameter(description = "model to be created", required = true)
102 @NotNull @Valid @FormDataParam("model") final ModelCreateRequest modelCreateRequest,
103 @Parameter(description = "the model TOSCA imports zipped", required = true)
104 @NotNull @FormDataParam("modelImportsZip") final InputStream modelImportsZip,
105 @HeaderParam(value = Constants.USER_ID_HEADER) final String userId) {
106 validateUser(ValidationUtils.sanitizeInputString(userId));
107 final var modelName = ValidationUtils.sanitizeInputString(modelCreateRequest.getName().trim());
109 final Model createdModel = modelBusinessLogic
110 .createModel(new JMapper<>(Model.class, ModelCreateRequest.class).getDestination(modelCreateRequest));
111 modelBusinessLogic.createModelImports(modelName, modelImportsZip);
112 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED),
113 RepresentationUtils.toRepresentation(createdModel));
114 } catch (final BusinessException e) {
116 } catch (final Exception e) {
117 var errorMsg = String.format("Unexpected error while creating model '%s' imports", modelName);
118 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(errorMsg);
119 log.error(errorMsg, e);
120 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
125 @Path("/model/imports")
126 @Consumes(MediaType.MULTIPART_FORM_DATA)
127 @Produces(MediaType.APPLICATION_JSON)
128 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
129 @Operation(description = "Update a model TOSCA imports", method = "PUT", summary = "Update a model TOSCA imports", responses = {
130 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
131 @ApiResponse(responseCode = "204", description = "Model imports updated"),
132 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
133 @ApiResponse(responseCode = "403", description = "Restricted operation"),
134 @ApiResponse(responseCode = "404", description = "Model not found")})
135 public Response updateModelImports(@Parameter(description = "model to be created", required = true)
136 @NotNull @FormDataParam("modelName") String modelName,
137 @Parameter(description = "the model TOSCA imports zipped", required = true)
138 @NotNull @FormDataParam("modelImportsZip") final InputStream modelImportsZip,
139 @HeaderParam(value = Constants.USER_ID_HEADER) final String userId) {
140 validateUser(ValidationUtils.sanitizeInputString(userId));
141 modelName = ValidationUtils.sanitizeInputString(modelName);
143 modelBusinessLogic.createModelImports(modelName, modelImportsZip);
144 } catch (final BusinessException e) {
146 } catch (final Exception e) {
147 var errorMsg = String.format("Unexpected error while creating model '%s' imports", modelName);
148 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(errorMsg);
149 log.error(errorMsg, e);
150 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
152 return Response.status(Status.NO_CONTENT).build();
155 private void validateUser(final String userId) {
156 userValidations.validateUserRole(userValidations.validateUserExists(userId), Arrays.asList(Role.DESIGNER, Role.ADMIN));