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.OpenAPIDefinition;
22 import io.swagger.v3.oas.annotations.Operation;
23 import io.swagger.v3.oas.annotations.Parameter;
24 import io.swagger.v3.oas.annotations.info.Info;
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.responses.ApiResponses;
30 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
31 import org.openecomp.sdc.be.components.impl.RequirementBusinessLogic;
32 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
33 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
34 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
35 import org.openecomp.sdc.be.config.BeEcompErrorManager;
36 import org.openecomp.sdc.be.dao.api.ActionStatus;
37 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
38 import org.openecomp.sdc.be.impl.ComponentsUtils;
39 import org.openecomp.sdc.be.impl.ServletUtils;
40 import org.openecomp.sdc.be.model.RequirementDefinition;
41 import org.openecomp.sdc.be.model.User;
42 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
43 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
44 import org.openecomp.sdc.be.user.UserBusinessLogic;
45 import org.openecomp.sdc.common.api.Constants;
46 import org.openecomp.sdc.common.log.wrappers.Logger;
47 import org.openecomp.sdc.exception.ResponseFormat;
48 import org.springframework.stereotype.Controller;
50 import javax.inject.Inject;
51 import javax.servlet.http.HttpServletRequest;
52 import javax.ws.rs.Consumes;
53 import javax.ws.rs.DELETE;
54 import javax.ws.rs.GET;
55 import javax.ws.rs.HeaderParam;
56 import javax.ws.rs.POST;
57 import javax.ws.rs.PUT;
58 import javax.ws.rs.Path;
59 import javax.ws.rs.PathParam;
60 import javax.ws.rs.Produces;
61 import javax.ws.rs.core.Context;
62 import javax.ws.rs.core.MediaType;
63 import javax.ws.rs.core.Response;
64 import java.util.List;
65 import java.util.Optional;
67 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
69 @Consumes(MediaType.APPLICATION_JSON)
70 @Produces(MediaType.APPLICATION_JSON)
71 @OpenAPIDefinition(info = @Info(title = "Requirement Servlet", description = "Requirement Servlet"))
73 public class RequirementServlet extends AbstractValidationsServlet {
74 private static final Logger LOGGER = Logger.getLogger(RequirementServlet.class);
75 private final RequirementBusinessLogic requirementBusinessLogic;
78 public RequirementServlet(UserBusinessLogic userBusinessLogic,
79 ComponentInstanceBusinessLogic componentInstanceBL,
80 ComponentsUtils componentsUtils, ServletUtils servletUtils,
81 ResourceImportManager resourceImportManager,
82 RequirementBusinessLogic requirementBusinessLogic) {
83 super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
84 this.requirementBusinessLogic = requirementBusinessLogic;
88 @Consumes(MediaType.APPLICATION_JSON)
89 @Produces(MediaType.APPLICATION_JSON)
90 @Path("/resources/{resourceId}/requirements")
91 @Operation(description = "Create requirements on resource", method = "POST",
92 summary = "Create requirements on resource",responses = @ApiResponse(
93 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
94 @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Create requirements"),
95 @ApiResponse(responseCode = "403", description = "Restricted operation"),
96 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
97 @ApiResponse(responseCode = "409", description = "requirement already exist")})
98 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
99 public Response createRequirementsOnResource(
100 @Parameter(description = "Requirement to create", required = true) String data,
101 @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId,
102 @Context final HttpServletRequest request,
103 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
104 return createOrUpdate(data, "resources" , resourceId, request,
105 userId, false, "createRequirements");
110 @Consumes(MediaType.APPLICATION_JSON)
111 @Produces(MediaType.APPLICATION_JSON)
112 @Path("/resources/{resourceId}/requirements")
113 @Operation(description = "Update Requirements on resource", method = "PUT",
114 summary = "Update Requirements on resource", responses = @ApiResponse(
115 content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class)))))
116 @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Update Requirements"),
117 @ApiResponse(responseCode = "403", description = "Restricted operation"),
118 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
119 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
120 public Response updateRequirementsOnResource(
121 @Parameter(description = "Requirements to update", required = true) String data,
122 @Parameter(description = "Component Id") @PathParam("resourceId") String resourceId,
123 @Context final HttpServletRequest request,
124 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
125 return createOrUpdate(data, "resources", resourceId, request,
126 userId, true, "updateRequirements");
130 @Consumes(MediaType.APPLICATION_JSON)
131 @Produces(MediaType.APPLICATION_JSON)
132 @Path("/resources/{resourceId}/requirements/{requirementId}")
133 @Operation(description = "Get Requirement from resource", method = "GET",
134 summary = "GET Requirement from resource", responses = @ApiResponse(
135 content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class)))))
136 @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "GET requirement"),
137 @ApiResponse(responseCode = "403", description = "Restricted operation"),
138 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
139 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
140 public Response getRequirementsFromResource(
141 @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId,
142 @Parameter(description = "Requirement Id") @PathParam("requirementId") String requirementId,
143 @Context final HttpServletRequest request,
144 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
146 return get(requirementId, resourceId, request, userId);
150 @Consumes(MediaType.APPLICATION_JSON)
151 @Produces(MediaType.APPLICATION_JSON)
152 @Path("/resources/{resourceId}/requirements/{requirementId}")
153 @Operation(description = "Delete requirements from resource", method = "DELETE",
154 summary = "Delete requirements from resource", responses = @ApiResponse(
155 content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class)))))
156 @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Delete requirement"),
157 @ApiResponse(responseCode = "403", description = "Restricted operation"),
158 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
159 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
160 public Response deleteRequirementsFromResource(
161 @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId,
162 @Parameter(description = "requirement Id") @PathParam("requirementId") String requirementId,
163 @Context final HttpServletRequest request,
164 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
165 return delete(requirementId, resourceId, request, userId);
169 @Consumes(MediaType.APPLICATION_JSON)
170 @Produces(MediaType.APPLICATION_JSON)
171 @Path("/services/{serviceId}/requirements")
172 @Operation(description = "Create requirements on service", method = "POST",
173 summary = "Create requirements on service", responses = @ApiResponse(
174 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
175 @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Create Requirements"),
176 @ApiResponse(responseCode = "403", description = "Restricted operation"),
177 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
178 @ApiResponse(responseCode = "409", description = "Requirement already exist")})
179 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
180 public Response createRequirementsOnService(
181 @Parameter(description = "Requirements to create", required = true) String data,
182 @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId,
183 @Context final HttpServletRequest request,
184 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
185 return createOrUpdate(data, "services" , serviceId, request, userId,
186 false , "createRequirements");
191 @Consumes(MediaType.APPLICATION_JSON)
192 @Produces(MediaType.APPLICATION_JSON)
193 @Path("/services/{serviceId}/requirements")
194 @Operation(description = "Update requirements on service", method = "PUT",
195 summary = "Update requirements on service", responses = @ApiResponse(
196 content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class)))))
197 @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Update requirements"),
198 @ApiResponse(responseCode = "403", description = "Restricted operation"),
199 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
200 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
201 public Response updateRequirementsOnService(
202 @Parameter(description = "Requirements to update", required = true) String data,
203 @Parameter(description = "Component Id") @PathParam("serviceId") String serviceId,
204 @Context final HttpServletRequest request,
205 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
206 return createOrUpdate(data, "services", serviceId, request, userId,
207 true, "updateRequirements");
211 @Consumes(MediaType.APPLICATION_JSON)
212 @Produces(MediaType.APPLICATION_JSON)
213 @Path("/services/{serviceId}/requirements/{requirementId}")
214 @Operation(description = "Get requirement from service", method = "GET",
215 summary = "GET requirement from service", responses = @ApiResponse(
216 content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class)))))
217 @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "GET Requirements"),
218 @ApiResponse(responseCode = "403", description = "Restricted operation"),
219 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
220 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
221 public Response getRequirementsOnService(
222 @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId,
223 @Parameter(description = "Requirement Id") @PathParam("requirementId") String requirementId,
224 @Context final HttpServletRequest request,
225 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
227 return get(requirementId, serviceId, request, userId);
232 @Consumes(MediaType.APPLICATION_JSON)
233 @Produces(MediaType.APPLICATION_JSON)
234 @Path("/services/{serviceId}/requirements/{requirementId}")
235 @Operation(description = "Delete requirement from service", method = "DELETE",
236 summary = "Delete requirement from service", responses = @ApiResponse(
237 content = @Content(array = @ArraySchema(schema = @Schema(implementation = RequirementDefinition.class)))))
238 @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Delete Requirements"),
239 @ApiResponse(responseCode = "403", description = "Restricted operation"),
240 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
241 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
242 public Response deleteRequirementsOnService(
243 @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId,
244 @Parameter(description = "Requirement Id") @PathParam("requirementId") String requirementId,
245 @Context final HttpServletRequest request,
246 @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
247 return delete(requirementId, serviceId, request, userId);
251 private Response createOrUpdate (String data, String componentType, String componentId,
252 HttpServletRequest request, String userId,
253 boolean isUpdate, String errorContext) {
254 String url = request.getMethod() + " " + request.getRequestURI();
256 User modifier = new User();
257 modifier.setUserId(userId);
258 LOGGER.debug("Start create or update request of {} with modifier id {}", url, userId);
261 String componentIdLower = componentId.toLowerCase();
263 Either<List<RequirementDefinition>, ResponseFormat> mappedRequirementDataEither =
264 getMappedRequirementData(data, modifier, ComponentTypeEnum.findByParamName(componentType));
265 if(mappedRequirementDataEither.isRight()) {
266 LOGGER.error("Failed to create or update requirements");
267 return buildErrorResponse(mappedRequirementDataEither.right().value());
269 List<RequirementDefinition> mappedRequirementData = mappedRequirementDataEither.left().value();
270 Either<List<RequirementDefinition>, ResponseFormat> actionResponse;
272 actionResponse = requirementBusinessLogic.updateRequirements(componentIdLower, mappedRequirementData, modifier,
275 actionResponse = requirementBusinessLogic.createRequirements(componentIdLower, mappedRequirementData, modifier,
279 if (actionResponse.isRight()) {
280 LOGGER.error("Failed to create or update requirements");
281 return buildErrorResponse(actionResponse.right().value());
284 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
285 actionResponse.left().value());
286 } catch (Exception e) {
287 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("requirements create or update");
288 LOGGER.error("Failed to create or update requirements with an error", e);
289 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
293 private Response get (String requirementIdToGet, String componentId,
294 HttpServletRequest request, String userId){
295 String url = request.getMethod() + " " + request.getRequestURI();
297 User modifier = new User();
298 modifier.setUserId(userId);
299 LOGGER.debug("Start get request of {} with modifier id {}", url, userId);
302 String componentIdLower = componentId.toLowerCase();
304 Either<RequirementDefinition, ResponseFormat> actionResponse = requirementBusinessLogic
305 .getRequirement(componentIdLower, requirementIdToGet, modifier, true);
306 if (actionResponse.isRight()) {
307 LOGGER.error("failed to get requirements");
308 return buildErrorResponse(actionResponse.right().value());
310 Object result = RepresentationUtils.toFilteredRepresentation(actionResponse.left().value());
311 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
312 } catch (Exception e) {
313 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get requirements");
314 LOGGER.error("get requirements failed with exception", e);
315 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
319 private Response delete (String requirementId, String componentId, HttpServletRequest
320 request, String userId){
321 String url = request.getMethod() + " " + request.getRequestURI();
323 User modifier = new User();
324 modifier.setUserId(userId);
325 LOGGER.debug("Start delete request of {} with modifier id {}", url, userId);
328 String componentIdLower = componentId.toLowerCase();
330 Either<RequirementDefinition, ResponseFormat> actionResponse = requirementBusinessLogic
331 .deleteRequirement(componentIdLower, requirementId, modifier, true);
332 if (actionResponse.isRight()) {
333 LOGGER.error("failed to delete requirements");
334 return buildErrorResponse(actionResponse.right().value());
336 Object result = RepresentationUtils.toRepresentation(actionResponse.left().value());
337 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
338 } catch (Exception e) {
339 BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete requirements");
340 LOGGER.error("Delete requirements failed with an error", e);
341 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
345 private Either<List<RequirementDefinition>, ResponseFormat> getMappedRequirementData(String inputJson, User user,
346 ComponentTypeEnum componentTypeEnum){
347 Either<UiComponentDataTransfer, ResponseFormat> mappedData = getComponentsUtils()
348 .convertJsonToObjectUsingObjectMapper(inputJson, user, UiComponentDataTransfer.class,
349 AuditingActionEnum.CREATE_RESOURCE, componentTypeEnum);
350 Optional<List<RequirementDefinition>> requirementDefinitionList = mappedData.left().value()
351 .getRequirements().values().stream().findFirst();
352 return requirementDefinitionList.<Either<List<RequirementDefinition>, ResponseFormat>>
353 map(Either::left).orElseGet(() -> Either.right(getComponentsUtils()
354 .getResponseFormat(ActionStatus.GENERAL_ERROR)));