2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. 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
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.be.servlets;
23 import fj.data.Either;
24 import io.swagger.v3.oas.annotations.OpenAPIDefinition;
25 import io.swagger.v3.oas.annotations.Operation;
26 import io.swagger.v3.oas.annotations.Parameter;
27 import io.swagger.v3.oas.annotations.info.Info;
28 import io.swagger.v3.oas.annotations.media.ArraySchema;
29 import io.swagger.v3.oas.annotations.media.Content;
30 import io.swagger.v3.oas.annotations.media.Schema;
31 import io.swagger.v3.oas.annotations.responses.ApiResponse;
32 import io.swagger.v3.oas.annotations.responses.ApiResponses;
33 import org.codehaus.jackson.map.ObjectMapper;
34 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
35 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
36 import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
37 import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
38 import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
39 import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
40 import org.openecomp.sdc.be.config.BeEcompErrorManager;
41 import org.openecomp.sdc.be.dao.api.ActionStatus;
42 import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor;
43 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
44 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
45 import org.openecomp.sdc.be.impl.ComponentsUtils;
46 import org.openecomp.sdc.be.impl.ServletUtils;
47 import org.openecomp.sdc.be.model.User;
48 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
49 import org.openecomp.sdc.be.tosca.utils.NodeFilterConverter;
50 import org.openecomp.sdc.be.ui.model.UIConstraint;
51 import org.openecomp.sdc.be.ui.model.UINodeFilter;
52 import org.openecomp.sdc.be.user.UserBusinessLogic;
53 import org.openecomp.sdc.common.api.Constants;
54 import org.openecomp.sdc.exception.ResponseFormat;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
58 import javax.inject.Inject;
59 import javax.inject.Singleton;
60 import javax.servlet.ServletContext;
61 import javax.servlet.http.HttpServletRequest;
62 import javax.servlet.http.HttpSession;
63 import javax.ws.rs.Consumes;
64 import javax.ws.rs.DELETE;
65 import javax.ws.rs.HeaderParam;
66 import javax.ws.rs.POST;
67 import javax.ws.rs.PUT;
68 import javax.ws.rs.Path;
69 import javax.ws.rs.PathParam;
70 import javax.ws.rs.Produces;
71 import javax.ws.rs.core.Context;
72 import javax.ws.rs.core.MediaType;
73 import javax.ws.rs.core.Response;
74 import java.util.List;
76 import java.util.stream.Collectors;
78 @Path("/v1/catalog/services/{serviceId}/resourceInstances/{resourceInstanceId}/nodeFilter")
79 @Consumes(MediaType.APPLICATION_JSON)
80 @Produces(MediaType.APPLICATION_JSON)
81 @OpenAPIDefinition(info = @Info(title = "Service Filter", description = "Service Filter Servlet"))
83 public class ServiceFilterServlet extends AbstractValidationsServlet {
85 private static final Logger log = LoggerFactory.getLogger(ServiceFilterServlet.class);
86 private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
87 private static final String MODIFIER_ID_IS = "modifier id is {}";
88 private static final String FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER = "failed to update or create node filter";
89 private static final String FAILED_TO_PARSE_SERVICE = "failed to parse service";
90 private static final String NODE_FILTER_CREATION_OR_UPDATE = "Node Filter Creation or update";
91 private static final String CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR =
92 "create or update node filter with an error";
93 private final ServiceBusinessLogic serviceBusinessLogic;
96 public ServiceFilterServlet(UserBusinessLogic userBusinessLogic,
97 ComponentInstanceBusinessLogic componentInstanceBL,
98 ComponentsUtils componentsUtils, ServletUtils servletUtils,
99 ResourceImportManager resourceImportManager,
100 ServiceBusinessLogic serviceBusinessLogic) {
101 super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
102 this.serviceBusinessLogic = serviceBusinessLogic;
106 @Consumes(MediaType.APPLICATION_JSON)
107 @Produces(MediaType.APPLICATION_JSON)
109 @Operation(description = "Add Service Filter Constraint", method = "POST", summary = "Add Service Filter Constraint",
110 responses = @ApiResponse(
111 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
112 @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Create Service 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 addServiceFilterConstraint(@Parameter(description = "Service data", required = true) String data,
117 @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId,
118 @Parameter(description = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId,
119 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
121 String url = request.getMethod() + " " + request.getRequestURI();
122 log.debug(START_HANDLE_REQUEST_OF, url);
123 final HttpSession session = request.getSession();
124 ServletContext context = session.getServletContext();
125 User modifier = new User();
126 modifier.setUserId(userId);
127 log.debug(MODIFIER_ID_IS, userId);
132 String serviceIdLower = serviceId.toLowerCase();
134 Either<UIConstraint, ResponseFormat> convertResponse = parseToConstraint(data, modifier);
135 if (convertResponse.isRight()) {
136 log.debug(FAILED_TO_PARSE_SERVICE);
137 response = buildErrorResponse(convertResponse.right().value());
140 UIConstraint uiConstraint = convertResponse.left().value();
141 if (uiConstraint == null) {
142 log.debug(FAILED_TO_PARSE_SERVICE);
143 response = buildErrorResponse(convertResponse.right().value());
146 Either<CINodeFilterDataDefinition, ResponseFormat> actionResponse;
147 String constraint = new ConstraintConvertor().convert(uiConstraint);
148 actionResponse = serviceBusinessLogic
149 .addOrDeleteServiceFilter(serviceIdLower, ciId, NodeFilterConstraintAction.ADD, uiConstraint.getServicePropertyName(),
150 constraint, -1, modifier, true);
152 if (actionResponse.isRight()) {
153 log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER);
154 response = buildErrorResponse(actionResponse.right().value());
158 CINodeFilterDataDefinition value = actionResponse.left().value();
159 UINodeFilter nodeFilter = new NodeFilterConverter().convertToUi(value);
160 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), nodeFilter);
162 } catch (Exception e) {
163 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE);
164 log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e);
165 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
172 @Consumes(MediaType.APPLICATION_JSON)
173 @Produces(MediaType.APPLICATION_JSON)
175 @Operation(description = "Update Service Filter Constraint", method = "PUT",
176 summary = "Update Service Filter Constraint", responses = @ApiResponse(
177 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
178 @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Create Service Filter"),
179 @ApiResponse(responseCode = "403", description = "Restricted operation"),
180 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
181 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
182 public Response updateServiceFilterConstraint(@Parameter(description = "Service data", required = true) String data,
183 @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId,
184 @Parameter(description = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId,
185 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
186 ServletContext context = request.getSession().getServletContext();
187 String url = request.getMethod() + " " + request.getRequestURI();
188 log.debug(START_HANDLE_REQUEST_OF, url);
190 User modifier = new User();
191 modifier.setUserId(userId);
192 log.debug(MODIFIER_ID_IS, userId);
197 String serviceIdLower = serviceId.toLowerCase();
199 Either<List, ResponseFormat> convertResponse = parseToConstraints(data, modifier);
200 if (convertResponse.isRight()) {
201 log.debug(FAILED_TO_PARSE_SERVICE);
202 response = buildErrorResponse(convertResponse.right().value());
205 List<Map<String,String>> uiConstraintsMaps = (List<Map<String,String>>) convertResponse.left().value();
206 if (uiConstraintsMaps == null) {
207 log.debug("failed to parse data");
208 response = buildErrorResponse(convertResponse.right().value());
211 final ObjectMapper objectMapper = new ObjectMapper();
212 List<UIConstraint> uiConstraints = uiConstraintsMaps.stream().map(dataMap -> objectMapper.convertValue(dataMap, UIConstraint.class)).collect(
213 Collectors.toList());
214 if (uiConstraints == null) {
215 log.debug("failed to parse data");
216 response = buildErrorResponse(convertResponse.right().value());
219 Either<CINodeFilterDataDefinition, ResponseFormat> actionResponse;
220 List<String> constraints = new ConstraintConvertor().convertToList(uiConstraints);
221 actionResponse = serviceBusinessLogic.updateServiceFilter(serviceIdLower, ciId, constraints, modifier, true);
223 if (actionResponse.isRight()) {
224 log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER);
225 response = buildErrorResponse(actionResponse.right().value());
229 CINodeFilterDataDefinition value = actionResponse.left().value();
230 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
231 new NodeFilterConverter().convertToUi(value));
233 } catch (Exception e) {
234 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE);
235 log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e);
236 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
243 @Consumes(MediaType.APPLICATION_JSON)
244 @Produces(MediaType.APPLICATION_JSON)
245 @Path("/{constraintIndex}")
246 @Operation(description = "Delete Service Filter Constraint", method = "Delete",
247 summary = "Delete Service Filter Constraint", responses = @ApiResponse(
248 content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))
249 @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Delete Service Filter Constraint"),
250 @ApiResponse(responseCode = "403", description = "Restricted operation"),
251 @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})
252 @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
253 public Response deleteServiceFilterConstraint(
254 @Parameter(description = "Service Id") @PathParam("serviceId") String serviceId,
255 @Parameter(description = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId,
256 @Parameter(description = "Constraint Index") @PathParam("constraintIndex") int index,
257 @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
258 String url = request.getMethod() + " " + request.getRequestURI();
259 log.debug(START_HANDLE_REQUEST_OF, url);
261 User modifier = new User();
262 modifier.setUserId(userId);
263 log.debug(MODIFIER_ID_IS, userId);
268 String serviceIdLower = serviceId.toLowerCase();
270 Either<CINodeFilterDataDefinition, ResponseFormat> actionResponse;
271 actionResponse = serviceBusinessLogic
272 .addOrDeleteServiceFilter(serviceIdLower, ciId, NodeFilterConstraintAction.DELETE,
273 null, null, index, modifier, true);
275 if (actionResponse.isRight()) {
277 log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER);
278 response = buildErrorResponse(actionResponse.right().value());
282 final CINodeFilterDataDefinition value = actionResponse.left().value();
283 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
284 new NodeFilterConverter().convertToUi(value));
286 } catch (Exception e) {
287 BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE);
288 log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e);
289 response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
295 private Either<UIConstraint, ResponseFormat> parseToConstraint(String serviceJson, User user) {
296 return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, UIConstraint.class,
297 AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
300 private Either<List, ResponseFormat> parseToConstraints(String serviceJson, User user) {
301 return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, List.class,
302 AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);