Catalog alignment
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / CapabilityServlet.java
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.openecomp.sdc.be.servlets;
18
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.CapabilitiesBusinessLogic;
31 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
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.CapabilityDefinition;
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;
49
50 import javax.inject.Inject;
51 import javax.servlet.ServletContext;
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;
67
68 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
69 @Path("/v1/catalog")
70 @Consumes(MediaType.APPLICATION_JSON)
71 @Produces(MediaType.APPLICATION_JSON)
72 @OpenAPIDefinition(info = @Info(title = "Capability Servlet", description = "Capability Servlet"))
73 @Controller
74 public class CapabilityServlet extends AbstractValidationsServlet {
75     private static final Logger LOGGER = Logger.getLogger(CapabilityServlet.class);
76     private final CapabilitiesBusinessLogic capabilitiesBusinessLogic;
77
78     @Inject
79     public CapabilityServlet(UserBusinessLogic userBusinessLogic,
80         ComponentInstanceBusinessLogic componentInstanceBL,
81         ComponentsUtils componentsUtils, ServletUtils servletUtils,
82         ResourceImportManager resourceImportManager,
83         CapabilitiesBusinessLogic capabilitiesBusinessLogic) {
84         super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
85         this.capabilitiesBusinessLogic = capabilitiesBusinessLogic;
86     }
87
88
89     @POST
90     @Consumes(MediaType.APPLICATION_JSON)
91     @Produces(MediaType.APPLICATION_JSON)
92     @Path("/resources/{resourceId}/capabilities")
93     @Operation(description = "Create Capabilities on resource", method = "POST",
94             summary = "Create Capabilities on resource",  responses = @ApiResponse(
95                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
96     @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Create Capabilities"),
97             @ApiResponse(responseCode = "403", description = "Restricted operation"),
98             @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
99             @ApiResponse(responseCode = "409", description = "Capability already exist")})
100     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
101     public Response createCapabilitiesOnResource(
102             @Parameter(description = "Capability 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,
107                 request, userId, false, "createCapabilities");
108     }
109
110     @PUT
111     @Consumes(MediaType.APPLICATION_JSON)
112     @Produces(MediaType.APPLICATION_JSON)
113     @Path("/resources/{resourceId}/capabilities")
114     @Operation(description = "Update Capabilities on resource", method = "PUT",
115             summary = "Update Capabilities on resource",responses = @ApiResponse(
116                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = CapabilityDefinition.class)))))
117     @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Update Capabilities"),
118             @ApiResponse(responseCode = "403", description = "Restricted operation"),
119             @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
120     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
121     public Response updateCapabilitiesOnResource(
122             @Parameter(description = "Capabilities to update", required = true) String data,
123             @Parameter(description = "Component Id") @PathParam("resourceId") String resourceId,
124             @Context final HttpServletRequest request,
125             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
126         return createOrUpdate(data, "resources", resourceId,
127                 request, userId, true, "updateCapabilities");
128     }
129
130     @GET
131     @Consumes(MediaType.APPLICATION_JSON)
132     @Produces(MediaType.APPLICATION_JSON)
133     @Path("/resources/{resourceId}/capabilities/{capabilityId}")
134     @Operation(description = "Get Capability from resource", method = "GET",
135             summary = "GET Capability from resource", responses = @ApiResponse(
136                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = CapabilityDefinition.class)))))
137     @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "GET Capability"),
138             @ApiResponse(responseCode = "403", description = "Restricted operation"),
139             @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
140     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
141     public Response getCapabilityOnResource(
142             @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId,
143             @Parameter(description = "Capability Id") @PathParam("capabilityId") String capabilityId,
144             @Context final HttpServletRequest request,
145             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
146
147         return get(capabilityId, resourceId, request, userId);
148     }
149
150     @DELETE
151     @Consumes(MediaType.APPLICATION_JSON)
152     @Produces(MediaType.APPLICATION_JSON)
153     @Path("/resources/{resourceId}/capabilities/{capabilityId}")
154     @Operation(description = "Delete capability from resource", method = "DELETE",
155             summary = "Delete capability from resource", responses = @ApiResponse(
156                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = CapabilityDefinition.class)))))
157     @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Delete capability"),
158             @ApiResponse(responseCode = "403", description = "Restricted operation"),
159             @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
160     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
161     public Response deleteCapabilityOnResource(
162             @Parameter(description = "capability Id") @PathParam("capabilityId") String capabilityId,
163             @Parameter(description = "Resource Id") @PathParam("resourceId") String resourceId,
164             @Context final HttpServletRequest request,
165             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
166         return delete(capabilityId, resourceId, request, userId);
167     }
168
169     @POST
170     @Consumes(MediaType.APPLICATION_JSON)
171     @Produces(MediaType.APPLICATION_JSON)
172     @Path("/services/{serviceId}/capabilities")
173     @Operation(description = "Create Capabilities on service", method = "POST",
174             summary = "Create Capabilities on service", responses = @ApiResponse(
175                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
176     @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Create Capabilities"),
177             @ApiResponse(responseCode = "403", description = "Restricted operation"),
178             @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"),
179             @ApiResponse(responseCode = "409", description = "Capability already exist")})
180     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
181     public Response createCapabilitiesOnService(
182             @Parameter(description = "Capability to create", required = true) String data,
183             @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId,
184             @Context final HttpServletRequest request,
185             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
186         return createOrUpdate(data, "services" , serviceId,
187                 request, userId, false, "createCapabilities");
188     }
189
190     @PUT
191     @Consumes(MediaType.APPLICATION_JSON)
192     @Produces(MediaType.APPLICATION_JSON)
193     @Path("/services/{serviceId}/capabilities")
194     @Operation(description = "Update Capabilities on service", method = "PUT",
195             summary = "Update Capabilities on service",responses = @ApiResponse(
196                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = CapabilityDefinition.class)))))
197     @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Update Capabilities"),
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 updateCapabilitiesOnService(
202             @Parameter(description = "Capabilities 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,
207                 request, userId, true, "updateCapabilities");
208     }
209
210     @GET
211     @Consumes(MediaType.APPLICATION_JSON)
212     @Produces(MediaType.APPLICATION_JSON)
213     @Path("/services/{serviceId}/capabilities/{capabilityId}")
214     @Operation(description = "Get Capability from service", method = "GET",
215             summary = "GET Capability from service", responses = @ApiResponse(
216                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = CapabilityDefinition.class)))))
217     @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "GET Capability"),
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 getCapabilityOnService(
222             @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId,
223             @Parameter(description = "Capability Id") @PathParam("capabilityId") String capabilityId,
224             @Context final HttpServletRequest request,
225             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
226
227         return get(capabilityId, serviceId, request, userId);
228     }
229
230     @DELETE
231     @Consumes(MediaType.APPLICATION_JSON)
232     @Produces(MediaType.APPLICATION_JSON)
233     @Path("/services/{serviceId}/capabilities/{capabilityId}")
234     @Operation(description = "Delete capability from service", method = "DELETE",
235             summary = "Delete capability from service",responses = @ApiResponse(
236                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = CapabilityDefinition.class)))))
237     @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Delete capability"),
238             @ApiResponse(responseCode = "403", description = "Restricted operation"),
239             @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
240     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
241     public Response deleteCapabilityOnService(
242             @Parameter(description = "capability Id") @PathParam("capabilityId") String capabilityId,
243             @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId,
244             @Context final HttpServletRequest request,
245             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
246         return delete(capabilityId, serviceId, request, userId);
247     }
248
249     private Response createOrUpdate (String data, String componentType, String componentId,
250                                      HttpServletRequest request,
251                                      String userId,
252                                      boolean isUpdate,
253                                      String errorContext) {
254         ServletContext context = request.getSession().getServletContext();
255         String url = request.getMethod() + " " + request.getRequestURI();
256
257         User modifier = new User();
258         modifier.setUserId(userId);
259         LOGGER.debug("Start create or update request of {} with modifier id {}", url, userId);
260         try {
261             String componentIdLower = componentId.toLowerCase();
262
263             Either<List<CapabilityDefinition>, ResponseFormat> mappedCapabilitiesDataEither
264                     = getMappedCapabilitiesData(data, modifier, ComponentTypeEnum.findByParamName(componentType));
265             if(mappedCapabilitiesDataEither.isRight()) {
266                 LOGGER.error("Failed to create or update capabilities");
267                 buildErrorResponse(mappedCapabilitiesDataEither.right().value());
268             }
269             List<CapabilityDefinition> mappedCapabilitiesData = mappedCapabilitiesDataEither.left().value();
270             Either<List<CapabilityDefinition>, ResponseFormat> actionResponse;
271             if(isUpdate) {
272                 actionResponse = capabilitiesBusinessLogic.updateCapabilities(componentIdLower,
273                         mappedCapabilitiesData, modifier, errorContext, true);
274             } else {
275                 actionResponse = capabilitiesBusinessLogic.createCapabilities(componentIdLower,
276                         mappedCapabilitiesData, modifier, errorContext, true);
277             }
278             if (actionResponse.isRight()) {
279                 LOGGER.error("Failed to create or update capabilities");
280                 return buildErrorResponse(actionResponse.right().value());
281             }
282             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
283                     actionResponse.left().value());
284         } catch (Exception e) {
285             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Capabilities create or update");
286             LOGGER.error("Failed to create or update capabilities with an error", e);
287             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
288         }
289     }
290
291     private Response get (String capabilityIdToGet,  String componentId,
292                           HttpServletRequest request, String userId){
293         ServletContext context = request.getSession().getServletContext();
294         String url = request.getMethod() + " " + request.getRequestURI();
295
296         User modifier = new User();
297         modifier.setUserId(userId);
298         LOGGER.debug("Start get request of {} with modifier id {}", url, userId);
299
300         try {
301             String componentIdLower = componentId.toLowerCase();
302
303             Either<CapabilityDefinition, ResponseFormat> actionResponse = capabilitiesBusinessLogic
304                     .getCapability(componentIdLower, capabilityIdToGet, modifier, true);
305             if (actionResponse.isRight()) {
306                 LOGGER.error("failed to get capability");
307                 return buildErrorResponse(actionResponse.right().value());
308             }
309             Object result = RepresentationUtils.toFilteredRepresentation(actionResponse.left().value());
310             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
311         } catch (Exception e) {
312             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get capability");
313             LOGGER.error("get capabilities failed with exception", e);
314             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
315         }
316     }
317
318     private Response delete (String capabilityId, String componentId, HttpServletRequest
319             request, String userId){
320
321         ServletContext context = request.getSession().getServletContext();
322         String url = request.getMethod() + " " + request.getRequestURI();
323
324         User modifier = new User();
325         modifier.setUserId(userId);
326         LOGGER.debug("Start delete request of {} with modifier id {}", url, userId);
327
328         try {
329             String componentIdLower = componentId.toLowerCase();
330
331             Either<CapabilityDefinition, ResponseFormat> actionResponse = capabilitiesBusinessLogic
332                     .deleteCapability(componentIdLower, capabilityId, modifier, true);
333             if (actionResponse.isRight()) {
334                 LOGGER.error("failed to delete capability");
335                 return buildErrorResponse(actionResponse.right().value());
336             }
337             Object result = RepresentationUtils.toRepresentation(actionResponse.left().value());
338             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
339         } catch (Exception e) {
340             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete capability");
341             LOGGER.error("Delete capability failed with an error", e);
342             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
343         }
344     }
345
346     private Either<List<CapabilityDefinition>, ResponseFormat> getMappedCapabilitiesData(String inputJson, User user,
347                                                                  ComponentTypeEnum componentTypeEnum){
348         Either<UiComponentDataTransfer, ResponseFormat> mappedData = getComponentsUtils()
349                 .convertJsonToObjectUsingObjectMapper(inputJson, user, UiComponentDataTransfer.class,
350                         AuditingActionEnum.CREATE_RESOURCE, componentTypeEnum);
351         Optional<List<CapabilityDefinition>> capabilityDefinitionList =
352                 mappedData.left().value().getCapabilities().values().stream().findFirst();
353         return capabilityDefinitionList.<Either<List<CapabilityDefinition>, ResponseFormat>>
354                 map(Either::left).orElseGet(() -> Either.right(getComponentsUtils()
355                 .getResponseFormat(ActionStatus.GENERAL_ERROR)));
356     }
357 }