68d8380ed276b83bfb1b40db36ab66ee025ca09b
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / ComponentNodeFilterServlet.java
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2020 Nordix Foundation
4  *  ================================================================================
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
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  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19
20 package org.openecomp.sdc.be.servlets;
21
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 java.util.Optional;
29 import javax.inject.Inject;
30 import javax.inject.Singleton;
31 import javax.servlet.http.HttpServletRequest;
32 import javax.ws.rs.Consumes;
33 import javax.ws.rs.DELETE;
34 import javax.ws.rs.HeaderParam;
35 import javax.ws.rs.POST;
36 import javax.ws.rs.PUT;
37 import javax.ws.rs.Path;
38 import javax.ws.rs.PathParam;
39 import javax.ws.rs.Produces;
40 import javax.ws.rs.core.Context;
41 import javax.ws.rs.core.MediaType;
42 import javax.ws.rs.core.Response;
43 import org.apache.commons.lang.StringUtils;
44 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
45 import org.openecomp.sdc.be.components.impl.ComponentNodeFilterBusinessLogic;
46 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
47 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
48 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
49 import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
50 import org.openecomp.sdc.be.config.BeEcompErrorManager;
51 import org.openecomp.sdc.be.dao.api.ActionStatus;
52 import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor;
53 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
54 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
55 import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType;
56 import org.openecomp.sdc.be.impl.ComponentsUtils;
57 import org.openecomp.sdc.be.impl.ServletUtils;
58 import org.openecomp.sdc.be.model.User;
59 import org.openecomp.sdc.be.tosca.utils.NodeFilterConverter;
60 import org.openecomp.sdc.be.ui.model.UIConstraint;
61 import org.openecomp.sdc.be.user.UserBusinessLogic;
62 import org.openecomp.sdc.common.api.Constants;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
65
66 @Path("/v1/catalog/{componentType}/{componentId}/componentInstance/{componentInstanceId}/{constraintType}")
67 @Consumes(MediaType.APPLICATION_JSON)
68 @Produces(MediaType.APPLICATION_JSON)
69 @Singleton
70 public class ComponentNodeFilterServlet extends AbstractValidationsServlet {
71
72     private static final Logger LOGGER = LoggerFactory.getLogger(ComponentNodeFilterServlet.class);
73     private static final String START_HANDLE_REQUEST_OF = "Start handle {} request of {}";
74     private static final String MODIFIER_ID_IS = "modifier id is {}";
75
76     private static final String FAILED_TO_PARSE_COMPONENT = "failed to parse component";
77
78     private static final String FAILED_TO_CREATE_NODE_FILTER = "failed to create node filter";
79     private static final String NODE_FILTER_CREATION = "Node Filter Creation";
80     private static final String CREATE_NODE_FILTER_WITH_AN_ERROR = "create node filter with an error";
81
82     private static final String FAILED_TO_UPDATE_NODE_FILTER = "failed to update node filter";
83     private static final String NODE_FILTER_UPDATE = "Node Filter Update";
84     private static final String UPDATE_NODE_FILTER_WITH_AN_ERROR = "update node filter with an error";
85
86     private static final String FAILED_TO_DELETE_NODE_FILTER = "failed to delete node filter";
87     private static final String NODE_FILTER_DELETE = "Node Filter Delete";
88     private static final String DELETE_NODE_FILTER_WITH_AN_ERROR = "delete node filter with an error";
89
90     private static  final String INVALID_NODE_FILTER_CONSTRAINT_TYPE = "Invalid value for NodeFilterConstraintType enum {}";
91
92     private final ComponentNodeFilterBusinessLogic componentNodeFilterBusinessLogic;
93
94     @Inject
95     public ComponentNodeFilterServlet(final UserBusinessLogic userBusinessLogic,
96                                       final ComponentInstanceBusinessLogic componentInstanceBL,
97                                       final ComponentsUtils componentsUtils,
98                                       final ServletUtils servletUtils,
99                                       final ResourceImportManager resourceImportManager,
100                                       final ComponentNodeFilterBusinessLogic componentNodeFilterBusinessLogic) {
101         super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
102         this.componentNodeFilterBusinessLogic = componentNodeFilterBusinessLogic;
103     }
104
105     @POST
106     @Consumes(MediaType.APPLICATION_JSON)
107     @Produces(MediaType.APPLICATION_JSON)
108     @Path("/nodeFilter")
109     @Operation(description = "Add Component Filter Constraint", method = "POST",
110         summary = "Add Component Filter Constraint", responses = {
111         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
112         @ApiResponse(responseCode = "201", description = "Create Component Filter"),
113         @ApiResponse(responseCode = "403", description = "Restricted operation"),
114         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
115     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
116     public Response addComponentFilterConstraint(
117         @Parameter(description = "UIConstraint data", required = true) String constraintData,
118         @Parameter(description = "Component Id") @PathParam("componentId") String componentId,
119         @Parameter(description = "Component Instance Id") @PathParam("componentInstanceId") String componentInstanceId,
120         @Parameter(description = "valid values: resources / services",
121             schema = @Schema(allowableValues = {
122                 ComponentTypeEnum.RESOURCE_PARAM_NAME,
123                 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") final String componentType,
124         @Parameter(description = "Constraint type. Valid values: properties / capabilities",
125             schema = @Schema(allowableValues = {NodeFilterConstraintType.PROPERTIES_PARAM_NAME,
126                 NodeFilterConstraintType.CAPABILITIES_PARAM_NAME}))
127         @PathParam("constraintType") final String constraintType,
128         @Context final HttpServletRequest request,
129         @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
130
131         LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI());
132         LOGGER.debug(MODIFIER_ID_IS, userId);
133         final User userModifier = componentNodeFilterBusinessLogic.validateUser(userId);
134
135         final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
136         try {
137             final Optional<UIConstraint> convertResponse = componentsUtils
138                 .parseToConstraint(constraintData, userModifier, componentTypeEnum);
139             if (convertResponse.isEmpty()) {
140                 LOGGER.error(FAILED_TO_PARSE_COMPONENT);
141                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
142             }
143             final Optional<NodeFilterConstraintType> nodeFilterConstraintType =
144                 NodeFilterConstraintType.parse(constraintType);
145             if (nodeFilterConstraintType.isEmpty()) {
146                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM,
147                     INVALID_NODE_FILTER_CONSTRAINT_TYPE, constraintType));
148             }
149             final UIConstraint uiConstraint = convertResponse.get();
150             final String constraint = new ConstraintConvertor().convert(uiConstraint);
151             final Optional<CINodeFilterDataDefinition> actionResponse = componentNodeFilterBusinessLogic
152                 .addNodeFilter(componentId.toLowerCase(), componentInstanceId, NodeFilterConstraintAction.ADD,
153                     uiConstraint.getServicePropertyName(), constraint, true, componentTypeEnum,
154                     nodeFilterConstraintType.get(),
155                     StringUtils.isEmpty(uiConstraint.getCapabilityName()) ? "" : uiConstraint.getCapabilityName());
156
157             if (actionResponse.isEmpty()) {
158                 LOGGER.error(FAILED_TO_CREATE_NODE_FILTER);
159                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
160             }
161
162             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
163                 new NodeFilterConverter().convertToUi(actionResponse.get()));
164
165         } catch (final Exception e) {
166             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION);
167             LOGGER.error(CREATE_NODE_FILTER_WITH_AN_ERROR, e);
168             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
169         }
170     }
171
172     @PUT
173     @Consumes(MediaType.APPLICATION_JSON)
174     @Produces(MediaType.APPLICATION_JSON)
175     @Path("/{constraintIndex}/nodeFilter")
176     @Operation(description = "Update Component Filter Constraint", method = "PUT",
177         summary = "Update Component Filter Constraint", responses = {
178         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
179         @ApiResponse(responseCode = "201", description = "Create Component Filter"),
180         @ApiResponse(responseCode = "403", description = "Restricted operation"),
181         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
182     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
183     public Response updateComponentFilterConstraint(
184         @Parameter(description = "UIConstraint data", required = true) String constraintData,
185         @Parameter(description = "Component Id") @PathParam("componentId") String componentId,
186         @Parameter(description = "Component Instance Id") @PathParam("componentInstanceId") String componentInstanceId,
187         @Parameter(description = "valid values: resources / services",
188             schema = @Schema(allowableValues = {
189                 ComponentTypeEnum.RESOURCE_PARAM_NAME,
190                 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") final String componentType,
191         @Parameter(description = "Constraint type. Valid values: properties / capabilities",
192             schema = @Schema(allowableValues = {NodeFilterConstraintType.PROPERTIES_PARAM_NAME,
193                 NodeFilterConstraintType.CAPABILITIES_PARAM_NAME}))
194         @PathParam("constraintType") final String constraintType,
195         @Parameter(description = "Constraint Index") @PathParam("constraintIndex") int index,
196         @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
197
198         LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI());
199         LOGGER.debug(MODIFIER_ID_IS, userId);
200         final User userModifier = componentNodeFilterBusinessLogic.validateUser(userId);
201
202         try {
203             final Optional<NodeFilterConstraintType> nodeFilterConstraintTypeOptional =
204                 NodeFilterConstraintType.parse(constraintType);
205             if (nodeFilterConstraintTypeOptional.isEmpty()) {
206                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM,
207                     INVALID_NODE_FILTER_CONSTRAINT_TYPE, constraintType));
208             }
209
210             final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
211             final Optional<UIConstraint> convertResponse = componentsUtils
212                 .parseToConstraint(constraintData, userModifier, componentTypeEnum);
213             if (convertResponse.isEmpty()) {
214                 LOGGER.error(FAILED_TO_PARSE_COMPONENT);
215                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
216             }
217             final NodeFilterConstraintType nodeFilterConstraintType = nodeFilterConstraintTypeOptional.get();
218             final Optional<CINodeFilterDataDefinition> actionResponse = componentNodeFilterBusinessLogic
219                 .updateNodeFilter(componentId.toLowerCase(), componentInstanceId, convertResponse.get(),
220                     componentTypeEnum, nodeFilterConstraintType, index);
221
222             if (actionResponse.isEmpty()) {
223                 LOGGER.error(FAILED_TO_UPDATE_NODE_FILTER);
224                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
225             }
226
227             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
228                 new NodeFilterConverter().convertToUi(actionResponse.get()));
229
230         } catch (final Exception e) {
231             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_UPDATE);
232             LOGGER.error(UPDATE_NODE_FILTER_WITH_AN_ERROR, e);
233             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
234         }
235     }
236
237     @DELETE
238     @Consumes(MediaType.APPLICATION_JSON)
239     @Produces(MediaType.APPLICATION_JSON)
240     @Path("{constraintIndex}/nodeFilter")
241     @Operation(description = "Delete Component Filter Constraint", method = "Delete",
242         summary = "Delete Component Filter Constraint", responses = {
243         @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))),
244         @ApiResponse(responseCode = "201", description = "Delete Component Filter Constraint"),
245         @ApiResponse(responseCode = "403", description = "Restricted operation"),
246         @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
247     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
248     public Response deleteComponentFilterConstraint(
249         @Parameter(description = "Component Id") @PathParam("componentId") String componentId,
250         @Parameter(description = "Component Instance Id") @PathParam("componentInstanceId") String componentInstanceId,
251         @Parameter(description = "Constraint Index") @PathParam("constraintIndex") int index,
252         @Parameter(description = "valid values: resources / services",
253             schema = @Schema(allowableValues = {
254                 ComponentTypeEnum.RESOURCE_PARAM_NAME,
255                 ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") final String componentType,
256         @Parameter(description = "Constraint type. Valid values: properties / capabilities",
257             schema = @Schema(allowableValues = {NodeFilterConstraintType.PROPERTIES_PARAM_NAME,
258                 NodeFilterConstraintType.CAPABILITIES_PARAM_NAME}))
259         @PathParam("constraintType") final String constraintType,
260         @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
261
262         LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI());
263         LOGGER.debug(MODIFIER_ID_IS, userId);
264         componentNodeFilterBusinessLogic.validateUser(userId);
265
266         try {
267             final Optional<NodeFilterConstraintType> nodeFilterConstraintType =
268                 NodeFilterConstraintType.parse(constraintType);
269             if (nodeFilterConstraintType.isEmpty()) {
270                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM,
271                     INVALID_NODE_FILTER_CONSTRAINT_TYPE, constraintType));
272             }
273             final Optional<CINodeFilterDataDefinition> actionResponse = componentNodeFilterBusinessLogic
274                 .deleteNodeFilter(componentId.toLowerCase(), componentInstanceId, NodeFilterConstraintAction.DELETE,
275                     null, index, true, ComponentTypeEnum.findByParamName(componentType),
276                     nodeFilterConstraintType.get());
277
278             if (actionResponse.isEmpty()) {
279                 LOGGER.debug(FAILED_TO_DELETE_NODE_FILTER);
280                 return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
281             }
282
283             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
284                 new NodeFilterConverter().convertToUi(actionResponse.get()));
285
286         } catch (final Exception e) {
287             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_DELETE);
288             LOGGER.debug(DELETE_NODE_FILTER_WITH_AN_ERROR, e);
289             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
290         }
291     }
292
293 }