properties files uncommited stuff
This commit is contained in:
parent
a6a6e22eb2
commit
0a77989b9b
@ -35,7 +35,17 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>io.zipkin.reporter2</groupId>
|
||||
<artifactId>zipkin-reporter-brave</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-tracing-bridge-brave</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -39,5 +39,7 @@ spring.security.oauth2.resourceserver.jwt.issuer-uri= http://localhost:8181/real
|
||||
#spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8181/realms/spring-boot-microservices-realm
|
||||
|
||||
#tracing
|
||||
#tracing
|
||||
logging.pattern.level: "%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]"
|
||||
management.zipkin.tracing.endpoint=http://localhost:9411/api/v2/spans
|
||||
spring.management.tracing.sampling.probability=1.0
|
||||
management.tracing.sampling.probability=1.0
|
||||
@ -28,6 +28,15 @@
|
||||
<groupId>io.zipkin.reporter2</groupId>
|
||||
<artifactId>zipkin-reporter-brave</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -23,4 +23,9 @@ eureka.client.proxyHost=eureka
|
||||
eureka.client.proxyPort=password
|
||||
|
||||
|
||||
|
||||
|
||||
#tracing
|
||||
logging.pattern.level: "%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]"
|
||||
management.zipkin.tracing.endpoint=http://localhost:9411/api/v2/spans
|
||||
management.tracing.sampling.probability=1.0
|
||||
@ -1,26 +1,42 @@
|
||||
---
|
||||
version: '3'
|
||||
services:
|
||||
zookeeper:
|
||||
image: confluentinc/cp-zookeeper:7.3.0
|
||||
hostname: zookeeper
|
||||
container_name: zookeeper
|
||||
environment:
|
||||
ZOOKEEPER_CLIENT_PORT: 2181
|
||||
ZOOKEEPER_TICK_TIME: 2000
|
||||
|
||||
broker:
|
||||
image: confluentinc/cp-kafka:7.3.0
|
||||
container_name: broker
|
||||
ports:
|
||||
- "9092:9092"
|
||||
depends_on:
|
||||
- zookeeper
|
||||
environment:
|
||||
KAFKA_BROKER_ID: 1
|
||||
KAFKA_ZOOKEEPER_CONNECT: 'zookeeper:2181'
|
||||
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_INTERNAL:PLAINTEXT
|
||||
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092,PLAINTEXT_INTERNAL://broker:29092
|
||||
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
|
||||
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
|
||||
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
|
||||
postgres-order:
|
||||
container_name: postgres-order
|
||||
image: postgres
|
||||
environment:
|
||||
POSTGRES_DB: order-service
|
||||
POSTGRES_USER: foo
|
||||
POSTGRES_PASSWORD: bar
|
||||
PGDATA: /data/postgres
|
||||
volumes:
|
||||
- ./postgres-order:/data/postgres
|
||||
expose:
|
||||
- "5431"
|
||||
ports:
|
||||
- "5431:5431"
|
||||
command: -p 5431
|
||||
restart: unless-stopped
|
||||
|
||||
postgres-inventory:
|
||||
container_name: postgres-inventory
|
||||
image: postgres
|
||||
environment:
|
||||
POSTGRES_DB: inventory-service
|
||||
POSTGRES_USER: foo
|
||||
POSTGRES_PASSWORD: bar
|
||||
PGDATA: /data/postgres
|
||||
volumes:
|
||||
- ./postgres-order:/data/postgres
|
||||
ports:
|
||||
- "5432:5432"
|
||||
restart: unless-stopped
|
||||
|
||||
mongo:
|
||||
container_name: mongo
|
||||
image: mongo:4.4.14-rc0-focal
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "27017:27017"
|
||||
volumes:
|
||||
- ./mongo-data:/data/db
|
||||
26
docker-compose_kafka.yml
Normal file
26
docker-compose_kafka.yml
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
version: '3'
|
||||
services:
|
||||
zookeeper:
|
||||
image: confluentinc/cp-zookeeper:7.3.0
|
||||
hostname: zookeeper
|
||||
container_name: zookeeper
|
||||
environment:
|
||||
ZOOKEEPER_CLIENT_PORT: 2181
|
||||
ZOOKEEPER_TICK_TIME: 2000
|
||||
|
||||
broker:
|
||||
image: confluentinc/cp-kafka:7.3.0
|
||||
container_name: broker
|
||||
ports:
|
||||
- "9092:9092"
|
||||
depends_on:
|
||||
- zookeeper
|
||||
environment:
|
||||
KAFKA_BROKER_ID: 1
|
||||
KAFKA_ZOOKEEPER_CONNECT: 'zookeeper:2181'
|
||||
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_INTERNAL:PLAINTEXT
|
||||
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092,PLAINTEXT_INTERNAL://broker:29092
|
||||
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
|
||||
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
|
||||
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
|
||||
@ -10,9 +10,9 @@
|
||||
<artifactId>inventory-service-mv</artifactId>
|
||||
<properties>
|
||||
|
||||
|
||||
<maven.compiler.source>20</maven.compiler.source>
|
||||
<maven.compiler.target>20</maven.compiler.target>
|
||||
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@ -43,5 +43,22 @@
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-tracing-bridge-brave</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.zipkin.reporter2</groupId>
|
||||
<artifactId>zipkin-reporter-brave</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-registry-prometheus</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -29,9 +29,13 @@ public class InventoryService {
|
||||
// Thread.sleep(10000);
|
||||
// log.info("Wait ended");
|
||||
// System.out.println(inventoryRepository.findBySkuCodeIn(skuCode).size());
|
||||
return inventoryRepository.findBySkuCodeIn(skuCode).stream().map(
|
||||
inv -> InventoryResponse.builder().skuCode(inv.getSkuCode()).isInStock(inv.getQuantity() > 0).build())
|
||||
.toList();
|
||||
return inventoryRepository.findBySkuCodeIn(skuCode).stream()
|
||||
.map(inventory ->
|
||||
InventoryResponse.builder()
|
||||
.skuCode(inventory.getSkuCode())
|
||||
.isInStock(inventory.getQuantity() > 0)
|
||||
.build()
|
||||
).toList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/inventory-service?useSSL=false
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=nEFK0Nu7OLW78NZl4VJj
|
||||
spring.datasource.password=REDACTED
|
||||
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
|
||||
|
||||
|
||||
@ -10,12 +10,18 @@ spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
|
||||
# TODO
|
||||
spring.jpa.hibernate.ddl-auto=create-drop
|
||||
#spring.jpa.hibernate.ddl-auto=update
|
||||
#logging.level.org.springframework.web: DEBUG
|
||||
#logging.level.org.hibernate: DEBUG
|
||||
logging.level.org.springframework.web: TRACE
|
||||
logging.level.org.hibernate: TRACE
|
||||
|
||||
# assign random port i.e. allow multiple parallel instances
|
||||
server.port=0
|
||||
|
||||
spring.application.name=inventory-service
|
||||
#eureka.client.serviceUrl.defaultZone=http://localhost:8763/eureka
|
||||
eureka.client.serviceUrl.defaultZone=http://eureka:password@localhost:8761/eureka
|
||||
eureka.client.serviceUrl.defaultZone=http://eureka:password@localhost:8761/eureka
|
||||
|
||||
#tracing
|
||||
#tracing
|
||||
logging.pattern.level: "%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]"
|
||||
management.zipkin.tracing.endpoint=http://localhost:9411/api/v2/spans
|
||||
management.tracing.sampling.probability=1.0
|
||||
@ -1,59 +1,78 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.shop</groupId>
|
||||
<artifactId>parent-service-new</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>notification-servicce</artifactId>
|
||||
<name>notification-service</name>
|
||||
<description>Notification Service</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.kafka</groupId>
|
||||
<artifactId>spring-kafka</artifactId>
|
||||
</dependency>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.shop</groupId>
|
||||
<artifactId>parent-service-new</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>notification-servicce</artifactId>
|
||||
<name>notification-service</name>
|
||||
<description>Notification Service</description>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.kafka</groupId>
|
||||
<artifactId>spring-kafka-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.kafka</groupId>
|
||||
<artifactId>spring-kafka</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.kafka</groupId>
|
||||
<artifactId>spring-kafka-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-tracing-bridge-brave</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.zipkin.reporter2</groupId>
|
||||
<artifactId>zipkin-reporter-brave</artifactId>
|
||||
</dependency>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-registry-prometheus</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@ -15,5 +15,6 @@ spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.seria
|
||||
spring.kafka.consumer.properties.spring.json.type.mapping=event:com.shop.OrderPlacedEvent
|
||||
|
||||
#tracing
|
||||
logging.pattern.level: "%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]"
|
||||
management.zipkin.tracing.endpoint=http://localhost:9411/api/v2/spans
|
||||
spring.management.tracing.sampling.probability=1.0
|
||||
management.tracing.sampling.probability=1.0
|
||||
@ -59,5 +59,26 @@
|
||||
<groupId>org.springframework.kafka</groupId>
|
||||
<artifactId>spring-kafka</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-tracing-bridge-brave</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.zipkin.reporter2</groupId>
|
||||
<artifactId>zipkin-reporter-brave</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-registry-prometheus</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -12,9 +12,6 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import com.shop.orderservice.dto.OrderRequest;
|
||||
import com.shop.orderservice.service.OrderService;
|
||||
|
||||
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
|
||||
import io.github.resilience4j.retry.annotation.Retry;
|
||||
import io.github.resilience4j.timelimiter.annotation.TimeLimiter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RestController
|
||||
@ -26,11 +23,14 @@ public class OrderController {
|
||||
|
||||
@PostMapping
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
@CircuitBreaker(name = "inventory", fallbackMethod = "fallbackMethod")
|
||||
@TimeLimiter(name = "inventory")
|
||||
@Retry(name = "inventory")
|
||||
public CompletableFuture< String > placeOrder(@RequestBody OrderRequest request) {
|
||||
return CompletableFuture.supplyAsync(() -> orderService.placeOrder(request));
|
||||
// @CircuitBreaker(name = "inventory", fallbackMethod = "fallbackMethod")
|
||||
// @TimeLimiter(name = "inventory")
|
||||
// @Retry(name = "inventory")
|
||||
// public CompletableFuture< String > placeOrder(@RequestBody OrderRequest request) {
|
||||
// return CompletableFuture.supplyAsync(() -> orderService.placeOrder(request));
|
||||
// }
|
||||
public String placeOrder(@RequestBody OrderRequest request) {
|
||||
return orderService.placeOrder(request);
|
||||
}
|
||||
|
||||
public CompletableFuture< String > fallbackMethod(OrderRequest request, RuntimeException exception) {
|
||||
|
||||
@ -1,13 +1,24 @@
|
||||
package com.shop.orderservice.event;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class OrderPlacedEvent {
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class OrderPlacedEvent extends ApplicationEvent {
|
||||
private static final long serialVersionUID = -8679697396951042519L;
|
||||
private String orderNumber;
|
||||
|
||||
public OrderPlacedEvent(Object source, String orderNumber) {
|
||||
super(source);
|
||||
this.orderNumber = orderNumber;
|
||||
}
|
||||
|
||||
public OrderPlacedEvent(String orderNumber) {
|
||||
super(orderNumber);
|
||||
this.orderNumber = orderNumber;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
package com.shop.orderservice.listener;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.kafka.support.SendResult;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.shop.orderservice.event.OrderPlacedEvent;
|
||||
|
||||
import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class OrderPlacedEventListener {
|
||||
private final KafkaTemplate<String, OrderPlacedEvent> kafkaTemplate;
|
||||
private final ObservationRegistry observationRegistry;
|
||||
|
||||
@EventListener
|
||||
public void handleOrderPlacedEvent(OrderPlacedEvent event) {
|
||||
log.info("Order Placed Event Received, Sending OrderPlacedEvent to notificationTopic: {}", event.getOrderNumber());
|
||||
|
||||
// Create Observation for Kafka Template
|
||||
try {
|
||||
Observation.createNotStarted("notification-topic", this.observationRegistry).observeChecked(() -> {
|
||||
CompletableFuture<SendResult<String, OrderPlacedEvent>> future = kafkaTemplate.send("notificationTopic",
|
||||
new OrderPlacedEvent(event.getOrderNumber()));
|
||||
return future.handle((result, throwable) -> CompletableFuture.completedFuture(result));
|
||||
}).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RuntimeException("Error while sending message to Kafka", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,8 @@ import com.shop.orderservice.model.Order;
|
||||
@Service
|
||||
public interface OrderRepository extends JpaRepository<Order, Long> {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked") // super method is for <T extends Order>
|
||||
public Order save(Order order);
|
||||
|
||||
}
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
package com.shop.orderservice.service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -19,44 +18,66 @@ import com.shop.orderservice.model.Order;
|
||||
import com.shop.orderservice.model.OrderLineItems;
|
||||
import com.shop.orderservice.repository.OrderRepository;
|
||||
|
||||
import io.micrometer.observation.Observation;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional
|
||||
@Slf4j
|
||||
public class OrderService {
|
||||
|
||||
private final OrderRepository orderRepository;
|
||||
private final WebClient.Builder webClientBuilder;
|
||||
private final ObservationRegistry observationRegistry;
|
||||
private final ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
private final KafkaTemplate<String, OrderPlacedEvent> kafkaTemplate;
|
||||
|
||||
public String placeOrder(OrderRequest orderRequest) {
|
||||
Order order = new Order();
|
||||
order.setOrderNumber(UUID.randomUUID().toString());
|
||||
public String placeOrder(OrderRequest orderRequest) {
|
||||
Order order = new Order();
|
||||
order.setOrderNumber(UUID.randomUUID().toString());
|
||||
|
||||
List<OrderLineItems> orderLineItems = orderRequest.getOrderLineItemsDtoList().stream().map(this::mapToDto)
|
||||
.toList();
|
||||
order.setItems(orderLineItems);
|
||||
// call inventory
|
||||
List<String> skuCodes = order.getItems().stream().map(OrderLineItems::getSkuCode).toList();
|
||||
Map<String, List<String>> skus = new HashMap<>();
|
||||
skus.put("skuCode", skuCodes);
|
||||
InventoryResponse[] inventoryResponseArray = webClientBuilder.build().get()
|
||||
.uri("http://inventory-service/api/inventory",
|
||||
uriBuilder -> uriBuilder.queryParam("skuCode", skuCodes).build())
|
||||
.retrieve().bodyToMono(InventoryResponse[].class).block();
|
||||
List<OrderLineItems> orderLineItems = orderRequest.getOrderLineItemsDtoList()
|
||||
.stream()
|
||||
.map(this::mapToDto)
|
||||
.toList();
|
||||
|
||||
Boolean allProductsInStock = Arrays.stream(inventoryResponseArray).allMatch(InventoryResponse::isInStock);
|
||||
order.setItems(orderLineItems);
|
||||
|
||||
if (allProductsInStock) {
|
||||
orderRepository.save(order);
|
||||
kafkaTemplate.send("notificationTopic", new OrderPlacedEvent(order.getOrderNumber()) );
|
||||
return "Order placed successfully";
|
||||
} else {
|
||||
throw new IllegalArgumentException("not in stock");
|
||||
}
|
||||
}
|
||||
List<String> skuCodes = order.getItems().stream()
|
||||
.map(OrderLineItems::getSkuCode)
|
||||
.toList();
|
||||
|
||||
// Call Inventory Service, and place order if product is in
|
||||
// stock
|
||||
Observation inventoryServiceObservation = Observation.createNotStarted("inventory-service-lookup",
|
||||
this.observationRegistry);
|
||||
inventoryServiceObservation.lowCardinalityKeyValue("call", "inventory-service");
|
||||
return inventoryServiceObservation.observe(() -> {
|
||||
InventoryResponse[] inventoryResponseArray = webClientBuilder.build().get()
|
||||
.uri("http://inventory-service/api/inventory",
|
||||
uriBuilder -> uriBuilder.queryParam("skuCode", skuCodes).build())
|
||||
.retrieve()
|
||||
.bodyToMono(InventoryResponse[].class)
|
||||
.block();
|
||||
|
||||
boolean allProductsInStock = Arrays.stream(inventoryResponseArray)
|
||||
.allMatch(InventoryResponse::isInStock);
|
||||
|
||||
if (allProductsInStock) {
|
||||
orderRepository.save(order);
|
||||
// publish Order Placed Event
|
||||
applicationEventPublisher.publishEvent(new OrderPlacedEvent(this, order.getOrderNumber()));
|
||||
return "Order Placed";
|
||||
} else {
|
||||
throw new IllegalArgumentException("Product is not in stock, please try again later");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private OrderLineItems mapToDto(OrderLineItemsDto itemDto) {
|
||||
OrderLineItems item = new OrderLineItems();
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
spring.datasource.url=jdbc:mysql://localhost:3306/order-service?useSSL=false
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=nEFK0Nu7OLW78NZl4VJj
|
||||
spring.datasource.password=REDACTED
|
||||
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
|
||||
|
||||
|
||||
@ -10,8 +10,8 @@ spring.datasource.driver-class-name=com.mysql.jdbc.Driver
|
||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
|
||||
|
||||
spring.jpa.hibernate.ddl-auto=create
|
||||
#logging.level.org.springframework.web: DEBUG
|
||||
#logging.level.org.hibernate: DEBUG
|
||||
logging.level.org.springframework.web: TRACE
|
||||
logging.level.org.hibernate: TRACE
|
||||
|
||||
server.port=8099
|
||||
|
||||
@ -49,5 +49,7 @@ spring.kafka.producer.value-serializer=org.springframework.kafka.support.seriali
|
||||
spring.kafka.producer.properties.spring.json.type.mapping=event:com.shop.orderservice.event.OrderPlacedEvent
|
||||
|
||||
#tracing
|
||||
#tracing
|
||||
logging.pattern.level: "%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]"
|
||||
management.zipkin.tracing.endpoint=http://localhost:9411/api/v2/spans
|
||||
spring.management.tracing.sampling.probability=1.0
|
||||
management.tracing.sampling.probability=1.0
|
||||
2
pom.xml
2
pom.xml
@ -17,7 +17,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<version>3.0.8</version>
|
||||
</parent>
|
||||
<properties>
|
||||
<spring-cloud.version>2022.0.2</spring-cloud.version>
|
||||
|
||||
@ -43,6 +43,23 @@
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-tracing-bridge-brave</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.zipkin.reporter2</groupId>
|
||||
<artifactId>zipkin-reporter-brave</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-registry-prometheus</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -6,4 +6,10 @@ spring.application.name=product-service
|
||||
eureka.client.serviceUrl.defaultZone=http://eureka:password@localhost:8761/eureka
|
||||
|
||||
logging.level.org.springframework.web= TRACE
|
||||
logging.level.org.springframework.cloud.gateway = TRACE
|
||||
logging.level.org.springframework.cloud.gateway = TRACE
|
||||
|
||||
#tracing
|
||||
#tracing
|
||||
logging.pattern.level: "%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]"
|
||||
management.zipkin.tracing.endpoint=http://localhost:9411/api/v2/spans
|
||||
management.tracing.sampling.probability=1.0
|
||||
Loading…
x
Reference in New Issue
Block a user