catalog-be servlets refactoring
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / ServiceFilterServlet.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.openecomp.sdc.be.servlets;
22
23 import fj.data.Either;
24 import io.swagger.annotations.Api;
25 import io.swagger.annotations.ApiOperation;
26 import io.swagger.annotations.ApiParam;
27 import io.swagger.annotations.ApiResponse;
28 import io.swagger.annotations.ApiResponses;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.stream.Collectors;
32 import javax.inject.Inject;
33 import javax.inject.Singleton;
34 import javax.servlet.ServletContext;
35 import javax.servlet.http.HttpServletRequest;
36 import javax.servlet.http.HttpSession;
37 import javax.ws.rs.Consumes;
38 import javax.ws.rs.DELETE;
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.codehaus.jackson.map.ObjectMapper;
49 import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
50 import org.openecomp.sdc.be.components.impl.GroupBusinessLogic;
51 import org.openecomp.sdc.be.components.impl.ResourceImportManager;
52 import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
53 import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
54 import org.openecomp.sdc.be.config.BeEcompErrorManager;
55 import org.openecomp.sdc.be.dao.api.ActionStatus;
56 import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor;
57 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
58 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
59 import org.openecomp.sdc.be.impl.ComponentsUtils;
60 import org.openecomp.sdc.be.impl.ServletUtils;
61 import org.openecomp.sdc.be.model.User;
62 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
63 import org.openecomp.sdc.be.tosca.utils.NodeFilterConverter;
64 import org.openecomp.sdc.be.ui.model.UIConstraint;
65 import org.openecomp.sdc.be.ui.model.UINodeFilter;
66 import org.openecomp.sdc.be.user.UserBusinessLogic;
67 import org.openecomp.sdc.common.api.Constants;
68 import org.openecomp.sdc.exception.ResponseFormat;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
71
72 @Path("/v1/catalog/services/{serviceId}/resourceInstances/{resourceInstanceId}/nodeFilter")
73 @Consumes(MediaType.APPLICATION_JSON)
74 @Produces(MediaType.APPLICATION_JSON)
75 @Api(value = "Service Filter", description = "Service Filter Servlet")
76 @Singleton
77 public class ServiceFilterServlet extends AbstractValidationsServlet {
78
79     private static final Logger log = LoggerFactory.getLogger(ServiceFilterServlet.class);
80     private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}";
81     private static final String MODIFIER_ID_IS = "modifier id is {}";
82     private static final String FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER = "failed to update or create node filter";
83     private static final String FAILED_TO_PARSE_SERVICE = "failed to parse service";
84     private static final String NODE_FILTER_CREATION_OR_UPDATE = "Node Filter Creation or update";
85     private static final String CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR =
86             "create or update node filter with an error";
87     private final ServiceBusinessLogic serviceBusinessLogic;
88
89     @Inject
90     public ServiceFilterServlet(UserBusinessLogic userBusinessLogic,
91         ComponentInstanceBusinessLogic componentInstanceBL,
92         ComponentsUtils componentsUtils, ServletUtils servletUtils,
93         ResourceImportManager resourceImportManager,
94         ServiceBusinessLogic serviceBusinessLogic) {
95         super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
96         this.serviceBusinessLogic = serviceBusinessLogic;
97     }
98
99     @POST
100     @Consumes(MediaType.APPLICATION_JSON)
101     @Produces(MediaType.APPLICATION_JSON)
102     @Path("/")
103     @ApiOperation(value = "Add Service Filter Constraint", httpMethod = "POST", notes = "Add Service Filter Constraint",
104             response = Response.class)
105     @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Service Filter"),
106             @ApiResponse(code = 403, message = "Restricted operation"),
107             @ApiResponse(code = 400, message = "Invalid content / Missing content")})
108     public Response addServiceFilterConstraint(@ApiParam(value = "Service data", required = true) String data,
109             @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
110             @ApiParam(value = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId,
111             @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
112
113         String url = request.getMethod() + " " + request.getRequestURI();
114         log.debug(START_HANDLE_REQUEST_OF, url);
115         final HttpSession session = request.getSession();
116         ServletContext context = session.getServletContext();
117         User modifier = new User();
118         modifier.setUserId(userId);
119         log.debug(MODIFIER_ID_IS, userId);
120
121         Response response;
122
123         try {
124             String serviceIdLower = serviceId.toLowerCase();
125
126             Either<UIConstraint, ResponseFormat> convertResponse = parseToConstraint(data, modifier);
127             if (convertResponse.isRight()) {
128                 log.debug(FAILED_TO_PARSE_SERVICE);
129                 response = buildErrorResponse(convertResponse.right().value());
130                 return response;
131             }
132             UIConstraint uiConstraint = convertResponse.left().value();
133             if (uiConstraint == null) {
134                 log.debug(FAILED_TO_PARSE_SERVICE);
135                 response = buildErrorResponse(convertResponse.right().value());
136                 return response;
137             }
138             Either<CINodeFilterDataDefinition, ResponseFormat> actionResponse;
139             String constraint = new ConstraintConvertor().convert(uiConstraint);
140             actionResponse = serviceBusinessLogic
141                                      .addOrDeleteServiceFilter(serviceIdLower, ciId, NodeFilterConstraintAction.ADD, uiConstraint.getServicePropertyName(),
142                                              constraint, -1, modifier, true);
143
144             if (actionResponse.isRight()) {
145                 log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER);
146                 response = buildErrorResponse(actionResponse.right().value());
147                 return response;
148             }
149
150             CINodeFilterDataDefinition value = actionResponse.left().value();
151             UINodeFilter nodeFilter = new NodeFilterConverter().convertToUi(value);
152             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), nodeFilter);
153
154         } catch (Exception e) {
155             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE);
156             log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e);
157             response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
158             return response;
159
160         }
161     }
162
163     @PUT
164     @Consumes(MediaType.APPLICATION_JSON)
165     @Produces(MediaType.APPLICATION_JSON)
166     @Path("/")
167     @ApiOperation(value = "Update Service Filter Constraint", httpMethod = "PUT",
168             notes = "Update Service Filter Constraint", response = Response.class)
169     @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Service Filter"),
170             @ApiResponse(code = 403, message = "Restricted operation"),
171             @ApiResponse(code = 400, message = "Invalid content / Missing content")})
172     public Response updateServiceFilterConstraint(@ApiParam(value = "Service data", required = true) String data,
173             @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
174             @ApiParam(value = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId,
175             @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
176         ServletContext context = request.getSession().getServletContext();
177         String url = request.getMethod() + " " + request.getRequestURI();
178         log.debug(START_HANDLE_REQUEST_OF, url);
179
180         User modifier = new User();
181         modifier.setUserId(userId);
182         log.debug(MODIFIER_ID_IS, userId);
183
184         Response response;
185
186         try {
187             String serviceIdLower = serviceId.toLowerCase();
188
189             Either<List, ResponseFormat> convertResponse = parseToConstraints(data, modifier);
190             if (convertResponse.isRight()) {
191                 log.debug(FAILED_TO_PARSE_SERVICE);
192                 response = buildErrorResponse(convertResponse.right().value());
193                 return response;
194             }
195             List<Map<String,String>> uiConstraintsMaps = (List<Map<String,String>>) convertResponse.left().value();
196             if (uiConstraintsMaps == null) {
197                 log.debug("failed to parse data");
198                 response = buildErrorResponse(convertResponse.right().value());
199                 return response;
200             }
201             final ObjectMapper objectMapper = new ObjectMapper();
202             List<UIConstraint> uiConstraints = uiConstraintsMaps.stream().map(dataMap -> objectMapper.convertValue(dataMap, UIConstraint.class)).collect(
203                     Collectors.toList());
204             if (uiConstraints == null) {
205                 log.debug("failed to parse data");
206                 response = buildErrorResponse(convertResponse.right().value());
207                 return response;
208             }
209             Either<CINodeFilterDataDefinition, ResponseFormat> actionResponse;
210             List<String> constraints = new ConstraintConvertor().convertToList(uiConstraints);
211             actionResponse = serviceBusinessLogic.updateServiceFilter(serviceIdLower, ciId, constraints, modifier, true);
212
213             if (actionResponse.isRight()) {
214                 log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER);
215                 response = buildErrorResponse(actionResponse.right().value());
216                 return response;
217             }
218
219             CINodeFilterDataDefinition value = actionResponse.left().value();
220             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
221                     new NodeFilterConverter().convertToUi(value));
222
223         } catch (Exception e) {
224             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE);
225             log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e);
226             response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
227             return response;
228
229         }
230     }
231
232     @DELETE
233     @Consumes(MediaType.APPLICATION_JSON)
234     @Produces(MediaType.APPLICATION_JSON)
235     @Path("/{constraintIndex}")
236     @ApiOperation(value = "Delete Service Filter Constraint", httpMethod = "Delete",
237             notes = "Delete Service Filter Constraint", response = Response.class)
238     @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete Service Filter Constraint"),
239             @ApiResponse(code = 403, message = "Restricted operation"),
240             @ApiResponse(code = 400, message = "Invalid content / Missing content")})
241     public Response deleteServiceFilterConstraint(
242             @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
243             @ApiParam(value = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId,
244             @ApiParam(value = "Constraint Index") @PathParam("constraintIndex") int index,
245             @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
246         String url = request.getMethod() + " " + request.getRequestURI();
247         log.debug(START_HANDLE_REQUEST_OF, url);
248
249         User modifier = new User();
250         modifier.setUserId(userId);
251         log.debug(MODIFIER_ID_IS, userId);
252
253         Response response;
254
255         try {
256             String serviceIdLower = serviceId.toLowerCase();
257
258             Either<CINodeFilterDataDefinition, ResponseFormat> actionResponse;
259             actionResponse = serviceBusinessLogic
260                                      .addOrDeleteServiceFilter(serviceIdLower, ciId, NodeFilterConstraintAction.DELETE,
261                                              null, null,  index, modifier, true);
262
263             if (actionResponse.isRight()) {
264
265                 log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER);
266                 response = buildErrorResponse(actionResponse.right().value());
267                 return response;
268             }
269
270             final CINodeFilterDataDefinition value = actionResponse.left().value();
271             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
272                     new NodeFilterConverter().convertToUi(value));
273
274         } catch (Exception e) {
275             BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE);
276             log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e);
277             response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
278             return response;
279
280         }
281     }
282
283     private Either<UIConstraint, ResponseFormat> parseToConstraint(String serviceJson, User user) {
284         return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, UIConstraint.class,
285                 AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
286     }
287
288     private Either<List, ResponseFormat> parseToConstraints(String serviceJson, User user) {
289         return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, List.class,
290                 AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
291     }
292 }