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