af6976d7b372eeb0fc7a5eb7aa4f92b2e18c9bf8
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / InterfaceOperationServlet.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.google.common.collect.ImmutableMap;
20 import com.jcabi.aspects.Loggable;
21 import fj.data.Either;
22 import io.swagger.annotations.Api;
23 import io.swagger.annotations.ApiOperation;
24 import io.swagger.annotations.ApiParam;
25 import io.swagger.annotations.ApiResponse;
26 import io.swagger.annotations.ApiResponses;
27 import java.io.IOException;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.stream.Collectors;
31 import java.util.stream.Stream;
32 import javax.inject.Singleton;
33 import javax.servlet.ServletContext;
34 import javax.servlet.http.HttpServletRequest;
35 import javax.ws.rs.Consumes;
36 import javax.ws.rs.DELETE;
37 import javax.ws.rs.GET;
38 import javax.ws.rs.HeaderParam;
39 import javax.ws.rs.POST;
40 import javax.ws.rs.PUT;
41 import javax.ws.rs.Path;
42 import javax.ws.rs.PathParam;
43 import javax.ws.rs.Produces;
44 import javax.ws.rs.core.Context;
45 import javax.ws.rs.core.MediaType;
46 import javax.ws.rs.core.Response;
47 import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic;
48 import org.openecomp.sdc.be.config.BeEcompErrorManager;
49 import org.openecomp.sdc.be.dao.api.ActionStatus;
50 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
51 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
52 import org.openecomp.sdc.be.model.InterfaceDefinition;
53 import org.openecomp.sdc.be.model.User;
54 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
55 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
56 import org.openecomp.sdc.common.api.Constants;
57 import org.openecomp.sdc.exception.ResponseFormat;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
62 @Path("/v1/catalog")
63 @Consumes(MediaType.APPLICATION_JSON)
64 @Produces(MediaType.APPLICATION_JSON)
65 @Api(value = "Interface Operation Servlet", description = "Interface Operation Servlet")
66 @Singleton
67 public class InterfaceOperationServlet extends AbstractValidationsServlet {
68
69   private static final Logger log = LoggerFactory.getLogger(InterfaceOperationServlet.class);
70
71   @POST
72   @Consumes(MediaType.APPLICATION_JSON)
73   @Produces(MediaType.APPLICATION_JSON)
74   @Path("/resources/{resourceId}/interfaceOperations")
75   @ApiOperation(value = "Create Interface Operations on Resource", httpMethod = "POST", notes = "Create Interface Operations on Resource", response = Response.class)
76   @ApiResponses(value = {
77       @ApiResponse(code = 201, message = "Create Interface Operations on Resource"),
78       @ApiResponse(code = 400, message = "Invalid content / Missing content"),
79       @ApiResponse(code = 403, message = "Restricted operation"),
80       @ApiResponse(code = 404, message = "Resource not found"),
81       @ApiResponse(code = 409, message = "Interface Operation already exist")})
82   public Response createInterfaceOperationsOnResource(
83       @ApiParam(value = "Interface Operations to create", required = true) String data,
84       @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
85       @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
86       @Context final HttpServletRequest request) {
87     return createOrUpdate(data, ComponentTypeEnum.RESOURCE, resourceId, request, userId, false);
88   }
89
90   @PUT
91   @Consumes(MediaType.APPLICATION_JSON)
92   @Produces(MediaType.APPLICATION_JSON)
93   @Path("/resources/{resourceId}/interfaceOperations")
94   @ApiOperation(value = "Update Interface Operations on Resource", httpMethod = "PUT", notes = "Update Interface Operations on Resource", response = Response.class)
95   @ApiResponses(value = {
96       @ApiResponse(code = 201, message = "Update Interface Operations on Resource"),
97       @ApiResponse(code = 400, message = "Invalid content / Missing content"),
98       @ApiResponse(code = 403, message = "Restricted operation"),
99       @ApiResponse(code = 404, message = "Resource not found")})
100   public Response updateInterfaceOperationsOnResource(
101       @ApiParam(value = "Interface Operations to update", required = true) String data,
102       @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
103       @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
104       @Context final HttpServletRequest request) {
105     return createOrUpdate(data, ComponentTypeEnum.RESOURCE, resourceId, request, userId, true);
106   }
107
108   @DELETE
109   @Consumes(MediaType.APPLICATION_JSON)
110   @Produces(MediaType.APPLICATION_JSON)
111   @Path("/resources/{resourceId}/interfaces/{interfaceId}/operations/{operationIds}")
112   @ApiOperation(value = "Delete Interface Operations from Resource", httpMethod = "DELETE", notes = "Delete Interface Operations from Resource", response = Response.class)
113   @ApiResponses(value = {
114       @ApiResponse(code = 201, message = "Delete Interface Operations from Resource"),
115       @ApiResponse(code = 400, message = "Invalid content / Missing content"),
116       @ApiResponse(code = 403, message = "Restricted operation"),
117       @ApiResponse(code = 404, message = "Resource not found")})
118   public Response deleteInterfaceOperationsFromResource(
119       @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
120       @ApiParam(value = "Interface Id") @PathParam("interfaceId") String interfaceId,
121       @ApiParam(value = "Comma seperated value of Operation Ids") @PathParam("operationIds") String operationIds,
122       @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
123       @Context final HttpServletRequest request) {
124     return delete(interfaceId, operationIds, resourceId, request, userId);
125   }
126
127   @GET
128   @Consumes(MediaType.APPLICATION_JSON)
129   @Produces(MediaType.APPLICATION_JSON)
130   @Path("/resources/{resourceId}/interfaces/{interfaceId}/operations/{operationIds}")
131   @ApiOperation(value = "Get Interface Operations from Resource", httpMethod = "GET", notes = "GET Interface Operations from Resource", response = Response.class)
132   @ApiResponses(value = {
133       @ApiResponse(code = 201, message = "Delete Interface Operations from Resource"),
134       @ApiResponse(code = 400, message = "Invalid content / Missing content"),
135       @ApiResponse(code = 403, message = "Restricted operation"),
136       @ApiResponse(code = 404, message = "Resource not found")})
137   public Response getInterfaceOperationsFromResource(
138       @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId,
139       @ApiParam(value = "Interface Id") @PathParam("interfaceId") String interfaceId,
140       @ApiParam(value = "Comma seperated value of operationIds") @PathParam("operationIds") String operationIds,
141       @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
142       @Context final HttpServletRequest request) {
143     return get(interfaceId, operationIds, resourceId, request, userId);
144   }
145
146   @POST
147   @Consumes(MediaType.APPLICATION_JSON)
148   @Produces(MediaType.APPLICATION_JSON)
149   @Path("/services/{serviceId}/interfaceOperations")
150   @ApiOperation(value = "Create Interface Operations on Service", httpMethod = "POST", notes = "Create Interface Operations on Service", response = Response.class)
151   @ApiResponses(value = {
152       @ApiResponse(code = 201, message = "Create Interface Operations on Service"),
153       @ApiResponse(code = 400, message = "Invalid content / Missing content"),
154       @ApiResponse(code = 403, message = "Restricted operation"),
155       @ApiResponse(code = 404, message = "Service not found"),
156       @ApiResponse(code = 409, message = "Interface Operation already exist")})
157   public Response createInterfaceOperationsOnService(
158       @ApiParam(value = "Interface Operations to create", required = true) String data,
159       @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
160       @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
161       @Context final HttpServletRequest request) {
162     return createOrUpdate(data, ComponentTypeEnum.SERVICE, serviceId, request, userId, false);
163   }
164
165   @PUT
166   @Consumes(MediaType.APPLICATION_JSON)
167   @Produces(MediaType.APPLICATION_JSON)
168   @Path("/services/{serviceId}/interfaceOperations")
169   @ApiOperation(value = "Update Interface Operations on Service", httpMethod = "PUT", notes = "Update Interface Operations on Service", response = Response.class)
170   @ApiResponses(value = {
171       @ApiResponse(code = 201, message = "Update Interface Operations on Service"),
172       @ApiResponse(code = 400, message = "Invalid content / Missing content"),
173       @ApiResponse(code = 403, message = "Restricted operation"),
174       @ApiResponse(code = 404, message = "Service not found")})
175   public Response updateInterfaceOperationsOnService(
176       @ApiParam(value = "Interface Operations to update", required = true) String data,
177       @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
178       @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
179       @Context final HttpServletRequest request) {
180     return createOrUpdate(data, ComponentTypeEnum.SERVICE, serviceId, request, userId, true);
181   }
182
183   @DELETE
184   @Consumes(MediaType.APPLICATION_JSON)
185   @Produces(MediaType.APPLICATION_JSON)
186   @Path("/services/{serviceId}/interfaces/{interfaceId}/operations/{operationIds}")
187   @ApiOperation(value = "Delete Interface Operations from Service", httpMethod = "DELETE", notes = "Delete Interface Operations from Service", response = Response.class)
188   @ApiResponses(value = {
189       @ApiResponse(code = 201, message = "Delete Interface Operations from Service"),
190       @ApiResponse(code = 400, message = "Invalid content / Missing content"),
191       @ApiResponse(code = 403, message = "Restricted operation"),
192       @ApiResponse(code = 404, message = "Service not found")})
193   public Response deleteInterfaceOperationsFromService(
194       @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
195       @ApiParam(value = "Interface Id") @PathParam("interfaceId") String interfaceId,
196       @ApiParam(value = "Comma seperated value of Operation Ids") @PathParam("operationIds") String operationIds,
197       @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
198       @Context final HttpServletRequest request) {
199     return delete(interfaceId, operationIds, serviceId, request, userId);
200   }
201
202   @GET
203   @Consumes(MediaType.APPLICATION_JSON)
204   @Produces(MediaType.APPLICATION_JSON)
205   @Path("/services/{serviceId}/interfaces/{interfaceId}/operations/{operationIds}")
206   @ApiOperation(value = "Get Interface Operations from Service", httpMethod = "GET", notes = "GET Interface Operations from Service", response = Response.class)
207   @ApiResponses(value = {
208       @ApiResponse(code = 201, message = "Get Interface Operations from Service"),
209       @ApiResponse(code = 400, message = "Invalid content / Missing content"),
210       @ApiResponse(code = 403, message = "Restricted operation"),
211       @ApiResponse(code = 404, message = "Service not found")})
212   public Response getInterfaceOperationsFromService(
213       @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
214       @ApiParam(value = "Interface Id") @PathParam("interfaceId") String interfaceId,
215       @ApiParam(value = "Comma seperated value of operationIds") @PathParam("operationIds") String operationIds,
216       @HeaderParam(value = Constants.USER_ID_HEADER) String userId,
217       @Context final HttpServletRequest request) {
218     return get(interfaceId, operationIds, serviceId, request, userId);
219   }
220
221   private Response get (String interfaceId, String operationIds,  String componentId, HttpServletRequest request, String userId){
222     ServletContext context = request.getSession().getServletContext();
223     String url = request.getMethod() + " " + request.getRequestURI();
224
225     User modifier = new User();
226     modifier.setUserId(userId);
227     log.debug("Start get request of {} with modifier id {}", url, userId);
228
229     try {
230       String componentIdLower = componentId.toLowerCase();
231       InterfaceOperationBusinessLogic businessLogic = getInterfaceOperationBL(context);
232
233       List<String> operationsToGet = Stream.of(operationIds.split(",")).map(String::trim).collect(Collectors.toList());
234       Either<List<InterfaceDefinition>, ResponseFormat> actionResponse = businessLogic.getInterfaceOperation(componentIdLower, interfaceId, operationsToGet, modifier, true);
235       if (actionResponse.isRight()) {
236         log.error("failed to get interface operation");
237         return buildErrorResponse(actionResponse.right().value());
238       }
239
240       return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), getFormattedResponse(actionResponse.left().value()));
241     }
242     catch (Exception e) {
243       BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Component interface operations");
244       log.error("get component interface operations failed with exception", e);
245       return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
246     }
247   }
248
249   private Response delete (String interfaceId, String operationIds, String componentId, HttpServletRequest request, String userId){
250
251     ServletContext context = request.getSession().getServletContext();
252     String url = request.getMethod() + " " + request.getRequestURI();
253
254     User modifier = new User();
255     modifier.setUserId(userId);
256     log.debug("Start delete request of {} with modifier id {}", url, userId);
257
258     try {
259       String componentIdLower = componentId.toLowerCase();
260       InterfaceOperationBusinessLogic businessLogic = getInterfaceOperationBL(context);
261
262       List<String> operationsToDelete = Stream.of(operationIds.split(",")).map(String::trim).collect(Collectors.toList());
263       Either<List<InterfaceDefinition>, ResponseFormat> actionResponse = businessLogic.deleteInterfaceOperation(componentIdLower, interfaceId, operationsToDelete, modifier, true);
264       if (actionResponse.isRight()) {
265         log.error("failed to delete interface operation");
266         return buildErrorResponse(actionResponse.right().value());
267       }
268
269       return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), getFormattedResponse(actionResponse.left().value()));
270     }
271     catch (Exception e) {
272       BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Interface Operation");
273       log.error("Delete interface operation with an error", e);
274       return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
275     }
276   }
277
278   private Response createOrUpdate (String data, ComponentTypeEnum componentType, String componentId, HttpServletRequest request, String userId, boolean isUpdate) {
279     ServletContext context = request.getSession().getServletContext();
280     String url = request.getMethod() + " " + request.getRequestURI();
281
282     User modifier = new User();
283     modifier.setUserId(userId);
284     log.debug("Start create or update request of {} with modifier id {}", url, userId);
285
286     try {
287       String componentIdLower = componentId.toLowerCase();
288       InterfaceOperationBusinessLogic businessLogic = getInterfaceOperationBL(context);
289
290       List<InterfaceDefinition> mappedInterfaceData = getMappedInterfaceData(data, modifier, componentType);
291       Either<List<InterfaceDefinition>, ResponseFormat> actionResponse ;
292       if (isUpdate) {
293         actionResponse = businessLogic.updateInterfaceOperation(componentIdLower, mappedInterfaceData, modifier, true);
294       } else {
295         actionResponse = businessLogic.createInterfaceOperation(componentIdLower, mappedInterfaceData, modifier, true);
296       }
297
298       if (actionResponse.isRight()) {
299         log.error("failed to update or create interface operation");
300         return buildErrorResponse(actionResponse.right().value());
301       }
302
303       return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), getFormattedResponse(actionResponse.left().value()));
304     }
305     catch (Exception e) {
306       BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Interface Operation Creation or update");
307       log.error("create or update interface Operation with an error", e);
308       return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
309     }
310   }
311
312   private List<InterfaceDefinition> getMappedInterfaceData(String inputJson, User user, ComponentTypeEnum componentTypeEnum){
313     Either<UiComponentDataTransfer, ResponseFormat> uiComponentEither = getComponentsUtils()
314             .convertJsonToObjectUsingObjectMapper(inputJson, user, UiComponentDataTransfer.class, AuditingActionEnum.CREATE_RESOURCE,
315                     componentTypeEnum);
316     return uiComponentEither.left().value().getInterfaces().values().stream().collect(Collectors.toList());
317   }
318
319   private Object getFormattedResponse(List<InterfaceDefinition> interfaceDefinitions) throws IOException {
320     Map<String, List<InterfaceDefinition>> allInterfaces = ImmutableMap.of(JsonPresentationFields.INTERFACES.getPresentation(), interfaceDefinitions);
321     return RepresentationUtils.toFilteredRepresentation(allInterfaces);
322   }
323
324 }
325