2 * Copyright © 2016-2018 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * 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.
17 package org.openecomp.sdc.be.servlets;
19 import com.jcabi.aspects.Loggable;
20 import fj.data.Either;
21 import io.swagger.v3.oas.annotations.Operation;
22 import io.swagger.v3.oas.annotations.Parameter;
23 import io.swagger.v3.oas.annotations.media.ArraySchema;
24 import io.swagger.v3.oas.annotations.media.Content;
25 import io.swagger.v3.oas.annotations.media.Schema;
26 import io.swagger.v3.oas.annotations.responses.ApiResponse;
27 import io.swagger.v3.oas.annotations.servers.Server;
28 import io.swagger.v3.oas.annotations.servers.Servers;
29 import io.swagger.v3.oas.annotations.tags.Tag;
30 import io.swagger.v3.oas.annotations.tags.Tags;
31 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
32 import org.openecomp.sdc.be.components.impl.RequirementBusinessLogic;
33 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
34 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
35 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
36 import org.openecomp.sdc.be.config.BeEcompErrorManager;
37 import org.openecomp.sdc.be.dao.api.ActionStatus;
38 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
39 import org.openecomp.sdc.be.impl.ComponentsUtils;
40 import org.openecomp.sdc.be.impl.ServletUtils;
41 import org.openecomp.sdc.be.model.RequirementDefinition;
42 import org.openecomp.sdc.be.model.User;
43 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
44 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
45 import org.openecomp.sdc.be.user.UserBusinessLogic;
46 import org.openecomp.sdc.common.api.Constants;
47 import org.openecomp.sdc.common.log.wrappers.Logger;
48 import org.openecomp.sdc.exception.ResponseFormat;
49 import org.springframework.stereotype.Controller;
51 import javax.inject.Inject;
52 import javax.servlet.http.HttpServletRequest;
53 import javax.ws.rs.Consumes;
54 import javax.ws.rs.DELETE;
55 import javax.ws.rs.GET;
56 import javax.ws.rs.HeaderParam;
57 import javax.ws.rs.POST;
58 import javax.ws.rs.PUT;
59 import javax.ws.rs.Path;
60 import javax.ws.rs.PathParam;
61 import javax.ws.rs.Produces;
62 import javax.ws.rs.core.Context;
63 import javax.ws.rs.core.MediaType;
64 import javax.ws.rs.core.Response;
65 import java.util.List;
66 import java.util.Optional;
68 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
70 @Consumes(MediaType.APPLICATION_JSON)
71 @Produces(MediaType.APPLICATION_JSON)
72 @Tags({@Tag(name = "SDCE-2 APIs")})
73 @Servers({@Server(url = "/sdc2/rest")})
75 public class RequirementServlet extends AbstractValidationsServlet {
76 private static final Logger LOGGER = Logger.getLogger(RequirementServlet.class);
77 private final RequirementBusinessLogic requirementBusinessLogic;
80 public RequirementServlet(UserBusinessLogic userBusinessLogic,
81 ComponentInstanceBusinessLogic componentInstanceBL,
82 ComponentsUtils componentsUtils, ServletUtils servletUtils,
83 ResourceImportManager resourceImportManager,
84 RequirementBusinessLogic requirementBusinessLogic) {
85 super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
86 this.requirementBusinessLogic = requirementBusinessLogic;
90 @Consumes(MediaType.APPLICATION_JSON)
91 @Produces(MediaType.APPLICATION_JSON)
92 @Path("/resources/{resourceId}/requirements")
93 @Operation(description = "Create requirements on resource", method = "POST",
94 summary = "Create requirements on resource", responses = {
95 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
96 @ApiResponse(responseCode = "201", description = "Create requirements"),
97 @ApiResponse(responseCode = "403", description = "Restricted operation"),
98 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
99 @ApiResponse(responseCode = "409", description = "requirement already exist")})
100 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
101 public Response createRequirementsOnResource(
102 @Parameter(description = "Requirement to create", required = true) String data,
103 @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId,
104 @Context final HttpServletRequest request,
105 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
106 return createOrUpdate(data, "resources" , resourceId, request,
107 userId, false, "createRequirements");
112 @Consumes(MediaType.APPLICATION_JSON)
113 @Produces(MediaType.APPLICATION_JSON)
114 @Path("/resources/{resourceId}/requirements")
115 @Operation(description = "Update Requirements on resource", method = "PUT",
116 summary = "Update Requirements on resource", responses = {@ApiResponse(
117 content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class)))),
118 @ApiResponse(responseCode = "201", description = "Update Requirements"),
119 @ApiResponse(responseCode = "403", description = "Restricted operation"),
120 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
121 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
122 public Response updateRequirementsOnResource(
123 @Parameter(description = "Requirements to update", required = true) String data,
124 @Parameter(description = "Component Id") @PathParam("resourceId") String resourceId,
125 @Context final HttpServletRequest request,
126 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
127 return createOrUpdate(data, "resources", resourceId, request,
128 userId, true, "updateRequirements");
132 @Consumes(MediaType.APPLICATION_JSON)
133 @Produces(MediaType.APPLICATION_JSON)
134 @Path("/resources/{resourceId}/requirements/{requirementId}")
135 @Operation(description = "Get Requirement from resource", method = "GET", summary = "GET Requirement from resource",
136 responses = {@ApiResponse(content = @Content(
137 array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class)))),
138 @ApiResponse(responseCode = "201", description = "GET requirement"),
139 @ApiResponse(responseCode = "403", description = "Restricted operation"),
140 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
141 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
142 public Response getRequirementsFromResource(
143 @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId,
144 @Parameter(description = "Requirement Id") @PathParam("requirementId") String requirementId,
145 @Context final HttpServletRequest request,
146 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
148 return get(requirementId, resourceId, request, userId);
152 @Consumes(MediaType.APPLICATION_JSON)
153 @Produces(MediaType.APPLICATION_JSON)
154 @Path("/resources/{resourceId}/requirements/{requirementId}")
155 @Operation(description = "Delete requirements from resource", method = "DELETE",
156 summary = "Delete requirements from resource", responses = {@ApiResponse(
157 content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class)))),
158 @ApiResponse(responseCode = "201", description = "Delete requirement"),
159 @ApiResponse(responseCode = "403", description = "Restricted operation"),
160 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
161 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
162 public Response deleteRequirementsFromResource(
163 @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId,
164 @Parameter(description = "requirement Id") @PathParam("requirementId") String requirementId,
165 @Context final HttpServletRequest request,
166 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
167 return delete(requirementId, resourceId, request, userId);
171 @Consumes(MediaType.APPLICATION_JSON)
172 @Produces(MediaType.APPLICATION_JSON)
173 @Path("/services/{serviceId}/requirements")
174 @Operation(description = "Create requirements on service", method = "POST",
175 summary = "Create requirements on service", responses = {
176 @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
177 @ApiResponse(responseCode = "201", description = "Create Requirements"),
178 @ApiResponse(responseCode = "403", description = "Restricted operation"),
179 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
180 @ApiResponse(responseCode = "409", description = "Requirement already exist")})
181 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
182 public Response createRequirementsOnService(
183 @Parameter(description = "Requirements to create", required = true) String data,
184 @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId,
185 @Context final HttpServletRequest request,
186 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
187 return createOrUpdate(data, "services" , serviceId, request, userId,
188 false , "createRequirements");
193 @Consumes(MediaType.APPLICATION_JSON)
194 @Produces(MediaType.APPLICATION_JSON)
195 @Path("/services/{serviceId}/requirements")
196 @Operation(description = "Update requirements on service", method = "PUT",
197 summary = "Update requirements on service", responses = {@ApiResponse(
198 content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class)))),
199 @ApiResponse(responseCode = "201", description = "Update requirements"),
200 @ApiResponse(responseCode = "403", description = "Restricted operation"),
201 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
202 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
203 public Response updateRequirementsOnService(
204 @Parameter(description = "Requirements to update", required = true) String data,
205 @Parameter(description = "Component Id") @PathParam("serviceId") String serviceId,
206 @Context final HttpServletRequest request,
207 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
208 return createOrUpdate(data, "services", serviceId, request, userId,
209 true, "updateRequirements");
213 @Consumes(MediaType.APPLICATION_JSON)
214 @Produces(MediaType.APPLICATION_JSON)
215 @Path("/services/{serviceId}/requirements/{requirementId}")
216 @Operation(description = "Get requirement from service", method = "GET", summary = "GET requirement from service",
217 responses = {@ApiResponse(content = @Content(
218 array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class)))),
219 @ApiResponse(responseCode = "201", description = "GET Requirements"),
220 @ApiResponse(responseCode = "403", description = "Restricted operation"),
221 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
222 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
223 public Response getRequirementsOnService(
224 @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId,
225 @Parameter(description = "Requirement Id") @PathParam("requirementId") String requirementId,
226 @Context final HttpServletRequest request,
227 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
229 return get(requirementId, serviceId, request, userId);
234 @Consumes(MediaType.APPLICATION_JSON)
235 @Produces(MediaType.APPLICATION_JSON)
236 @Path("/services/{serviceId}/requirements/{requirementId}")
237 @Operation(description = "Delete requirement from service", method = "DELETE",
238 summary = "Delete requirement from service", responses = {@ApiResponse(
239 content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class)))),
240 @ApiResponse(responseCode = "201", description = "Delete Requirements"),
241 @ApiResponse(responseCode = "403", description = "Restricted operation"),
242 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
243 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
244 public Response deleteRequirementsOnService(
245 @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId,
246 @Parameter(description = "Requirement Id") @PathParam("requirementId") String requirementId,
247 @Context final HttpServletRequest request,
248 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
249 return delete(requirementId, serviceId, request, userId);
253 private Response createOrUpdate (String data, String componentType, String componentId,
254 HttpServletRequest request, String userId,
255 boolean isUpdate, String errorContext) {
256 String url = request.getMethod() + " " + request.getRequestURI();
258 User modifier = new User();
259 modifier.setUserId(userId);
260 LOGGER.debug("Start create or update request of {} with modifier id {}", url, userId);
263 String componentIdLower = componentId.toLowerCase();
265 Either<List<RequirementDefinition>, ResponseFormat> mappedRequirementDataEither =
266 getMappedRequirementData(data, modifier, ComponentTypeEnum.findByParamName(componentType));
267 if(mappedRequirementDataEither.isRight()) {
268 LOGGER.error("Failed to create or update requirements");
269 return buildErrorResponse(mappedRequirementDataEither.right().value());
271 List<RequirementDefinition> mappedRequirementData = mappedRequirementDataEither.left().value();
272 Either<List<RequirementDefinition>, ResponseFormat> actionResponse;
274 actionResponse = requirementBusinessLogic.updateRequirements(componentIdLower, mappedRequirementData, modifier,
277 actionResponse = requirementBusinessLogic.createRequirements(componentIdLower, mappedRequirementData, modifier,
281 if (actionResponse.isRight()) {
282 LOGGER.error("Failed to create or update requirements");
283 return buildErrorResponse(actionResponse.right().value());
286 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
287 actionResponse.left().value());
288 } catch (Exception e) {
289 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("requirements create or update");
290 LOGGER.error("Failed to create or update requirements with an error", e);
291 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
295 private Response get (String requirementIdToGet, String componentId,
296 HttpServletRequest request, String userId){
297 String url = request.getMethod() + " " + request.getRequestURI();
299 User modifier = new User();
300 modifier.setUserId(userId);
301 LOGGER.debug("Start get request of {} with modifier id {}", url, userId);
304 String componentIdLower = componentId.toLowerCase();
306 Either<RequirementDefinition, ResponseFormat> actionResponse = requirementBusinessLogic
307 .getRequirement(componentIdLower, requirementIdToGet, modifier, true);
308 if (actionResponse.isRight()) {
309 LOGGER.error("failed to get requirements");
310 return buildErrorResponse(actionResponse.right().value());
312 Object result = RepresentationUtils.toFilteredRepresentation(actionResponse.left().value());
313 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
314 } catch (Exception e) {
315 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get requirements");
316 LOGGER.error("get requirements failed with exception", e);
317 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
321 private Response delete (String requirementId, String componentId, HttpServletRequest
322 request, String userId){
323 String url = request.getMethod() + " " + request.getRequestURI();
325 User modifier = new User();
326 modifier.setUserId(userId);
327 LOGGER.debug("Start delete request of {} with modifier id {}", url, userId);
330 String componentIdLower = componentId.toLowerCase();
332 Either<RequirementDefinition, ResponseFormat> actionResponse = requirementBusinessLogic
333 .deleteRequirement(componentIdLower, requirementId, modifier, true);
334 if (actionResponse.isRight()) {
335 LOGGER.error("failed to delete requirements");
336 return buildErrorResponse(actionResponse.right().value());
338 Object result = RepresentationUtils.toRepresentation(actionResponse.left().value());
339 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
340 } catch (Exception e) {
341 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete requirements");
342 LOGGER.error("Delete requirements failed with an error", e);
343 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
347 private Either<List<RequirementDefinition>, ResponseFormat> getMappedRequirementData(String inputJson, User user,
348 ComponentTypeEnum componentTypeEnum){
349 Either<UiComponentDataTransfer, ResponseFormat> mappedData = getComponentsUtils()
350 .convertJsonToObjectUsingObjectMapper(inputJson, user, UiComponentDataTransfer.class,
351 AuditingActionEnum.CREATE_RESOURCE, componentTypeEnum);
352 Optional<List<RequirementDefinition>> requirementDefinitionList = mappedData.left().value()
353 .getRequirements().values().stream().findFirst();
354 return requirementDefinitionList.<Either<List<RequirementDefinition>, ResponseFormat>>
355 map(Either::left).orElseGet(() -> Either.right(getComponentsUtils()
356 .getResponseFormat(ActionStatus.GENERAL_ERROR)));