catalog-be servlets refactoring
[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.annotations.Api;
22 import io.swagger.annotations.ApiOperation;
23 import io.swagger.annotations.ApiParam;
24 import io.swagger.annotations.ApiResponse;
25 import io.swagger.annotations.ApiResponses;
26 import javax.inject.Inject;
27 import org.openecomp.sdc.be.components.impl.CapabilitiesBusinessLogic;
28 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
29 import org.openecomp.sdc.be.components.impl.GroupBusinessLogic;
30 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
31 import org.openecomp.sdc.be.config.BeEcompErrorManager;
32 import org.openecomp.sdc.be.dao.api.ActionStatus;
33 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
34 import org.openecomp.sdc.be.impl.ComponentsUtils;
35 import org.openecomp.sdc.be.impl.ServletUtils;
36 import org.openecomp.sdc.be.model.CapabilityDefinition;
37 import org.openecomp.sdc.be.model.User;
38 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
39 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
40 import org.openecomp.sdc.be.user.UserBusinessLogic;
41 import org.openecomp.sdc.common.api.Constants;
42 import org.openecomp.sdc.common.log.wrappers.Logger;
43 import org.openecomp.sdc.exception.ResponseFormat;
44
45 import javax.inject.Singleton;
46 import javax.servlet.ServletContext;
47 import javax.servlet.http.HttpServletRequest;
48 import javax.ws.rs.Consumes;
49 import javax.ws.rs.DELETE;
50 import javax.ws.rs.GET;
51 import javax.ws.rs.HeaderParam;
52 import javax.ws.rs.POST;
53 import javax.ws.rs.PUT;
54 import javax.ws.rs.Path;
55 import javax.ws.rs.PathParam;
56 import javax.ws.rs.Produces;
57 import javax.ws.rs.core.Context;
58 import javax.ws.rs.core.MediaType;
59 import javax.ws.rs.core.Response;
60 import java.util.List;
61 import java.util.Optional;
62 import org.springframework.beans.factory.annotation.Autowired;
63
64 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
65 @Path("/v1/catalog")
66 @Consumes(MediaType.APPLICATION_JSON)
67 @Produces(MediaType.APPLICATION_JSON)
68 @Api(value = "Capability Servlet", description = "Capability Servlet")
69 @Singleton
70 public class CapabilityServlet extends AbstractValidationsServlet {
71     private static final Logger LOGGER = Logger.getLogger(CapabilityServlet.class);
72     private final CapabilitiesBusinessLogic capabilitiesBusinessLogic;
73
74     @Inject
75     public CapabilityServlet(UserBusinessLogic userBusinessLogic,
76         ComponentInstanceBusinessLogic componentInstanceBL,
77         ComponentsUtils componentsUtils, ServletUtils servletUtils,
78         ResourceImportManager resourceImportManager,
79         CapabilitiesBusinessLogic capabilitiesBusinessLogic) {
80         super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
81         this.capabilitiesBusinessLogic = capabilitiesBusinessLogic;
82     }
83
84
85     @POST
86     @Consumes(MediaType.APPLICATION_JSON)
87     @Produces(MediaType.APPLICATION_JSON)
88     @Path("/resources/{resourceId}/capabilities")
89     @ApiOperation(value = "Create Capabilities on resource", httpMethod = "POST",
90             notes = "Create Capabilities on resource", response = Response.class)
91     @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Capabilities"),
92             @ApiResponse(code = 403, message = "Restricted operation"),
93             @ApiResponse(code = 400, message = "Invalid content / Missing content"),
94             @ApiResponse(code = 409, message = "Capability already exist")})
95     public Response createCapabilitiesOnResource(
96             @ApiParam(value = "Capability to create", required = true) String data,
97             @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
98             @Context final HttpServletRequest request,
99             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
100         return createOrUpdate(data, "resources" , resourceId,
101                 request, userId, false, "createCapabilities");
102     }
103
104     @PUT
105     @Consumes(MediaType.APPLICATION_JSON)
106     @Produces(MediaType.APPLICATION_JSON)
107     @Path("/resources/{resourceId}/capabilities")
108     @ApiOperation(value = "Update Capabilities on resource", httpMethod = "PUT",
109             notes = "Update Capabilities on resource", response = CapabilityDefinition.class)
110     @ApiResponses(value = {@ApiResponse(code = 201, message = "Update Capabilities"),
111             @ApiResponse(code = 403, message = "Restricted operation"),
112             @ApiResponse(code = 400, message = "Invalid content / Missing content")})
113     public Response updateCapabilitiesOnResource(
114             @ApiParam(value = "Capabilities to update", required = true) String data,
115             @ApiParam(value = "Component Id") @PathParam("resourceId") String resourceId,
116             @Context final HttpServletRequest request,
117             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
118         return createOrUpdate(data, "resources", resourceId,
119                 request, userId, true, "updateCapabilities");
120     }
121
122     @GET
123     @Consumes(MediaType.APPLICATION_JSON)
124     @Produces(MediaType.APPLICATION_JSON)
125     @Path("/resources/{resourceId}/capabilities/{capabilityId}")
126     @ApiOperation(value = "Get Capability from resource", httpMethod = "GET",
127             notes = "GET Capability from resource", response = CapabilityDefinition.class)
128     @ApiResponses(value = {@ApiResponse(code = 201, message = "GET Capability"),
129             @ApiResponse(code = 403, message = "Restricted operation"),
130             @ApiResponse(code = 400, message = "Invalid content / Missing content")})
131     public Response getCapabilityOnResource(
132             @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
133             @ApiParam(value = "Capability Id") @PathParam("capabilityId") String capabilityId,
134             @Context final HttpServletRequest request,
135             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
136
137         return get(capabilityId, resourceId, request, userId);
138     }
139
140     @DELETE
141     @Consumes(MediaType.APPLICATION_JSON)
142     @Produces(MediaType.APPLICATION_JSON)
143     @Path("/resources/{resourceId}/capabilities/{capabilityId}")
144     @ApiOperation(value = "Delete capability from resource", httpMethod = "DELETE",
145             notes = "Delete capability from resource", response = CapabilityDefinition.class)
146     @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete capability"),
147             @ApiResponse(code = 403, message = "Restricted operation"),
148             @ApiResponse(code = 400, message = "Invalid content / Missing content")})
149     public Response deleteCapabilityOnResource(
150             @ApiParam(value = "capability Id") @PathParam("capabilityId") String capabilityId,
151             @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
152             @Context final HttpServletRequest request,
153             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
154         return delete(capabilityId, resourceId, request, userId);
155     }
156
157     @POST
158     @Consumes(MediaType.APPLICATION_JSON)
159     @Produces(MediaType.APPLICATION_JSON)
160     @Path("/services/{serviceId}/capabilities")
161     @ApiOperation(value = "Create Capabilities on service", httpMethod = "POST",
162             notes = "Create Capabilities on service", response = Response.class)
163     @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Capabilities"),
164             @ApiResponse(code = 403, message = "Restricted operation"),
165             @ApiResponse(code = 400, message = "Invalid content / Missing content"),
166             @ApiResponse(code = 409, message = "Capability already exist")})
167     public Response createCapabilitiesOnService(
168             @ApiParam(value = "Capability to create", required = true) String data,
169             @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
170             @Context final HttpServletRequest request,
171             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
172         return createOrUpdate(data, "services" , serviceId,
173                 request, userId, false, "createCapabilities");
174     }
175
176     @PUT
177     @Consumes(MediaType.APPLICATION_JSON)
178     @Produces(MediaType.APPLICATION_JSON)
179     @Path("/services/{serviceId}/capabilities")
180     @ApiOperation(value = "Update Capabilities on service", httpMethod = "PUT",
181             notes = "Update Capabilities on service", response = CapabilityDefinition.class)
182     @ApiResponses(value = {@ApiResponse(code = 201, message = "Update Capabilities"),
183             @ApiResponse(code = 403, message = "Restricted operation"),
184             @ApiResponse(code = 400, message = "Invalid content / Missing content")})
185     public Response updateCapabilitiesOnService(
186             @ApiParam(value = "Capabilities to update", required = true) String data,
187             @ApiParam(value = "Component Id") @PathParam("serviceId") String serviceId,
188             @Context final HttpServletRequest request,
189             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
190         return createOrUpdate(data, "services", serviceId,
191                 request, userId, true, "updateCapabilities");
192     }
193
194     @GET
195     @Consumes(MediaType.APPLICATION_JSON)
196     @Produces(MediaType.APPLICATION_JSON)
197     @Path("/services/{serviceId}/capabilities/{capabilityId}")
198     @ApiOperation(value = "Get Capability from service", httpMethod = "GET",
199             notes = "GET Capability from service", response = CapabilityDefinition.class)
200     @ApiResponses(value = {@ApiResponse(code = 201, message = "GET Capability"),
201             @ApiResponse(code = 403, message = "Restricted operation"),
202             @ApiResponse(code = 400, message = "Invalid content / Missing content")})
203     public Response getCapabilityOnService(
204             @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
205             @ApiParam(value = "Capability Id") @PathParam("capabilityId") String capabilityId,
206             @Context final HttpServletRequest request,
207             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
208
209         return get(capabilityId, serviceId, request, userId);
210     }
211
212     @DELETE
213     @Consumes(MediaType.APPLICATION_JSON)
214     @Produces(MediaType.APPLICATION_JSON)
215     @Path("/services/{serviceId}/capabilities/{capabilityId}")
216     @ApiOperation(value = "Delete capability from service", httpMethod = "DELETE",
217             notes = "Delete capability from service", response = CapabilityDefinition.class)
218     @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete capability"),
219             @ApiResponse(code = 403, message = "Restricted operation"),
220             @ApiResponse(code = 400, message = "Invalid content / Missing content")})
221     public Response deleteCapabilityOnService(
222             @ApiParam(value = "capability Id") @PathParam("capabilityId") String capabilityId,
223             @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
224             @Context final HttpServletRequest request,
225             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
226         return delete(capabilityId, serviceId, request, userId);
227     }
228
229     private Response createOrUpdate (String data, String componentType, String componentId,
230                                      HttpServletRequest request,
231                                      String userId,
232                                      boolean isUpdate,
233                                      String errorContext) {
234         String url = request.getMethod() + " " + request.getRequestURI();
235
236         User modifier = new User();
237         modifier.setUserId(userId);
238         LOGGER.debug("Start create or update request of {} with modifier id {}", url, userId);
239         try {
240             String componentIdLower = componentId.toLowerCase();
241
242             Either<List<CapabilityDefinition>, ResponseFormat> mappedCapabilitiesDataEither
243                     = getMappedCapabilitiesData(data, modifier, ComponentTypeEnum.findByParamName(componentType));
244             if(mappedCapabilitiesDataEither.isRight()) {
245                 LOGGER.error("Failed to create or update capabilities");
246                 buildErrorResponse(mappedCapabilitiesDataEither.right().value());
247             }
248             List<CapabilityDefinition> mappedCapabilitiesData = mappedCapabilitiesDataEither.left().value();
249             Either<List<CapabilityDefinition>, ResponseFormat> actionResponse;
250             if(isUpdate) {
251                 actionResponse = capabilitiesBusinessLogic.updateCapabilities(componentIdLower,
252                         mappedCapabilitiesData, modifier, errorContext, true);
253             } else {
254                 actionResponse = capabilitiesBusinessLogic.createCapabilities(componentIdLower,
255                         mappedCapabilitiesData, modifier, errorContext, true);
256             }
257             if (actionResponse.isRight()) {
258                 LOGGER.error("Failed to create or update capabilities");
259                 return buildErrorResponse(actionResponse.right().value());
260             }
261             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
262                     actionResponse.left().value());
263         } catch (Exception e) {
264             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Capabilities create or update");
265             LOGGER.error("Failed to create or update capabilities with an error", e);
266             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
267         }
268     }
269
270     private Response get (String capabilityIdToGet,  String componentId,
271                           HttpServletRequest request, String userId){
272         String url = request.getMethod() + " " + request.getRequestURI();
273
274         User modifier = new User();
275         modifier.setUserId(userId);
276         LOGGER.debug("Start get request of {} with modifier id {}", url, userId);
277
278         try {
279             String componentIdLower = componentId.toLowerCase();
280
281             Either<CapabilityDefinition, ResponseFormat> actionResponse = capabilitiesBusinessLogic
282                     .getCapability(componentIdLower, capabilityIdToGet, modifier, true);
283             if (actionResponse.isRight()) {
284                 LOGGER.error("failed to get capability");
285                 return buildErrorResponse(actionResponse.right().value());
286             }
287             Object result = RepresentationUtils.toFilteredRepresentation(actionResponse.left().value());
288             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
289         } catch (Exception e) {
290             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get capability");
291             LOGGER.error("get capabilities failed with exception", e);
292             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
293         }
294     }
295
296     private Response delete (String capabilityId, String componentId, HttpServletRequest
297             request, String userId){
298
299         String url = request.getMethod() + " " + request.getRequestURI();
300
301         User modifier = new User();
302         modifier.setUserId(userId);
303         LOGGER.debug("Start delete request of {} with modifier id {}", url, userId);
304
305         try {
306             String componentIdLower = componentId.toLowerCase();
307
308             Either<CapabilityDefinition, ResponseFormat> actionResponse = capabilitiesBusinessLogic
309                     .deleteCapability(componentIdLower, capabilityId, modifier, true);
310             if (actionResponse.isRight()) {
311                 LOGGER.error("failed to delete capability");
312                 return buildErrorResponse(actionResponse.right().value());
313             }
314             Object result = RepresentationUtils.toRepresentation(actionResponse.left().value());
315             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
316         } catch (Exception e) {
317             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete capability");
318             LOGGER.error("Delete capability failed with an error", e);
319             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
320         }
321     }
322
323     private Either<List<CapabilityDefinition>, ResponseFormat> getMappedCapabilitiesData(String inputJson, User user,
324                                                                  ComponentTypeEnum componentTypeEnum){
325         Either<UiComponentDataTransfer, ResponseFormat> mappedData = getComponentsUtils()
326                 .convertJsonToObjectUsingObjectMapper(inputJson, user, UiComponentDataTransfer.class,
327                         AuditingActionEnum.CREATE_RESOURCE, componentTypeEnum);
328         Optional<List<CapabilityDefinition>> capabilityDefinitionList =
329                 mappedData.left().value().getCapabilities().values().stream().findFirst();
330         return capabilityDefinitionList.<Either<List<CapabilityDefinition>, ResponseFormat>>
331                 map(Either::left).orElseGet(() -> Either.right(getComponentsUtils()
332                 .getResponseFormat(ActionStatus.GENERAL_ERROR)));
333     }
334 }