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