| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache license, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the license for the specific language governing permissions and |
| * limitations under the license. |
| */ |
| package org.apache.logging.log4j.audit.service.controller; |
| |
| import java.lang.reflect.Type; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Optional; |
| import javax.annotation.PostConstruct; |
| |
| import io.swagger.annotations.ApiImplicitParam; |
| import io.swagger.annotations.ApiImplicitParams; |
| import io.swagger.annotations.ApiOperation; |
| import io.swagger.annotations.ApiParam; |
| import org.apache.logging.log4j.LogManager; |
| import org.apache.logging.log4j.Logger; |
| import org.apache.logging.log4j.audit.service.catalog.AuditManager; |
| import org.apache.logging.log4j.catalog.api.Attribute; |
| import org.apache.logging.log4j.catalog.api.Category; |
| import org.apache.logging.log4j.catalog.api.Event; |
| import org.apache.logging.log4j.catalog.api.Product; |
| import org.apache.logging.log4j.catalog.api.Versions; |
| import org.apache.logging.log4j.catalog.jpa.converter.AttributeConverter; |
| import org.apache.logging.log4j.catalog.jpa.converter.AttributeModelConverter; |
| import org.apache.logging.log4j.catalog.jpa.converter.CategoryConverter; |
| import org.apache.logging.log4j.catalog.jpa.converter.CategoryModelConverter; |
| import org.apache.logging.log4j.catalog.jpa.converter.EventConverter; |
| import org.apache.logging.log4j.catalog.jpa.converter.EventModelConverter; |
| import org.apache.logging.log4j.catalog.jpa.converter.ProductConverter; |
| import org.apache.logging.log4j.catalog.jpa.converter.ProductModelConverter; |
| import org.apache.logging.log4j.catalog.jpa.model.AttributeModel; |
| import org.apache.logging.log4j.catalog.jpa.model.CategoryModel; |
| import org.apache.logging.log4j.catalog.jpa.model.EventModel; |
| import org.apache.logging.log4j.catalog.jpa.model.ProductModel; |
| import org.apache.logging.log4j.catalog.jpa.service.AttributeService; |
| import org.apache.logging.log4j.catalog.jpa.service.CategoryService; |
| import org.apache.logging.log4j.catalog.jpa.service.EventService; |
| import org.apache.logging.log4j.catalog.jpa.service.ProductService; |
| import org.modelmapper.ModelMapper; |
| import org.modelmapper.TypeToken; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.http.HttpStatus; |
| import org.springframework.http.ResponseEntity; |
| import org.springframework.web.bind.annotation.DeleteMapping; |
| import org.springframework.web.bind.annotation.GetMapping; |
| import org.springframework.web.bind.annotation.PathVariable; |
| import org.springframework.web.bind.annotation.PostMapping; |
| import org.springframework.web.bind.annotation.PutMapping; |
| import org.springframework.web.bind.annotation.RequestBody; |
| import org.springframework.web.bind.annotation.RequestMapping; |
| import org.springframework.web.bind.annotation.RequestParam; |
| import org.springframework.web.bind.annotation.RestController; |
| |
| import static org.apache.logging.log4j.catalog.api.constant.Constants.DEFAULT_CATALOG; |
| |
| @RestController |
| @RequestMapping(value = "/catalog") |
| public class CatalogController { |
| |
| private static final Logger LOGGER = LogManager.getLogger(CatalogController.class); |
| |
| private final ModelMapper attributeModelMapper = new ModelMapper(); |
| private final ModelMapper eventModelMapper = new ModelMapper(); |
| private final ModelMapper productModelMapper = new ModelMapper(); |
| private final ModelMapper categoryModelMapper = new ModelMapper(); |
| |
| @Autowired |
| private AttributeService attributeService; |
| |
| @Autowired |
| private AttributeModelConverter attributeModelConverter; |
| |
| @Autowired |
| private AttributeConverter attributeConverter; |
| |
| @Autowired |
| private EventService eventService; |
| |
| @Autowired |
| private EventModelConverter eventModelConverter; |
| |
| @Autowired |
| private EventConverter eventConverter; |
| |
| @Autowired |
| private ProductService productService; |
| |
| @Autowired |
| private ProductModelConverter productModelConverter; |
| |
| @Autowired |
| private ProductConverter productConverter; |
| |
| @Autowired |
| private CategoryService categoryService; |
| |
| @Autowired |
| private AuditManager auditManager; |
| |
| @Autowired |
| private CategoryModelConverter categoryModelConverter; |
| |
| @Autowired |
| private CategoryConverter categoryConverter; |
| |
| @PostConstruct |
| public void init() { |
| attributeModelMapper.addConverter(attributeModelConverter); |
| eventModelMapper.addConverter(eventModelConverter); |
| productModelMapper.addConverter(productModelConverter); |
| categoryModelMapper.addConverter(categoryModelConverter); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "List catalog Attributes", notes = "List catalog attributes for a catalog id", tags = {"Catalog"}) |
| @GetMapping(value = "{catalogId}/attributes") |
| public ResponseEntity<List<Attribute>> getAttributes(@ApiParam(value = "catalog id", required = true) @PathVariable String catalogId, |
| @RequestParam(value = "startIndex", required = false) Integer startIndex, |
| @RequestParam(value = "pageSize", required = false) Integer pageSize, |
| @RequestParam(value = "sortCol", required= false) String sortColumn, |
| @RequestParam(value = "sortDir", required = false) String sortDirection) { |
| Type listType = new TypeToken<List<Attribute>>() { |
| }.getType(); |
| List<Attribute> attributes; |
| if (startIndex == null || pageSize == null) { |
| attributes = attributeModelMapper.map(attributeService.getAttributes(catalogId), listType); |
| } else { |
| sortDirection = validateSortDirection(sortDirection); |
| if (sortColumn == null || sortColumn.length() == 0) { |
| sortColumn = "name"; |
| } |
| int startPage = 0; |
| if (startIndex > 0) { |
| startPage = startIndex / pageSize; |
| } |
| attributes = attributeModelMapper.map(attributeService.getAttributes(startPage, pageSize, sortColumn, |
| sortDirection), listType); |
| } |
| if (attributes == null) { |
| attributes = new ArrayList<>(); |
| } |
| return new ResponseEntity<>(attributes, HttpStatus.OK); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "Create a catalog Attribute", notes = "Returns a catalog attribute", tags = {"Catalog"}) |
| @GetMapping(value = "{catalogId}/attribute/{name}") |
| public ResponseEntity<Attribute> getAttribute(@ApiParam(value = "catalog id", required = true) @PathVariable String catalogId, |
| @ApiParam(value = "attribute name", required = true) @PathVariable String name) { |
| Optional<AttributeModel> optional = attributeService.getAttribute(catalogId, name); |
| if (!optional.isPresent()) { |
| LOGGER.warn("Unable to locate attribute {} in catalog {}", name, catalogId); |
| return new ResponseEntity<>(HttpStatus.NOT_FOUND); |
| } |
| Attribute attribute = attributeModelConverter.convert(optional.get()); |
| return new ResponseEntity<>(attribute, HttpStatus.OK); |
| } |
| |
| |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "Create a catalog Attribute", notes = "Creates a catalog attribute", tags = {"Catalog"}) |
| @PostMapping(value = "/attribute", consumes=Versions.V1_0, produces=Versions.V1_0) |
| public ResponseEntity<Attribute> createAttribute(@ApiParam(value = "attribute", required = true) @RequestBody Attribute attribute) { |
| if (attribute.getCatalogId() == null) { |
| throw new IllegalArgumentException("A catalog id is required."); |
| } |
| if (DEFAULT_CATALOG.equals(attribute.getCatalogId())) { |
| throw new IllegalArgumentException("The default catalog cannot be modified at run time."); |
| } |
| AttributeModel model; |
| synchronized(this) { |
| Optional<AttributeModel> opt = attributeService.getAttribute(attribute.getCatalogId(), attribute.getName()); |
| if (opt != null && opt.isPresent()) { |
| throw new IllegalStateException( |
| "An attribute named " + attribute.getName() + " in catalog " + attribute.getCatalogId() + " already exists"); |
| } |
| model = attributeService.saveAttribute(attributeConverter.convert(attribute)); |
| auditManager.saveAttribute(attribute); |
| } |
| return new ResponseEntity<>(attributeModelConverter.convert(model), HttpStatus.CREATED); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "Update a catalog Attribute", notes = "Updates a catalog attribute", tags = {"Catalog"}) |
| @PutMapping(value = "/attribute", consumes=Versions.V1_0, produces=Versions.V1_0) |
| public ResponseEntity<Attribute> updateAttribute(@ApiParam(value = "attribute", required = true) @RequestBody Attribute attribute) { |
| if (attribute.getId() == null) { |
| throw new IllegalArgumentException("An Attribute must have an id to be updated."); |
| } |
| if (attribute.getCatalogId() == null) { |
| throw new IllegalArgumentException("A catalog id is required in the Attribute."); |
| } |
| if (DEFAULT_CATALOG.equals(attribute.getCatalogId())) { |
| throw new IllegalArgumentException("The default catalog cannot be modified at run time."); |
| } |
| AttributeModel model = attributeConverter.convert(attribute); |
| model = attributeService.saveAttribute(model); |
| auditManager.saveAttribute(attribute); |
| return new ResponseEntity<>(attributeModelConverter.convert(model), HttpStatus.OK); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "Deletes a catalog Attribute", notes = "Deletes a catalog attribute", tags = {"Catalog"}) |
| @DeleteMapping(value = "/attribute/{id}") |
| public ResponseEntity<?> deleteAttribute(@RequestParam("id") Long attributeId) { |
| synchronized (this) { |
| Optional<AttributeModel> opt = attributeService.getAttribute(attributeId); |
| if (opt.isPresent()) { |
| attributeService.deleteAttribute(attributeId); |
| } |
| } |
| return new ResponseEntity<>(HttpStatus.OK); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "List catalog Events", notes = "Lists catalog events for a catalog id", tags = {"Catalog"}) |
| @GetMapping(value = "{catalogId}/events") |
| public ResponseEntity<List<Event>> getEvents(@ApiParam(value = "catalog id", required = true) @PathVariable String catalogId, |
| @RequestParam(value = "startIndex", required = false) Integer startIndex, |
| @RequestParam(value = "pageSize", required = false) Integer pageSize, |
| @RequestParam(value = "sortCol", required= false) String sortColumn, |
| @RequestParam(value = "sortDir", required = false) String sortDirection) { |
| Type listType = new TypeToken<List<Event>>() {}.getType(); |
| List<Event> events; |
| if (startIndex == null || pageSize == null) { |
| events = eventModelMapper.map(eventService.getEvents(catalogId), listType); |
| } else { |
| sortDirection = validateSortDirection(sortDirection); |
| if (sortColumn == null || sortColumn.length() == 0) { |
| sortColumn = "name"; |
| } |
| int startPage = 0; |
| if (startIndex > 0) { |
| startPage = startIndex / pageSize; |
| } |
| events = eventModelMapper.map(eventService.getEvents(startPage, pageSize, sortColumn, |
| sortDirection), listType); |
| } |
| if (events == null) { |
| events = new ArrayList<>(); |
| } |
| return new ResponseEntity<>(events, HttpStatus.OK); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "Create a catalog Event", notes = "Creates a catalog event", tags = {"Catalog"}) |
| @PostMapping(value = "/event", consumes=Versions.V1_0, produces=Versions.V1_0) |
| public ResponseEntity<Event> createEvent(@ApiParam(value = "event", required = true) @RequestBody Event event) { |
| if (event.getCatalogId() == null) { |
| throw new IllegalArgumentException("A catalog id is required to create an event."); |
| } |
| if (DEFAULT_CATALOG.equals(event.getCatalogId())) { |
| throw new IllegalArgumentException("The default catalog cannot be modified at run time."); |
| } |
| EventModel model; |
| synchronized(this) { |
| Optional<EventModel> opt = eventService.getEvent(event.getCatalogId(), event.getName()); |
| if (opt != null && opt.isPresent()) { |
| throw new IllegalStateException( |
| "An event named " + event.getName() + " in catalog " + event.getCatalogId() + " already exists"); |
| } |
| model = auditManager.saveEvent(event); |
| } |
| return new ResponseEntity<>(eventModelConverter.convert(model), HttpStatus.CREATED); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "Update a catalog Event", notes = "Updates a catalog event", tags = {"Catalog"}) |
| @PutMapping(value = "/event", consumes=Versions.V1_0, produces=Versions.V1_0) |
| public ResponseEntity<Event> updateEvent(@ApiParam(value = "event", required = true) @RequestBody Event event) { |
| if (event.getCatalogId() == null) { |
| throw new IllegalArgumentException("A catalog id is required to update an event."); |
| } |
| if (DEFAULT_CATALOG.equals(event.getCatalogId())) { |
| throw new IllegalArgumentException("The default catalog cannot be modified at run time."); |
| } |
| EventModel model; |
| synchronized(this) { |
| model = eventConverter.convert(event); |
| model = eventService.saveEvent(model); |
| } |
| return new ResponseEntity<>(eventModelConverter.convert(model), HttpStatus.OK); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "Deletes a catalog event", notes = "Deletes a catalog event", tags = {"Catalog"}) |
| @DeleteMapping(value = "/event/{id}") |
| public ResponseEntity<?> deleteEvent(@RequestParam("id") Long eventId) { |
| eventService.deleteEvent(eventId); |
| return new ResponseEntity<>(HttpStatus.OK); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "List catalog Products", notes = "Lists catalog products for a catalog id", tags = {"Catalog"}) |
| @GetMapping(value = "{catalogId}/products") |
| public ResponseEntity<List<Product>> getProducts(@ApiParam(value = "catalog id", required = true) @PathVariable String catalogId, |
| @RequestParam(value = "startIndex", required = false) Integer startIndex, |
| @RequestParam(value = "pageSize", required = false) Integer pageSize, |
| @RequestParam(value = "sortCol", required= false) String sortColumn, |
| @RequestParam(value = "sortDir", required = false) String sortDirection) { |
| Type listType = new TypeToken<List<Product>>() {}.getType(); |
| List<Product> products; |
| if (startIndex == null || pageSize == null) { |
| products = productModelMapper.map(productService.getProducts(catalogId), listType); |
| } else { |
| sortDirection = validateSortDirection(sortDirection); |
| if (sortColumn == null || sortColumn.length() == 0) { |
| sortColumn = "name"; |
| } |
| int startPage = 0; |
| if (startIndex > 0) { |
| startPage = startIndex / pageSize; |
| } |
| products = productModelMapper.map(productService.getProducts(startPage, pageSize, sortColumn, |
| sortDirection), listType); |
| } |
| if (products == null) { |
| products = new ArrayList<>(); |
| } |
| return new ResponseEntity<>(products, HttpStatus.OK); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "Create a catalog Product", notes = "Creates a catalog product", tags = {"Catalog"}) |
| @PostMapping(value = "/product", consumes=Versions.V1_0, produces=Versions.V1_0) |
| public ResponseEntity<Product> createProduct(@ApiParam(value = "product", required = true) @RequestBody Product product) { |
| if (product.getCatalogId() == null) { |
| throw new IllegalArgumentException("A catalog id is required to create a product."); |
| } |
| if (DEFAULT_CATALOG.equals(product.getCatalogId())) { |
| throw new IllegalArgumentException("The default catalog cannot be modified at run time."); |
| } |
| Optional<ProductModel> opt = productService.getProduct(product.getCatalogId(), product.getName()); |
| if (opt != null && opt.isPresent()) { |
| throw new IllegalStateException("A product named "+ product.getName() + " in catalog " + |
| product.getCatalogId() + " already exists"); |
| } |
| ProductModel model = productConverter.convert(product); |
| model = productService.saveProduct(model); |
| return new ResponseEntity<>(productModelConverter.convert(model), HttpStatus.CREATED); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "Update a catalog Product", notes = "Updates a catalog event", tags = {"Catalog"}) |
| @PutMapping(value = "/product", consumes=Versions.V1_0, produces=Versions.V1_0) |
| public ResponseEntity<Product> updateProduct(@ApiParam(value = "product", required = true) @RequestBody Product product) { |
| if (product.getCatalogId() == null) { |
| throw new IllegalArgumentException("A catalog id is required to update a product."); |
| } |
| if (DEFAULT_CATALOG.equals(product.getCatalogId())) { |
| throw new IllegalArgumentException("The default catalog cannot be modified at run time."); |
| } |
| ProductModel model = productConverter.convert(product); |
| model = productService.saveProduct(model); |
| return new ResponseEntity<>(productModelConverter.convert(model), HttpStatus.OK); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "Deletes a catalog product", notes = "Deletes a catalog product", tags = {"Catalog"}) |
| @DeleteMapping(value = "/product/{id}") |
| public ResponseEntity<?> deleteProduct(@RequestParam("id") Long productId) { |
| productService.deleteProduct(productId); |
| return new ResponseEntity<>(HttpStatus.OK); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "List catalog Categories", notes = "Lists catalog categories for a catalog id", tags = {"Catalog"}) |
| @GetMapping(value = "{catalogId}/categories") |
| public ResponseEntity<List<Category>> getCategories(@ApiParam(value = "catalog id", required = true) @PathVariable String catalogId, |
| @RequestParam(value = "startIndex", required = false) Integer startIndex, |
| @RequestParam(value = "pageSize", required = false) Integer pageSize, |
| @RequestParam(value = "sortCol", required= false) String sortColumn, |
| @RequestParam(value = "sortDir", required = false) String sortDirection) { |
| Type listType = new TypeToken<List<Category>>() {}.getType(); |
| List<Category> categories; |
| if (startIndex == null || pageSize == null) { |
| categories = categoryModelMapper.map(categoryService.getCategories(catalogId), listType); |
| } else { |
| sortDirection = validateSortDirection(sortDirection); |
| if (sortColumn == null || sortColumn.length() == 0) { |
| sortColumn = "name"; |
| } |
| int startPage = 0; |
| if (startIndex > 0) { |
| startPage = startIndex / pageSize; |
| } |
| categories = categoryModelMapper.map(categoryService.getCategories(startPage, pageSize, sortColumn, |
| sortDirection), listType); |
| } |
| if (categories == null) { |
| categories = new ArrayList<>(); |
| } |
| return new ResponseEntity<>(categories, HttpStatus.OK); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "Create a catalog Category", notes = "Creates a catalog category", tags = {"Catalog"}) |
| @PostMapping(value = "/category", consumes=Versions.V1_0, produces=Versions.V1_0) |
| public ResponseEntity<Category> createCategory(@ApiParam(value = "category", required = true) @RequestBody Category category) { |
| if (category.getCatalogId() == null) { |
| throw new IllegalArgumentException("A catalog id is required to create a category."); |
| } |
| if (DEFAULT_CATALOG.equals(category.getCatalogId())) { |
| throw new IllegalArgumentException("The default catalog cannot be modified at run time."); |
| } |
| Optional<CategoryModel> opt = categoryService.getCategory(category.getCatalogId(), category.getName()); |
| if (opt != null && opt.isPresent()) { |
| throw new IllegalStateException("A category named "+ category.getName() + " in catalog " + |
| category.getCatalogId() + " already exists"); |
| } |
| CategoryModel model = categoryConverter.convert(category); |
| model = categoryService.saveCategory(model); |
| return new ResponseEntity<>(categoryModelConverter.convert(model), HttpStatus.CREATED); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "Update a catalog Category", notes = "Updates a catalog category", tags = {"Catalog"}) |
| @PutMapping(value = "/category", consumes=Versions.V1_0, produces=Versions.V1_0) |
| public ResponseEntity<Category> updateCategory(@ApiParam(value = "category", required = true) @RequestBody Category category) { |
| if (category.getCatalogId() == null) { |
| throw new IllegalArgumentException("A catalog id is required to create a category."); |
| } |
| if (DEFAULT_CATALOG.equals(category.getCatalogId())) { |
| throw new IllegalArgumentException("The default catalog cannot be modified at run time."); |
| } |
| CategoryModel model = categoryConverter.convert(category); |
| model = categoryService.saveCategory(model); |
| return new ResponseEntity<>(categoryModelConverter.convert(model), HttpStatus.OK); |
| } |
| |
| @ApiImplicitParams( {@ApiImplicitParam(dataType = "String", name = "Authorization", paramType = "header")}) |
| @ApiOperation(value = "Deletes a catalog category", notes = "Deletes a catalog category", tags = {"Catalog"}) |
| @DeleteMapping(value = "/category/{id}") |
| public ResponseEntity<?> deleteCategory(@RequestParam("id") Long categoryId) { |
| categoryService.deleteCategory(categoryId); |
| return new ResponseEntity<>(HttpStatus.OK); |
| } |
| |
| private String validateSortDirection(String sortDirection) { |
| if (sortDirection == null) { |
| sortDirection = "ASC"; |
| } else if (!sortDirection.equals("ASC") && !sortDirection.equals("DESC")) { |
| LOGGER.warn("Invalid sort direction {}, defaulting to ascending", sortDirection); |
| sortDirection = "ASC"; |
| } |
| return sortDirection; |
| } |
| } |