CSIT Fix for SDC-2585
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / ProductServlet.java
1 /*-\r
2  * ============LICENSE_START=======================================================\r
3  * SDC\r
4  * ================================================================================\r
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.\r
6  * ================================================================================\r
7  * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * you may not use this file except in compliance with the License.\r
9  * You may obtain a copy of the License at\r
10  * \r
11  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * \r
13  * Unless required by applicable law or agreed to in writing, software\r
14  * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * See the License for the specific language governing permissions and\r
17  * limitations under the License.\r
18  * ============LICENSE_END=========================================================\r
19  */\r
20 \r
21 package org.openecomp.sdc.be.servlets;\r
22 \r
23 import java.util.Map;\r
24 import javax.inject.Inject;\r
25 import javax.inject.Singleton;\r
26 import javax.servlet.http.HttpServletRequest;\r
27 import javax.ws.rs.Consumes;\r
28 import javax.ws.rs.DELETE;\r
29 import javax.ws.rs.GET;\r
30 import javax.ws.rs.HeaderParam;\r
31 import javax.ws.rs.POST;\r
32 import javax.ws.rs.PUT;\r
33 import javax.ws.rs.Path;\r
34 import javax.ws.rs.PathParam;\r
35 import javax.ws.rs.Produces;\r
36 import javax.ws.rs.core.Context;\r
37 import javax.ws.rs.core.MediaType;\r
38 import javax.ws.rs.core.Response;\r
39 import org.openecomp.sdc.be.components.impl.ProductBusinessLogic;\r
40 import org.openecomp.sdc.be.config.BeEcompErrorManager;\r
41 import org.openecomp.sdc.be.dao.api.ActionStatus;\r
42 import org.openecomp.sdc.be.impl.ComponentsUtils;\r
43 import org.openecomp.sdc.be.model.Product;\r
44 import org.openecomp.sdc.be.model.User;\r
45 import org.openecomp.sdc.be.user.UserBusinessLogic;\r
46 import org.openecomp.sdc.common.api.Constants;\r
47 import org.openecomp.sdc.common.log.wrappers.Logger;\r
48 import org.openecomp.sdc.exception.ResponseFormat;\r
49 import com.jcabi.aspects.Loggable;\r
50 import fj.data.Either;\r
51 import io.swagger.v3.oas.annotations.OpenAPIDefinition;\r
52 import io.swagger.v3.oas.annotations.Operation;\r
53 import io.swagger.v3.oas.annotations.Parameter;\r
54 import io.swagger.v3.oas.annotations.info.Info;\r
55 import io.swagger.v3.oas.annotations.media.ArraySchema;\r
56 import io.swagger.v3.oas.annotations.media.Content;\r
57 import io.swagger.v3.oas.annotations.media.Schema;\r
58 import io.swagger.v3.oas.annotations.responses.ApiResponse;\r
59 import io.swagger.v3.oas.annotations.responses.ApiResponses;\r
60 \r
61 @Loggable(prepend = true, value = Loggable.DEBUG, trim = false)\r
62 @Path("/v1/catalog")\r
63 @OpenAPIDefinition(info = @Info(title = "Product Catalog", description = "Product Catalog"))\r
64 @Singleton\r
65 public class ProductServlet extends BeGenericServlet {\r
66     private static final Logger log = Logger.getLogger(ProductServlet.class);\r
67     private final ProductBusinessLogic productBusinessLogic;\r
68 \r
69     @Inject\r
70     public ProductServlet(UserBusinessLogic userBusinessLogic,\r
71         ProductBusinessLogic productBusinessLogic,\r
72         ComponentsUtils componentsUtils) {\r
73         super(userBusinessLogic, componentsUtils);\r
74         this.productBusinessLogic = productBusinessLogic;\r
75     }\r
76 \r
77     @POST\r
78     @Path("/products")\r
79     @Consumes(MediaType.APPLICATION_JSON)\r
80     @Produces(MediaType.APPLICATION_JSON)\r
81     @Operation(description = "Create product", method = "POST", summary = "Returns created product",\r
82             responses = @ApiResponse(\r
83                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = Product.class)))))\r
84     @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Product created"),\r
85             @ApiResponse(responseCode = "403", description = "Restricted operation / Empty USER_ID header"),\r
86             @ApiResponse(responseCode = "400", description = "Invalid/missing content"),\r
87             @ApiResponse(responseCode = "409", description = "Product already exists / User not found / Wrong user role")})\r
88     public Response createProduct(@Parameter(description = "Product object to be created", required = true) String data,\r
89             @Context final HttpServletRequest request,\r
90             @HeaderParam(value = Constants.USER_ID_HEADER) @Parameter(description = "USER_ID of product strategist user",\r
91                     required = true) String userId) {\r
92 \r
93         String url = request.getMethod() + " " + request.getRequestURI();\r
94         log.debug("Start handle request of {}", url);\r
95 \r
96         User modifier = new User();\r
97         modifier.setUserId(userId);\r
98         log.debug("modifier id is {}", userId);\r
99 \r
100         Response response = null;\r
101         try {\r
102             Product product = RepresentationUtils.fromRepresentation(data, Product.class);\r
103             Either<Product, ResponseFormat> actionResponse = productBusinessLogic.createProduct(product, modifier);\r
104 \r
105             if (actionResponse.isRight()) {\r
106                 log.debug("Failed to create product");\r
107                 response = buildErrorResponse(actionResponse.right().value());\r
108                 return response;\r
109             }\r
110 \r
111             Object result = RepresentationUtils.toRepresentation(actionResponse.left().value());\r
112             response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), result);\r
113             return response;\r
114 \r
115         } catch (Exception e) {\r
116             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Product");\r
117             log.debug("create product failed with error ", e);\r
118             response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));\r
119             return response;\r
120         }\r
121     }\r
122 \r
123     @GET\r
124     @Path("/products/{productId}")\r
125     @Consumes(MediaType.APPLICATION_JSON)\r
126     @Produces(MediaType.APPLICATION_JSON)\r
127     @Operation(description = "Retrieve product", method = "GET", summary = "Returns product according to productId",\r
128             responses = @ApiResponse(\r
129                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = Product.class)))))\r
130     @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Product found"),\r
131             @ApiResponse(responseCode = "403", description = "Missing information"),\r
132             @ApiResponse(responseCode = "409", description = "Restricted operation"),\r
133             @ApiResponse(responseCode = "500", description = "Internal Server Error"),\r
134             @ApiResponse(responseCode = "404", description = "Product not found"),})\r
135     public Response getProductById(@PathParam("productId") final String productId,\r
136             @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {\r
137 \r
138         String url = request.getMethod() + " " + request.getRequestURI();\r
139         log.debug("Start handle request of {}", url);\r
140 \r
141         User modifier = new User();\r
142         modifier.setUserId(userId);\r
143         log.debug("modifier id is {}", userId);\r
144 \r
145         Response response = null;\r
146 \r
147         try {\r
148             log.trace("get product with id {}", productId);\r
149             Either<Product, ResponseFormat> actionResponse = productBusinessLogic.getProduct(productId, modifier);\r
150 \r
151             if (actionResponse.isRight()) {\r
152                 log.debug("Failed to get product");\r
153                 response = buildErrorResponse(actionResponse.right().value());\r
154                 return response;\r
155             }\r
156 \r
157             Object product = RepresentationUtils.toRepresentation(actionResponse.left().value());\r
158             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), product);\r
159 \r
160         } catch (Exception e) {\r
161             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Product");\r
162             log.debug("get product failed with error ", e);\r
163             response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));\r
164             return response;\r
165         }\r
166     }\r
167 \r
168     @GET\r
169     @Path("/products/productName/{productName}/productVersion/{productVersion}")\r
170     @Consumes(MediaType.APPLICATION_JSON)\r
171     @Produces(MediaType.APPLICATION_JSON)\r
172     @Operation(description = "Retrieve Service", method = "GET",\r
173             summary = "Returns product according to name and version",responses = @ApiResponse(\r
174                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = Product.class)))))\r
175     @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Product found"),\r
176             @ApiResponse(responseCode = "403", description = "Restricted operation"),\r
177             @ApiResponse(responseCode = "404", description = "Product not found")})\r
178     public Response getServiceByNameAndVersion(@PathParam("productName") final String productName,\r
179             @PathParam("productVersion") final String productVersion, @Context final HttpServletRequest request,\r
180             @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {\r
181 \r
182         // get modifier id\r
183         User modifier = new User();\r
184         modifier.setUserId(userId);\r
185         log.debug("modifier id is {}", userId);\r
186 \r
187         Response response = null;\r
188         try {\r
189             Either<Product, ResponseFormat> actionResponse =\r
190                     productBusinessLogic.getProductByNameAndVersion(productName, productVersion, userId);\r
191 \r
192             if (actionResponse.isRight()) {\r
193                 response = buildErrorResponse(actionResponse.right().value());\r
194                 return response;\r
195             }\r
196 \r
197             Product product = actionResponse.left().value();\r
198             Object result = RepresentationUtils.toRepresentation(product);\r
199 \r
200             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);\r
201 \r
202         } catch (Exception e) {\r
203             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get product by name and version");\r
204             log.debug("get product failed with exception", e);\r
205             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));\r
206 \r
207         }\r
208     }\r
209 \r
210     @DELETE\r
211     @Path("/products/{productId}")\r
212     public Response deleteProduct(@PathParam("productId") final String productId, @Context final HttpServletRequest request) {\r
213 \r
214         String url = request.getMethod() + " " + request.getRequestURI();\r
215         log.debug("Start handle request of {}", url);\r
216 \r
217         // get modifier id\r
218         String userId = request.getHeader(Constants.USER_ID_HEADER);\r
219         User modifier = new User();\r
220         modifier.setUserId(userId);\r
221         log.debug("modifier id is {}", userId);\r
222 \r
223         Response response = null;\r
224 \r
225         try {\r
226             log.trace("delete product with id {}", productId);\r
227             Either<Product, ResponseFormat> actionResponse = productBusinessLogic.deleteProduct(productId, modifier);\r
228 \r
229             if (actionResponse.isRight()) {\r
230                 log.debug("Failed to delete product");\r
231                 response = buildErrorResponse(actionResponse.right().value());\r
232                 return response;\r
233             }\r
234 \r
235             Object product = RepresentationUtils.toRepresentation(actionResponse.left().value());\r
236             response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), product);\r
237             return response;\r
238 \r
239         } catch (Exception e) {\r
240             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource");\r
241             log.debug("delete resource failed with error ", e);\r
242             response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));\r
243             return response;\r
244 \r
245         }\r
246     }\r
247 \r
248     @PUT\r
249     @Path("/products/{productId}/metadata")\r
250     @Consumes(MediaType.APPLICATION_JSON)\r
251     @Produces(MediaType.APPLICATION_JSON)\r
252     @Operation(description = "Update Product Metadata", method = "PUT", summary = "Returns updated product",\r
253             responses = @ApiResponse(\r
254                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = Product.class)))))\r
255     @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Product Updated"),\r
256             @ApiResponse(responseCode = "403", description = "Restricted operation"),\r
257             @ApiResponse(responseCode = "400", description = "Invalid content / Missing content")})\r
258     public Response updateProductMetadata(@PathParam("productId") final String productId,\r
259             @Parameter(description = "Product object to be Updated", required = true) String data,\r
260             @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {\r
261 \r
262         String url = request.getMethod() + " " + request.getRequestURI();\r
263         log.debug("Start handle request of {}", url);\r
264 \r
265         User modifier = new User();\r
266         modifier.setUserId(userId);\r
267         log.debug("modifier id is {}", userId);\r
268         Response response = null;\r
269 \r
270         try {\r
271             String productIdLower = productId.toLowerCase();\r
272             Product updatedProduct = RepresentationUtils.fromRepresentation(data, Product.class);\r
273             Either<Product, ResponseFormat> actionResponse =\r
274                     productBusinessLogic.updateProductMetadata(productIdLower, updatedProduct, modifier);\r
275 \r
276             if (actionResponse.isRight()) {\r
277                 log.debug("failed to update product");\r
278                 response = buildErrorResponse(actionResponse.right().value());\r
279                 return response;\r
280             }\r
281 \r
282             Product product = actionResponse.left().value();\r
283             Object result = RepresentationUtils.toRepresentation(product);\r
284             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);\r
285 \r
286         } catch (Exception e) {\r
287             log.debug("update product metadata failed with exception", e);\r
288             response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));\r
289             return response;\r
290         }\r
291     }\r
292 \r
293     @GET\r
294     @Path("/products/validate-name/{productName}")\r
295     @Consumes(MediaType.APPLICATION_JSON)\r
296     @Produces(MediaType.APPLICATION_JSON)\r
297     @Operation(description = "validate product name", method = "GET",\r
298             summary = "checks if the chosen product name is available ",responses = @ApiResponse(\r
299                     content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))))\r
300     @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Service found"),\r
301             @ApiResponse(responseCode = "403", description = "Restricted operation")})\r
302     public Response validateServiceName(@PathParam("productName") final String productName,\r
303             @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {\r
304         String url = request.getMethod() + " " + request.getRequestURI();\r
305         log.debug("Start handle request of {}", url);\r
306 \r
307         User modifier = new User();\r
308         modifier.setUserId(userId);\r
309         log.debug("modifier id is {}", userId);\r
310         Response response = null;\r
311         try {\r
312             Either<Map<String, Boolean>, ResponseFormat> actionResponse =\r
313                     productBusinessLogic.validateProductNameExists(productName, userId);\r
314 \r
315             if (actionResponse.isRight()) {\r
316                 log.debug("failed to get validate service name");\r
317                 response = buildErrorResponse(actionResponse.right().value());\r
318                 return response;\r
319             }\r
320             return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),\r
321                     actionResponse.left().value());\r
322         } catch (Exception e) {\r
323             BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Validate Product Name");\r
324             log.debug("validate product name failed with exception", e);\r
325             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));\r
326         }\r
327     }\r
328 \r
329 }\r