2 * ============LICENSE_START=======================================================
\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
11 * http://www.apache.org/licenses/LICENSE-2.0
\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
21 package org.openecomp.sdc.be.servlets;
\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
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
65 public class ProductServlet extends BeGenericServlet {
\r
66 private static final Logger log = Logger.getLogger(ProductServlet.class);
\r
67 private final ProductBusinessLogic productBusinessLogic;
\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
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
93 String url = request.getMethod() + " " + request.getRequestURI();
\r
94 log.debug("Start handle request of {}", url);
\r
96 User modifier = new User();
\r
97 modifier.setUserId(userId);
\r
98 log.debug("modifier id is {}", userId);
\r
100 Response response = null;
\r
102 Product product = RepresentationUtils.fromRepresentation(data, Product.class);
\r
103 Either<Product, ResponseFormat> actionResponse = productBusinessLogic.createProduct(product, modifier);
\r
105 if (actionResponse.isRight()) {
\r
106 log.debug("Failed to create product");
\r
107 response = buildErrorResponse(actionResponse.right().value());
\r
111 Object result = RepresentationUtils.toRepresentation(actionResponse.left().value());
\r
112 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), result);
\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
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
138 String url = request.getMethod() + " " + request.getRequestURI();
\r
139 log.debug("Start handle request of {}", url);
\r
141 User modifier = new User();
\r
142 modifier.setUserId(userId);
\r
143 log.debug("modifier id is {}", userId);
\r
145 Response response = null;
\r
148 log.trace("get product with id {}", productId);
\r
149 Either<Product, ResponseFormat> actionResponse = productBusinessLogic.getProduct(productId, modifier);
\r
151 if (actionResponse.isRight()) {
\r
152 log.debug("Failed to get product");
\r
153 response = buildErrorResponse(actionResponse.right().value());
\r
157 Object product = RepresentationUtils.toRepresentation(actionResponse.left().value());
\r
158 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), product);
\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
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
183 User modifier = new User();
\r
184 modifier.setUserId(userId);
\r
185 log.debug("modifier id is {}", userId);
\r
187 Response response = null;
\r
189 Either<Product, ResponseFormat> actionResponse =
\r
190 productBusinessLogic.getProductByNameAndVersion(productName, productVersion, userId);
\r
192 if (actionResponse.isRight()) {
\r
193 response = buildErrorResponse(actionResponse.right().value());
\r
197 Product product = actionResponse.left().value();
\r
198 Object result = RepresentationUtils.toRepresentation(product);
\r
200 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
\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
211 @Path("/products/{productId}")
\r
212 public Response deleteProduct(@PathParam("productId") final String productId, @Context final HttpServletRequest request) {
\r
214 String url = request.getMethod() + " " + request.getRequestURI();
\r
215 log.debug("Start handle request of {}", url);
\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
223 Response response = null;
\r
226 log.trace("delete product with id {}", productId);
\r
227 Either<Product, ResponseFormat> actionResponse = productBusinessLogic.deleteProduct(productId, modifier);
\r
229 if (actionResponse.isRight()) {
\r
230 log.debug("Failed to delete product");
\r
231 response = buildErrorResponse(actionResponse.right().value());
\r
235 Object product = RepresentationUtils.toRepresentation(actionResponse.left().value());
\r
236 response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), product);
\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
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
262 String url = request.getMethod() + " " + request.getRequestURI();
\r
263 log.debug("Start handle request of {}", url);
\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
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
276 if (actionResponse.isRight()) {
\r
277 log.debug("failed to update product");
\r
278 response = buildErrorResponse(actionResponse.right().value());
\r
282 Product product = actionResponse.left().value();
\r
283 Object result = RepresentationUtils.toRepresentation(product);
\r
284 return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result);
\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
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
307 User modifier = new User();
\r
308 modifier.setUserId(userId);
\r
309 log.debug("modifier id is {}", userId);
\r
310 Response response = null;
\r
312 Either<Map<String, Boolean>, ResponseFormat> actionResponse =
\r
313 productBusinessLogic.validateProductNameExists(productName, userId);
\r
315 if (actionResponse.isRight()) {
\r
316 log.debug("failed to get validate service name");
\r
317 response = buildErrorResponse(actionResponse.right().value());
\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