Remove legacy certificate handling
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / ComponentInterfaceOperationServlet.java
1 /*
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  *  Copyright (C) 2021 Nordix Foundation. All rights reserved.
6  *  ================================================================================
7  *  Licensed under the Apache License, Version 2.0 (the "License");
8  *  you may not use this file except in compliance with the License.
9  *  You may obtain a copy of the License at
10  *
11  *        http://www.apache.org/licenses/LICENSE-2.0
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  *  SPDX-License-Identifier: Apache-2.0
19  *  ============LICENSE_END=========================================================
20  */
21
22 package org.openecomp.sdc.be.servlets;
23
24 import static org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum.RESOURCE;
25
26 import fj.data.Either;
27 import io.swagger.v3.oas.annotations.Operation;
28 import io.swagger.v3.oas.annotations.Parameter;
29 import io.swagger.v3.oas.annotations.media.ArraySchema;
30 import io.swagger.v3.oas.annotations.media.Content;
31 import io.swagger.v3.oas.annotations.media.Schema;
32 import io.swagger.v3.oas.annotations.responses.ApiResponse;
33 import io.swagger.v3.oas.annotations.servers.Server;
34 import io.swagger.v3.oas.annotations.tags.Tag;
35 import java.io.IOException;
36 import java.util.Optional;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.ws.rs.Consumes;
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.apache.commons.io.IOUtils;
49 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
50 import org.openecomp.sdc.be.components.impl.ComponentInterfaceOperationBusinessLogic;
51 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
52 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
53 import org.openecomp.sdc.be.config.BeEcompErrorManager;
54 import org.openecomp.sdc.be.dao.api.ActionStatus;
55 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
56 import org.openecomp.sdc.be.impl.ComponentsUtils;
57 import org.openecomp.sdc.be.impl.ServletUtils;
58 import org.openecomp.sdc.be.model.Component;
59 import org.openecomp.sdc.be.model.ComponentInstance;
60 import org.openecomp.sdc.be.model.InterfaceDefinition;
61 import org.openecomp.sdc.be.model.User;
62 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
63 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
64 import org.openecomp.sdc.common.api.Constants;
65 import org.openecomp.sdc.common.datastructure.Wrapper;
66 import org.openecomp.sdc.common.util.ValidationUtils;
67 import org.openecomp.sdc.exception.ResponseFormat;
68 import org.slf4j.Logger;
69 import org.slf4j.LoggerFactory;
70 import org.springframework.beans.factory.annotation.Autowired;
71 import org.springframework.stereotype.Controller;
72
73 @Path("/v1/catalog")
74 @Tag(name = "SDCE-2 APIs")
75 @Consumes(MediaType.APPLICATION_JSON)
76 @Produces(MediaType.APPLICATION_JSON)
77 @Server(url = "/sdc2/rest")
78 @Controller
79 public class ComponentInterfaceOperationServlet extends AbstractValidationsServlet {
80
81     private static final Logger LOGGER = LoggerFactory.getLogger(ComponentInterfaceOperationServlet.class);
82     private static final String START_HANDLE_REQUEST_OF = "Start handle {} request of {}";
83     private static final String MODIFIER_ID_IS = "modifier id is {}";
84     private static final String FAILED_TO_UPDATE_INTERFACE_OPERATION = "failed to update Interface Operation on component instance {}";
85     private static final String UPDATE_INTERFACE_OPERATION = "Update Interface Operation on Component Instance";
86     private static final String FAILED_TO_UPDATE_INTERFACE_OPERATION_WITH_ERROR = "Failed to update Interface Operation with an error";
87     private static final String INTERFACE_OPERATION_CONTENT_INVALID = "Interface Operation content is invalid - {}";
88     private static final String UNSUPPORTED_COMPONENT_TYPE = "Unsupported component type {}";
89     private static final String INTERFACE_OPERATION_SUCCESSFULLY_UPDATED =
90         "Interface Operation successfully updated on component instance with id {}";
91     private final ComponentInterfaceOperationBusinessLogic componentInterfaceOperationBusinessLogic;
92
93     @Autowired
94     public ComponentInterfaceOperationServlet(final ComponentInstanceBusinessLogic componentInstanceBL,
95                                               final ComponentsUtils componentsUtils, final ServletUtils servletUtils,
96                                               final ResourceImportManager resourceImportManager,
97                                               final ComponentInterfaceOperationBusinessLogic componentInterfaceOperationBusinessLogic) {
98         super(componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
99         this.componentInterfaceOperationBusinessLogic = componentInterfaceOperationBusinessLogic;
100     }
101
102     @PUT
103     @Path("/{componentType}/{componentId}/componentInstance/{componentInstanceId}/interfaceOperation")
104     @Consumes(MediaType.APPLICATION_JSON)
105     @Produces(MediaType.APPLICATION_JSON)
106     @Operation(description = "Update Interface Operation", method = "PUT", summary = "Update Interface Operation on ComponentInstance", responses = {
107         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
108         @ApiResponse(responseCode = "201", description = "Update Interface Operation"),
109         @ApiResponse(responseCode = "403", description = "Restricted operation"),
110         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
111     public Response updateComponentInstanceInterfaceOperation(
112         @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
113             ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") String componentType,
114         @Parameter(description = "Component Id") @PathParam("componentId") String componentId,
115         @Parameter(description = "Component Instance Id") @PathParam("componentInstanceId") String componentInstanceId,
116         @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
117         LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI());
118         userId = ValidationUtils.sanitizeInputString(userId);
119         componentType = ValidationUtils.sanitizeInputString(componentType);
120         componentInstanceId = ValidationUtils.sanitizeInputString(componentInstanceId);
121         LOGGER.debug(MODIFIER_ID_IS, userId);
122         final User userModifier = componentInterfaceOperationBusinessLogic.validateUser(userId);
123         final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
124         if (componentTypeEnum == null) {
125             LOGGER.debug(UNSUPPORTED_COMPONENT_TYPE, componentType);
126             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, componentType));
127         }
128         final byte[] bytes = IOUtils.toByteArray(request.getInputStream());
129         if (bytes == null || bytes.length == 0) {
130             LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID, "content is empty");
131             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
132         }
133         final String data = new String(bytes);
134         final Optional<InterfaceDefinition> mappedInterfaceOperationData = getMappedInterfaceData(data, userModifier, componentTypeEnum);
135         if (mappedInterfaceOperationData.isEmpty()) {
136             LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID, data);
137             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
138         }
139         final Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
140         try {
141             final Optional<ComponentInstance> actionResponse = componentInterfaceOperationBusinessLogic.updateComponentInstanceInterfaceOperation(
142                 componentId, componentInstanceId, mappedInterfaceOperationData.get(), componentTypeEnum, errorWrapper, true);
143             if (actionResponse.isEmpty()) {
144                 LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION, componentInstanceId);
145                 return buildErrorResponse(errorWrapper.getInnerElement());
146             } else {
147                 LOGGER.debug(INTERFACE_OPERATION_SUCCESSFULLY_UPDATED, componentInstanceId);
148                 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.get());
149             }
150         } catch (final Exception e) {
151             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_INTERFACE_OPERATION);
152             LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION_WITH_ERROR, e);
153             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
154         }
155     }
156
157     @PUT
158     @Path("/resources/{componentId}/interfaceOperation")
159     @Consumes(MediaType.APPLICATION_JSON)
160     @Produces(MediaType.APPLICATION_JSON)
161     @Operation(description = "Update Interface Operation", method = "PUT", summary = "Update Interface Operation on ComponentInstance", responses = {
162         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
163         @ApiResponse(responseCode = "201", description = "Update Interface Operation"),
164         @ApiResponse(responseCode = "403", description = "Restricted operation"),
165         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
166     public Response updateResourceInterfaceOperation(
167         @Parameter(description = "Component Id") @PathParam("componentId") String componentId,
168         @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
169         LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI());
170         LOGGER.debug(MODIFIER_ID_IS, userId);
171         final User userModifier = componentInterfaceOperationBusinessLogic.validateUser(userId);
172         final byte[] bytes = IOUtils.toByteArray(request.getInputStream());
173         if (bytes == null || bytes.length == 0) {
174             LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID);
175             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
176         }
177         final ComponentTypeEnum componentType = RESOURCE;
178         final String data = new String(bytes);
179         final Optional<InterfaceDefinition> mappedInterfaceOperationData = getMappedInterfaceData(data, userModifier, componentType);
180         if (mappedInterfaceOperationData.isEmpty()) {
181             LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID, data);
182             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
183         }
184         final Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
185         try {
186             final Optional<Component> actionResponse = componentInterfaceOperationBusinessLogic
187                 .updateResourceInterfaceOperation(componentId, userId, mappedInterfaceOperationData.get(), componentType,
188                     errorWrapper, true);
189             if (actionResponse.isEmpty()) {
190                 LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION, componentId);
191                 return buildErrorResponse(errorWrapper.getInnerElement());
192             } else {
193                 LOGGER.debug(INTERFACE_OPERATION_SUCCESSFULLY_UPDATED, componentId);
194                 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.get());
195             }
196         } catch (final ComponentException e) {
197             //let it be handled by org.openecomp.sdc.be.servlets.exception.ComponentExceptionMapper
198             throw e;
199         } catch (final Exception e) {
200             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_INTERFACE_OPERATION);
201             LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION_WITH_ERROR, e);
202             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
203         }
204     }
205
206     @POST
207     @Path("/{componentType}/{componentId}/componentInstance/{componentInstanceId}/interfaceOperation")
208     @Consumes(MediaType.APPLICATION_JSON)
209     @Produces(MediaType.APPLICATION_JSON)
210     @Operation(description = "Create Interface Operation", method = "POST", summary = "Create Interface Operation on ComponentInstance", responses = {
211         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
212         @ApiResponse(responseCode = "201", description = "Create Interface Operation"),
213         @ApiResponse(responseCode = "403", description = "Restricted operation"),
214         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
215     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
216     public Response createComponentInstanceInterfaceOperation(
217         @Parameter(description = "valid values: resources / services", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME,
218             ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") String componentType,
219         @Parameter(description = "Component Id") @PathParam("componentId") String componentId,
220         @Parameter(description = "Component Instance Id") @PathParam("componentInstanceId") String componentInstanceId,
221         @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
222         LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI());
223         userId = ValidationUtils.sanitizeInputString(userId);
224         componentType = ValidationUtils.sanitizeInputString(componentType);
225         componentInstanceId = ValidationUtils.sanitizeInputString(componentInstanceId);
226         LOGGER.debug(MODIFIER_ID_IS, userId);
227         final User userModifier = componentInterfaceOperationBusinessLogic.validateUser(userId);
228         final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
229         if (componentTypeEnum == null) {
230             LOGGER.debug(UNSUPPORTED_COMPONENT_TYPE, componentType);
231             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, componentType));
232         }
233         final byte[] bytes = IOUtils.toByteArray(request.getInputStream());
234         if (bytes == null || bytes.length == 0) {
235             LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID, "content is empty");
236             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
237         }
238         final String data = new String(bytes);
239         final Optional<InterfaceDefinition> mappedInterfaceOperationData = getMappedInterfaceData(data, userModifier, componentTypeEnum);
240         if (mappedInterfaceOperationData.isEmpty()) {
241             LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID, data);
242             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
243         }
244         final Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
245         try {
246             final Optional<ComponentInstance> actionResponse = componentInterfaceOperationBusinessLogic.createComponentInstanceInterfaceOperation(
247                 componentId, componentInstanceId, mappedInterfaceOperationData.get(), componentTypeEnum, errorWrapper, true);
248             if (actionResponse.isEmpty()) {
249                 LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION, componentInstanceId);
250                 return buildErrorResponse(errorWrapper.getInnerElement());
251             } else {
252                 LOGGER.debug(INTERFACE_OPERATION_SUCCESSFULLY_UPDATED, componentInstanceId);
253                 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.get());
254             }
255         } catch (final Exception e) {
256             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_INTERFACE_OPERATION);
257             LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION_WITH_ERROR, e);
258             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
259         }
260     }
261
262     @POST
263     @Path("/{componentType}/{componentId}/resource/interfaceOperation")
264     @Consumes(MediaType.APPLICATION_JSON)
265     @Produces(MediaType.APPLICATION_JSON)
266     @Operation(description = "Create Interface Operation", method = "POST", summary = "Create Interface Operation on ComponentInstance", responses = {
267         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
268         @ApiResponse(responseCode = "201", description = "Create Interface Operation"),
269         @ApiResponse(responseCode = "403", description = "Restricted operation"),
270         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
271     public Response createInterfaceOperationInResource(
272         @Parameter(description = "valid values: resources", schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME}))
273         @PathParam("componentType") final String componentType,
274         @Parameter(description = "Component Id") @PathParam("componentId") String componentId,
275         @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) throws IOException {
276         LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI());
277         LOGGER.debug(MODIFIER_ID_IS, userId);
278         final User userModifier = componentInterfaceOperationBusinessLogic.validateUser(userId);
279         final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
280         if (componentTypeEnum == null) {
281             LOGGER.debug(UNSUPPORTED_COMPONENT_TYPE, componentType);
282             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, componentType));
283         }
284         final byte[] bytes = IOUtils.toByteArray(request.getInputStream());
285         if (bytes == null || bytes.length == 0) {
286             LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID);
287             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
288         }
289         final String data = new String(bytes);
290         final Optional<InterfaceDefinition> mappedInterfaceOperationData = getMappedInterfaceData(data, userModifier, componentTypeEnum);
291         if (mappedInterfaceOperationData.isEmpty()) {
292             LOGGER.error(INTERFACE_OPERATION_CONTENT_INVALID, data);
293             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
294         }
295         final Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
296         try {
297             final Optional<Component> actionResponse = componentInterfaceOperationBusinessLogic.createInterfaceOperationInResource(
298                 componentId, mappedInterfaceOperationData.get(), componentTypeEnum, errorWrapper, true);
299             if (actionResponse.isEmpty()) {
300                 LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION, componentId);
301                 return buildErrorResponse(errorWrapper.getInnerElement());
302             } else {
303                 LOGGER.debug(INTERFACE_OPERATION_SUCCESSFULLY_UPDATED, componentId);
304                 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.get());
305             }
306         } catch (final Exception e) {
307             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(UPDATE_INTERFACE_OPERATION);
308             LOGGER.error(FAILED_TO_UPDATE_INTERFACE_OPERATION_WITH_ERROR, e);
309             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
310         }
311     }
312
313     private Optional<InterfaceDefinition> getMappedInterfaceData(final String inputJson, final User user, final ComponentTypeEnum componentTypeEnum) {
314         final Either<UiComponentDataTransfer, ResponseFormat> uiComponentEither = getComponentsUtils()
315             .convertJsonToObjectUsingObjectMapper(inputJson, user, UiComponentDataTransfer.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA,
316                 componentTypeEnum);
317         return uiComponentEither.left().value().getInterfaces().values().stream().findFirst();
318     }
319 }