Commit 5e67d4ed authored by Tejas Sharma's avatar Tejas Sharma

implemented mapstruct, internalization and parallel/sequential req res...

implemented mapstruct, internalization and parallel/sequential req res mechanism in inventory service
parent 41ab3dda
......@@ -59,5 +59,52 @@
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct-processor -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.5.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>3.4.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<source>17</source> <!-- Set this according to your JDK version -->
<target>17</target>
<compilerArgument>-parameters</compilerArgument>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version> <!-- Ensure this is the same as above -->
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
package org.nisum.config;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MessageConfig implements WebMvcConfigurer {
public MessageSource messageSource(){
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath::messages"); //base name for messages file
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
}
package org.nisum.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
@Configuration
public class WebClientConfig {
@Bean
public WebClient.Builder webClientBuilder(){
return WebClient.builder();
}
}
package org.nisum.controller;
import org.nisum.dto.InventoryDTO;
import org.nisum.model.Inventory;
import org.nisum.service.InventoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Locale;
@RestController
@RequestMapping("/inventory")
public class InventoryController {
@Autowired
private InventoryService inventoryService;
@Autowired
private MessageSource messageSource;
@PostMapping("/create")
public Mono<Inventory> AddProductToInventory(@RequestBody Inventory inventory){
return inventoryService.createInventory(inventory);
public Mono<ResponseEntity<String>> AddProductToInventory(@RequestBody InventoryDTO inventoryDTO, Locale locale){
return inventoryService.createInventory(inventoryDTO)
.map(savedInventory -> ResponseEntity.status(HttpStatus.CREATED)
.body(messageSource.getMessage("inventory.created.success",new Object[]{},locale)))
.defaultIfEmpty(ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(messageSource.getMessage("inventory.invalid.data",new Object[]{},locale)));
}
@GetMapping("/check/{productId}/{quantity}")
......@@ -24,5 +39,24 @@ public class InventoryController {
return inventoryService.checkProductAvailability(productId,quantity);
}
// http://localhost:8082/inventory/allRecords
@GetMapping("/allRecords")
public Flux<InventoryDTO> getAllInventories(){
return inventoryService.getAllInventories();
}
@GetMapping("/sequential")
public Mono<List<String>> getSequentialInventoryDetails() {
return inventoryService.getSequentialInventoryDetails();
}
@GetMapping("/sequential1")
public Mono<List<String>> getSequentialInventoryDetails1() {
return inventoryService.getSequentialInventoryDetails();
}
@GetMapping("/parallel")
public Mono<List<String>> getParallelInventoryDetails() {
return inventoryService.getParallelInventoryDetails();
}
}
package org.nisum.dto;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class InventoryDTO {
private String id;
private String productId;
private boolean inStock;
private int quantity;
private LocalDateTime timeStamp;
}
package org.nisum.mapper;
import org.mapstruct.Mapper;
import org.nisum.dto.InventoryDTO;
import org.nisum.model.Inventory;
@Mapper(componentModel = "spring")
public interface InventoryMapper {
Inventory toInventory(InventoryDTO inventoryDTO);
InventoryDTO toInventoryDTO(Inventory inventory);
}
......@@ -3,10 +3,9 @@ package org.nisum.repository;
import org.nisum.model.Inventory;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
import reactor.core.publisher.Flux;
@Repository
public interface InventoryRepository extends ReactiveMongoRepository<Inventory,String> {
Optional<Inventory> findByProductId(String productId);
Flux<Inventory> findByProductId(String productId);
}
package org.nisum.service;
import org.nisum.dto.InventoryDTO;
import org.nisum.mapper.InventoryMapper;
import org.nisum.model.Inventory;
import org.nisum.repository.InventoryRepository;
import org.slf4j.Logger;
......@@ -7,37 +9,118 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
@Service
public class InventoryService {
private final InventoryMapper inventoryMapper;
@Autowired
private InventoryRepository inventoryRepository;
@Autowired
private WebClient.Builder webClientBuilder;
Boolean status;
public static final Logger log = LoggerFactory.getLogger(InventoryService.class);
public Mono<Inventory> createInventory(Inventory inventory) {
@Autowired
public InventoryService(InventoryMapper inventoryMapper) {
this.inventoryMapper = inventoryMapper;
}
public InventoryDTO getInventoryDTO(Inventory inventory){
return inventoryMapper.toInventoryDTO(inventory);
}
public Inventory getInventory(InventoryDTO inventoryDTO){
return inventoryMapper.toInventory(inventoryDTO);
}
public Mono<InventoryDTO> createInventory(InventoryDTO inventoryDTO) {
Inventory inventory = inventoryMapper.toInventory(inventoryDTO);
inventory.setTimeStamp(LocalDateTime.now());
inventory.setInStock(true);
return inventoryRepository.save(inventory).doOnSuccess(inventory1 -> {
log.info("product with product id: "+inventory1.getProductId() + " added successfully to the inventory");
});
return Mono.just(inventory).flatMap(inventoryRepository::save)
.map(inventoryMapper::toInventoryDTO).doOnSuccess(inventoryDTO1 -> {
log.info("product with product id: "+inventoryDTO1.getProductId() + " added successfully to the inventory");
});
}
public Flux<InventoryDTO> getAllInventories(){
Flux<Inventory> inventoryFlux = inventoryRepository.findAll();
return inventoryFlux.map(inventoryMapper::toInventoryDTO);
}
public ResponseEntity<Boolean> checkProductAvailability(String productId, int requiredQuantity){
Inventory inventory = inventoryRepository.findByProductId(productId).orElse(null);
Flux<Inventory> inventory = inventoryRepository.findByProductId(productId);
inventory.subscribe(inventory1 -> {
log.info(inventory1.getProductId() + " : " + inventory1.getQuantity());
log.info(String.valueOf(requiredQuantity));
if(inventory1 != null){
log.info("inside not null");
if(inventory != null){
if(inventory.getQuantity() >= requiredQuantity){
return ResponseEntity.ok(true);
}else{
return ResponseEntity.ok(false);
if(inventory1.getQuantity() >= requiredQuantity){
log.info("inside true");
status = true;
}else{
status = false;
}
}else {
log.info("inside false");
status = false;
}
}else {
return ResponseEntity.ok(false);
}
});
log.info(String.valueOf(status));
return ResponseEntity.ok(status);
}
//sequential request-response model
public Mono<List<String>> getSequentialInventoryDetails(){
return webClientBuilder.baseUrl("https://dummyjson.com")
.build()
.get()
.uri("/products/1")
.retrieve()
.bodyToMono(String.class)
.flatMap(s ->
webClientBuilder.baseUrl("https://dummyjson.com")
.build()
.get()
.uri("/products/2")
.retrieve()
.bodyToMono(String.class)
.map(s1 -> List.of(s,s1)));
}
//parallel request response model
public Mono<List<String>> getParallelInventoryDetails(){
Mono<String> product1 =webClientBuilder.baseUrl("https://dummyjson.com")
.build()
.get()
.uri("/products/1")
.retrieve()
.bodyToMono(String.class);
Mono<String> product2 =webClientBuilder.baseUrl("https://dummyjson.com")
.build()
.get()
.uri("/products/2")
.retrieve()
.bodyToMono(String.class);
return Mono.zip(product1,product2)
.map(objects -> List.of(objects.getT1(),objects.getT2()));
}
}
......@@ -3,4 +3,10 @@ server:
spring:
data:
mongodb:
uri: mongodb://localhost:27017/inventory_db
\ No newline at end of file
uri: mongodb://localhost:27017/inventory_db
messages:
basename: messages
cache-duration: 3600
mvc:
locale: en #Points to the base name of the message files. In this case, we use messages.properties, messages_en.properties, etc.
locale-resolver: accept-header #We are using the AcceptHeaderLocaleResolver that will automatically resolve the locale based on the Accept-Language header in the HTTP request.
inventory.created.success=Inventory created successfully!
inventory.all.retrieved=All inventories retrieved successfully!
inventory.invalid.data=Invalid data provided!
\ No newline at end of file
inventory.created.success=¡Inventario creado con éxito!
inventory.all.retrieved=¡Todos los inventarios recuperados con éxito!
inventory.invalid.data=¡Datos proporcionados no válidos!
\ No newline at end of file
......@@ -68,6 +68,28 @@
<artifactId>slf4j-api</artifactId>
<version>2.0.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct-processor -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.5.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
......@@ -81,7 +103,16 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<source>17</source> <!-- Set this according to your JDK version -->
<target>17</target>
<compilerArgument>-parameters</compilerArgument>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version> <!-- Ensure this is the same as above -->
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
......
......@@ -38,19 +38,21 @@ public class OrderService {
}
public Mono<String> placeOrder(String productId, int quantity){
return checkProductAvailability(productId, quantity)
.flatMap(isAvailable -> {
if(isAvailable){
return createOrder(productId,quantity);
}
return Mono.just("Product is out of stock or insufficient quantity.");
});
log.info(String.valueOf(checkProductAvailability(productId,quantity)));
return Mono.just("Something");
// return checkProductAvailability(productId, quantity)
// .flatMap(isAvailable -> {
// if(isAvailable){
// return createOrder(productId,quantity);
// }
// return Mono.just("Product is out of stock or insufficient quantity.");
// });
}
private Mono<Boolean> checkProductAvailability(String productId, int quantity){
return webClient.get()
.uri("/check/{productId}/{quantity}")
.uri("/check/{'"+productId+"'}/{'"+quantity+"'}")
.retrieve()
.bodyToMono(Boolean.class);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment