From 153879e9368216f08ceecfd729532607f94ff452 Mon Sep 17 00:00:00 2001 From: AbhishekT Date: Tue, 26 Sep 2023 00:06:27 +0530 Subject: [PATCH 1/3] Implemented 7 apis --- .../controllers/CategoryController.java | 6 + .../controllers/FakeProductController.java | 69 +++++++++++ .../controllers/ProductController.java | 40 +++---- .../productservice/dtos/CategoryDto.java | 1 - .../naman/productservice/models/Category.java | 2 +- .../naman/productservice/models/Product.java | 1 - .../repositories/ProductRepository.java | 5 + .../services/CategoryService.java | 2 + .../services/CategoryServiceImpl.java | 31 +++++ .../services/FakeProductService.java | 18 +++ .../services/ProductService.java | 13 +- .../services/SelfProductServiceImpl.java | 111 ++++++++++++++++-- 12 files changed, 262 insertions(+), 37 deletions(-) create mode 100644 src/main/java/dev/naman/productservice/controllers/FakeProductController.java create mode 100644 src/main/java/dev/naman/productservice/services/FakeProductService.java diff --git a/src/main/java/dev/naman/productservice/controllers/CategoryController.java b/src/main/java/dev/naman/productservice/controllers/CategoryController.java index be875bb..b38994e 100644 --- a/src/main/java/dev/naman/productservice/controllers/CategoryController.java +++ b/src/main/java/dev/naman/productservice/controllers/CategoryController.java @@ -1,5 +1,6 @@ package dev.naman.productservice.controllers; +import dev.naman.productservice.dtos.CategoryDto; import dev.naman.productservice.dtos.GetProductTitlesRequestDto; import dev.naman.productservice.dtos.ProductDto; import dev.naman.productservice.models.Category; @@ -46,4 +47,9 @@ public List getProductTitles(@RequestBody GetProductTitlesRequestDto req return categoryService.getProductTitles(uuids); } + @GetMapping() + public List getAllCategories(@RequestBody GetProductTitlesRequestDto requestDto) { + List uuids = requestDto.getUuids(); + return categoryService.getAllCategories(uuids); + } } diff --git a/src/main/java/dev/naman/productservice/controllers/FakeProductController.java b/src/main/java/dev/naman/productservice/controllers/FakeProductController.java new file mode 100644 index 0000000..b4897bc --- /dev/null +++ b/src/main/java/dev/naman/productservice/controllers/FakeProductController.java @@ -0,0 +1,69 @@ +package dev.naman.productservice.controllers; + +import dev.naman.productservice.dtos.GenericProductDto; +import dev.naman.productservice.exceptions.NotFoundException; +import dev.naman.productservice.services.FakeProductService; +import dev.naman.productservice.services.FakeStoreProductService; +import dev.naman.productservice.services.ProductService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/fakeproducts") +public class FakeProductController { +// @Autowired + // field injection + private FakeProductService fakeProductService; + // ....; + // ...; + + + + // constructor injection +// @Autowired + public FakeProductController(FakeProductService fakeProductService) { + this.fakeProductService = fakeProductService; + } +// + + // setter injection +// @Autowired +// public void setProductService(ProductService productService) { +// this.productService = productService; +// } + + // GET /products {} + @GetMapping + public List getAllProducts() { + return fakeProductService.getAllProducts(); + } + + // localhost:8080/products/{id} + // localhost:8080/products/123 + @GetMapping("{id}") + public GenericProductDto getProductById(@PathVariable("id") Long id) throws NotFoundException { + return fakeProductService.getProductById(id); + } + + @DeleteMapping("{id}") + public ResponseEntity deleteProductById(@PathVariable("id") Long id) { + return new ResponseEntity<>( + fakeProductService.deleteProduct(id), + HttpStatus.OK + ); + } + + @PostMapping + public GenericProductDto createProduct(@RequestBody GenericProductDto product) { +// System.out.println(product.name); + return fakeProductService.createProduct(product); + } + +// @PutMapping("{id}") +// public void updateProductById() { +// +// } +} diff --git a/src/main/java/dev/naman/productservice/controllers/ProductController.java b/src/main/java/dev/naman/productservice/controllers/ProductController.java index af619d5..8d92af2 100644 --- a/src/main/java/dev/naman/productservice/controllers/ProductController.java +++ b/src/main/java/dev/naman/productservice/controllers/ProductController.java @@ -2,7 +2,10 @@ import dev.naman.productservice.dtos.ExceptionDto; import dev.naman.productservice.dtos.GenericProductDto; +import dev.naman.productservice.dtos.GetProductTitlesRequestDto; +import dev.naman.productservice.dtos.ProductDto; import dev.naman.productservice.exceptions.NotFoundException; +import dev.naman.productservice.models.Product; import dev.naman.productservice.services.ProductService; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.HttpStatus; @@ -14,42 +17,36 @@ @RestController @RequestMapping("/products") public class ProductController { -// @Autowired - // field injection private ProductService productService; - // ....; - // ...; - - - // constructor injection -// @Autowired public ProductController(ProductService productService) { this.productService = productService; } -// - // setter injection -// @Autowired -// public void setProductService(ProductService productService) { -// this.productService = productService; -// } // GET /products {} @GetMapping - public List getAllProducts() { - return productService.getAllProducts(); + public List getAllProducts(@RequestBody GetProductTitlesRequestDto requestDto) { + List uuids = requestDto.getUuids(); + return productService.getAllProducts(uuids); + } + + // localhost:8080/products/{id} + // localhost:8080/products/123 + @GetMapping("/category/{categoryId}") + public List getProductsInCategory(@PathVariable("categoryId") String categoryId) throws NotFoundException { + return productService.getProductsInCategory(categoryId); } // localhost:8080/products/{id} // localhost:8080/products/123 @GetMapping("{id}") - public GenericProductDto getProductById(@PathVariable("id") Long id) throws NotFoundException { + public ProductDto getProductById(@PathVariable("id") String id) throws NotFoundException { return productService.getProductById(id); } @DeleteMapping("{id}") - public ResponseEntity deleteProductById(@PathVariable("id") Long id) { + public ResponseEntity deleteProductById(@PathVariable("id") String id) { return new ResponseEntity<>( productService.deleteProduct(id), HttpStatus.OK @@ -57,13 +54,12 @@ public ResponseEntity deleteProductById(@PathVariable("id") L } @PostMapping - public GenericProductDto createProduct(@RequestBody GenericProductDto product) { -// System.out.println(product.name); + public ProductDto createProduct(@RequestBody Product product) { return productService.createProduct(product); } @PutMapping("{id}") - public void updateProductById() { - + public ProductDto updateProductById(@RequestBody ProductDto product,@PathVariable("id") String id) { + return productService.updateProduct(product,id); } } diff --git a/src/main/java/dev/naman/productservice/dtos/CategoryDto.java b/src/main/java/dev/naman/productservice/dtos/CategoryDto.java index fabb541..ba5c015 100644 --- a/src/main/java/dev/naman/productservice/dtos/CategoryDto.java +++ b/src/main/java/dev/naman/productservice/dtos/CategoryDto.java @@ -9,6 +9,5 @@ @Setter public class CategoryDto { private String name; - private List products; } diff --git a/src/main/java/dev/naman/productservice/models/Category.java b/src/main/java/dev/naman/productservice/models/Category.java index 4fd8f7f..c5e70cc 100644 --- a/src/main/java/dev/naman/productservice/models/Category.java +++ b/src/main/java/dev/naman/productservice/models/Category.java @@ -18,7 +18,7 @@ public class Category extends BaseModel { private String name; @OneToMany(mappedBy = "category") - @Fetch(FetchMode.SELECT) + @Fetch(FetchMode.SUBSELECT) private List products = new ArrayList<>(); // this is the same relation being mapped by category attribute in the other (Product) class diff --git a/src/main/java/dev/naman/productservice/models/Product.java b/src/main/java/dev/naman/productservice/models/Product.java index aeac87b..7678e1f 100644 --- a/src/main/java/dev/naman/productservice/models/Product.java +++ b/src/main/java/dev/naman/productservice/models/Product.java @@ -29,5 +29,4 @@ public class Product extends BaseModel { @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY) // @Fetch(FetchMode.JOIN) private Price price; -// private double price; } diff --git a/src/main/java/dev/naman/productservice/repositories/ProductRepository.java b/src/main/java/dev/naman/productservice/repositories/ProductRepository.java index c2bd45c..5a071d8 100644 --- a/src/main/java/dev/naman/productservice/repositories/ProductRepository.java +++ b/src/main/java/dev/naman/productservice/repositories/ProductRepository.java @@ -1,5 +1,6 @@ package dev.naman.productservice.repositories; +import dev.naman.productservice.dtos.ProductDto; import dev.naman.productservice.models.Category; import dev.naman.productservice.models.Product; import org.springframework.data.domain.Example; @@ -9,12 +10,15 @@ import org.springframework.stereotype.Repository; import java.util.List; +import java.util.Optional; import java.util.UUID; import java.util.function.Function; @Repository public interface ProductRepository extends JpaRepository { + @Override + Optional findById(UUID uuid); Product findByTitleEquals(String title); @@ -25,6 +29,7 @@ public interface ProductRepository @Override void delete(Product entity); + long countAllByPrice_Currency(String currency); diff --git a/src/main/java/dev/naman/productservice/services/CategoryService.java b/src/main/java/dev/naman/productservice/services/CategoryService.java index 91d2912..7f364cf 100644 --- a/src/main/java/dev/naman/productservice/services/CategoryService.java +++ b/src/main/java/dev/naman/productservice/services/CategoryService.java @@ -1,5 +1,6 @@ package dev.naman.productservice.services; +import dev.naman.productservice.dtos.CategoryDto; import dev.naman.productservice.models.Category; import java.util.List; @@ -7,4 +8,5 @@ public interface CategoryService { Category getCategory(String uuid); List getProductTitles(List categoryUUIDs); + List getAllCategories(List categoryUUIds); } diff --git a/src/main/java/dev/naman/productservice/services/CategoryServiceImpl.java b/src/main/java/dev/naman/productservice/services/CategoryServiceImpl.java index b167a55..5235d3b 100644 --- a/src/main/java/dev/naman/productservice/services/CategoryServiceImpl.java +++ b/src/main/java/dev/naman/productservice/services/CategoryServiceImpl.java @@ -1,5 +1,7 @@ package dev.naman.productservice.services; +import dev.naman.productservice.dtos.CategoryDto; +import dev.naman.productservice.dtos.ProductDto; import dev.naman.productservice.models.Category; import dev.naman.productservice.models.Product; import dev.naman.productservice.repositories.CategoryRepository; @@ -76,4 +78,33 @@ public List getProductTitles(List categoryUUIDs) { return titles; } + + @Override + public List getAllCategories(List categoryUUIds) { + List uuids = new ArrayList<>(); + for(String categoryId: categoryUUIds){ + uuids.add(UUID.fromString(categoryId)); + } + List categories = categoryRepository.findAllById(uuids); + List categoryDtos = new ArrayList<>(); + for(Category category:categories){ + CategoryDto categoryDto = new CategoryDto(); + categoryDto.setName(category.getName()); + List products = category.getProducts(); + List productDtos = new ArrayList<>(); + products.forEach( + product -> { + ProductDto productDto = new ProductDto(); + productDto.setTitle(product.getTitle()); + productDto.setDescription(product.getDescription()); + productDto.setImage(product.getImage()); + productDto.setPrice(product.getPrice()); + productDtos.add(productDto); + } + ); + categoryDto.setProducts(productDtos); + categoryDtos.add(categoryDto); + } + return categoryDtos; + } } diff --git a/src/main/java/dev/naman/productservice/services/FakeProductService.java b/src/main/java/dev/naman/productservice/services/FakeProductService.java new file mode 100644 index 0000000..7209941 --- /dev/null +++ b/src/main/java/dev/naman/productservice/services/FakeProductService.java @@ -0,0 +1,18 @@ +package dev.naman.productservice.services; + +import dev.naman.productservice.dtos.GenericProductDto; +import dev.naman.productservice.exceptions.NotFoundException; + +import java.util.List; +import java.util.UUID; + +public interface FakeProductService { + + GenericProductDto createProduct(GenericProductDto product); + + GenericProductDto getProductById(Long id) throws NotFoundException; + + List getAllProducts(); + + GenericProductDto deleteProduct(Long id); +} diff --git a/src/main/java/dev/naman/productservice/services/ProductService.java b/src/main/java/dev/naman/productservice/services/ProductService.java index bc5eb10..f313781 100644 --- a/src/main/java/dev/naman/productservice/services/ProductService.java +++ b/src/main/java/dev/naman/productservice/services/ProductService.java @@ -1,17 +1,22 @@ package dev.naman.productservice.services; import dev.naman.productservice.dtos.GenericProductDto; +import dev.naman.productservice.dtos.ProductDto; import dev.naman.productservice.exceptions.NotFoundException; +import dev.naman.productservice.models.Product; import java.util.List; +import java.util.UUID; public interface ProductService { - GenericProductDto createProduct(GenericProductDto product); + ProductDto createProduct(Product product); - GenericProductDto getProductById(Long id) throws NotFoundException; + ProductDto getProductById(String id) throws NotFoundException; + List getProductsInCategory(String id) throws NotFoundException; - List getAllProducts(); + List getAllProducts(List categories); - GenericProductDto deleteProduct(Long id); + ProductDto deleteProduct(String id); + ProductDto updateProduct(ProductDto productDto,String id); } diff --git a/src/main/java/dev/naman/productservice/services/SelfProductServiceImpl.java b/src/main/java/dev/naman/productservice/services/SelfProductServiceImpl.java index 260a45b..c03ed34 100644 --- a/src/main/java/dev/naman/productservice/services/SelfProductServiceImpl.java +++ b/src/main/java/dev/naman/productservice/services/SelfProductServiceImpl.java @@ -1,39 +1,134 @@ package dev.naman.productservice.services; import dev.naman.productservice.dtos.GenericProductDto; +import dev.naman.productservice.dtos.ProductDto; +import dev.naman.productservice.exceptions.NotFoundException; +import dev.naman.productservice.models.Category; import dev.naman.productservice.models.Product; +import dev.naman.productservice.repositories.CategoryRepository; import dev.naman.productservice.repositories.ProductRepository; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.CancellationException; @Primary @Service("selfProductServiceImpl") public class SelfProductServiceImpl implements ProductService { private ProductRepository productRepository; + private CategoryRepository categoryRepository; public SelfProductServiceImpl(ProductRepository productRepository) { this.productRepository = productRepository; } @Override - public GenericProductDto getProductById(Long id) { - return null; + public ProductDto getProductById(String id) { + Optional product = productRepository.findById(UUID.fromString(id)); + if(product.isEmpty()) + throw new RuntimeException(); + Product prod = product.get(); + ProductDto productDto = new ProductDto(); + productDto.setTitle(prod.getTitle()); + productDto.setDescription(prod.getDescription()); + productDto.setPrice(prod.getPrice()); + productDto.setImage(prod.getImage()); + return productDto; } @Override - public GenericProductDto createProduct(GenericProductDto product) { - return null; + public List getProductsInCategory(String categoryid) throws NotFoundException { + Optional optionalCategory = categoryRepository.findById(UUID.fromString(categoryid)); + if(optionalCategory.isEmpty()) + throw new RuntimeException(); + Category category = optionalCategory.get(); + List products = category.getProducts(); + List productDTOs = new ArrayList<>(); + for(Product product:products){ + ProductDto productDto = new ProductDto(); + productDto.setTitle(product.getTitle()); + productDto.setDescription(product.getDescription()); + productDto.setPrice(product.getPrice()); + productDto.setImage(product.getImage()); + productDTOs.add(productDto); + } + return productDTOs; } @Override - public List getAllProducts() { - return null; + public ProductDto createProduct(Product product) { + Product newProduct = new Product(); + newProduct.setTitle(product.getTitle()); + newProduct.setDescription(product.getDescription()); + newProduct.setImage(product.getImage()); + newProduct.setPrice(product.getPrice()); + Category category = product.getCategory(); + newProduct.setCategory(category); + Product savedProduct = productRepository.save(newProduct); + ProductDto newProductDto = new ProductDto(); + newProductDto.setTitle(savedProduct.getTitle()); + newProductDto.setDescription(savedProduct.getDescription()); + newProductDto.setImage(savedProduct.getImage()); + newProductDto.setPrice(savedProduct.getPrice()); + return newProductDto; } @Override - public GenericProductDto deleteProduct(Long id) { - return null; + public List getAllProducts(List categoryUUIDs) { + List uuids = new ArrayList<>(); + for(String categoryId:categoryUUIDs){ + uuids.add(UUID.fromString(categoryId)); + } + List categories = categoryRepository.findAllById(uuids); + List products = productRepository.findAllByCategoryIn(categories); + List productDtos = new ArrayList<>(); + for(Product product:products){ + ProductDto productDto = new ProductDto(); + productDto.setTitle(product.getTitle()); + productDto.setImage(product.getImage()); + productDto.setDescription(product.getDescription()); + productDto.setPrice(product.getPrice()); + productDtos.add(productDto); + } + return productDtos; + } + + @Override + public ProductDto deleteProduct(String id) { + Optional optionalProduct = productRepository.findById(UUID.fromString(id)); + if(optionalProduct.isEmpty()) + throw new RuntimeException(); + Product product = optionalProduct.get(); + //Product Details to Return + ProductDto productDto = new ProductDto(); + productDto.setTitle(product.getTitle()); + productDto.setDescription(product.getDescription()); + productDto.setImage(product.getImage()); + productDto.setPrice(product.getPrice()); + productRepository.delete(product); + return productDto; + } + + @Override + public ProductDto updateProduct(ProductDto productDto, String id) { + Optional optionalProduct = productRepository.findById(UUID.fromString(id)); + if(optionalProduct.isEmpty()) + throw new RuntimeException(); + Product product = optionalProduct.get(); + product.setTitle(productDto.getTitle()); + product.setDescription(productDto.getDescription()); + product.setImage(productDto.getImage()); + product.setPrice(productDto.getPrice()); + Product savedProduct = productRepository.save(product); + ProductDto newProductDto = new ProductDto(); + newProductDto.setTitle(savedProduct.getTitle()); + newProductDto.setDescription(savedProduct.getDescription()); + newProductDto.setImage(savedProduct.getImage()); + newProductDto.setPrice(savedProduct.getPrice()); + return newProductDto; } } From f8eb2c94f951ef7237ed5ba367c1e0554e61cebb Mon Sep 17 00:00:00 2001 From: AbhishekT Date: Tue, 26 Sep 2023 00:06:47 +0530 Subject: [PATCH 2/3] Added 7 APIs --- .../naman/productservice/services/FakeStoreProductService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/dev/naman/productservice/services/FakeStoreProductService.java b/src/main/java/dev/naman/productservice/services/FakeStoreProductService.java index ceb58af..0502202 100644 --- a/src/main/java/dev/naman/productservice/services/FakeStoreProductService.java +++ b/src/main/java/dev/naman/productservice/services/FakeStoreProductService.java @@ -14,7 +14,7 @@ @Repository("fakeStoreProductService") -public class FakeStoreProductService implements ProductService { +public class FakeStoreProductService implements FakeProductService { private FakeStoryProductServiceClient fakeStoryProductServiceClient; From 27bd032fbf4e67f655329bf7cda9ef7706941895 Mon Sep 17 00:00:00 2001 From: AbhishekT Date: Tue, 26 Sep 2023 10:21:46 +0530 Subject: [PATCH 3/3] Changed Fetch Type to Eager for Product->Price --- .../naman/productservice/controllers/CategoryController.java | 1 - src/main/java/dev/naman/productservice/models/Product.java | 2 +- .../naman/productservice/services/CategoryServiceImpl.java | 2 +- .../productservice/services/SelfProductServiceImpl.java | 5 +++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/dev/naman/productservice/controllers/CategoryController.java b/src/main/java/dev/naman/productservice/controllers/CategoryController.java index b38994e..0720f0c 100644 --- a/src/main/java/dev/naman/productservice/controllers/CategoryController.java +++ b/src/main/java/dev/naman/productservice/controllers/CategoryController.java @@ -34,7 +34,6 @@ public List getCategory(@PathVariable("uuid") String uuid) { productDto.setImage(product.getImage()); productDto.setPrice(product.getPrice()); productDtos.add(productDto); -// productDto.se } return productDtos; diff --git a/src/main/java/dev/naman/productservice/models/Product.java b/src/main/java/dev/naman/productservice/models/Product.java index 7678e1f..be12ffe 100644 --- a/src/main/java/dev/naman/productservice/models/Product.java +++ b/src/main/java/dev/naman/productservice/models/Product.java @@ -26,7 +26,7 @@ public class Product extends BaseModel { @JoinColumn(name = "category") private Category category; - @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY) + @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}) // @Fetch(FetchMode.JOIN) private Price price; } diff --git a/src/main/java/dev/naman/productservice/services/CategoryServiceImpl.java b/src/main/java/dev/naman/productservice/services/CategoryServiceImpl.java index 5235d3b..3d93b4c 100644 --- a/src/main/java/dev/naman/productservice/services/CategoryServiceImpl.java +++ b/src/main/java/dev/naman/productservice/services/CategoryServiceImpl.java @@ -6,6 +6,7 @@ import dev.naman.productservice.models.Product; import dev.naman.productservice.repositories.CategoryRepository; import dev.naman.productservice.repositories.ProductRepository; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestBody; @@ -18,7 +19,6 @@ public class CategoryServiceImpl implements CategoryService { private CategoryRepository categoryRepository; private final ProductRepository productRepository; - public CategoryServiceImpl(CategoryRepository categoryRepository, ProductRepository productRepository) { this.categoryRepository = categoryRepository; diff --git a/src/main/java/dev/naman/productservice/services/SelfProductServiceImpl.java b/src/main/java/dev/naman/productservice/services/SelfProductServiceImpl.java index c03ed34..6138de8 100644 --- a/src/main/java/dev/naman/productservice/services/SelfProductServiceImpl.java +++ b/src/main/java/dev/naman/productservice/services/SelfProductServiceImpl.java @@ -14,7 +14,6 @@ import java.util.List; import java.util.Optional; import java.util.UUID; -import java.util.concurrent.CancellationException; @Primary @Service("selfProductServiceImpl") @@ -22,8 +21,9 @@ public class SelfProductServiceImpl implements ProductService { private ProductRepository productRepository; private CategoryRepository categoryRepository; - public SelfProductServiceImpl(ProductRepository productRepository) { + public SelfProductServiceImpl(ProductRepository productRepository,CategoryRepository categoryRepository) { this.productRepository = productRepository; + this.categoryRepository = categoryRepository; } @Override @@ -32,6 +32,7 @@ public ProductDto getProductById(String id) { if(product.isEmpty()) throw new RuntimeException(); Product prod = product.get(); + prod.getPrice();//Needed coz of lazy loading ProductDto productDto = new ProductDto(); productDto.setTitle(prod.getTitle()); productDto.setDescription(prod.getDescription());