Skip to content

Commit 1714fad

Browse files
committed
added projects
1 parent a586361 commit 1714fad

File tree

31 files changed

+1051
-0
lines changed

31 files changed

+1051
-0
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Spring Study
2+
3+
## Posts
4+
5+
- [Embracing Virtual Threads](https://spring.io/blog/2022/10/11/embracing-virtual-threads)
6+
- [Initial AOT Support in Spring Framework 6.0.0-M3](https://spring.io/blog/2022/03/22/initial-aot-support-in-spring-framework-6-0-0-m3)
7+
- [Native Support in Spring Boot 3.0.0-M5](https://spring.io/blog/2022/09/26/native-support-in-spring-boot-3-0-0-m5)
8+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.vscode/
2+
target/
3+
*.class
4+
.project
5+
.settings
6+
.classpath
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"orderNumber":11223344,"orderDate":"2019-09-15T13:18:30.044454","sku":"XPTO-1","total":1999}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>org.springframework.boot</groupId>
7+
<artifactId>spring-boot-starter-parent</artifactId>
8+
<version>2.5.13</version>
9+
<relativePath/> <!-- lookup parent from repository -->
10+
</parent>
11+
<groupId>com.github.wesleyegberto.springstudy</groupId>
12+
<artifactId>rabbitmq-version-testing</artifactId>
13+
<version>0.0.1-SNAPSHOT</version>
14+
<name>rabbitmq-version-testing</name>
15+
16+
<properties>
17+
<java.version>11</java.version>
18+
</properties>
19+
20+
<dependencies>
21+
<dependency>
22+
<groupId>org.springframework.boot</groupId>
23+
<artifactId>spring-boot-starter-actuator</artifactId>
24+
</dependency>
25+
<dependency>
26+
<groupId>org.springframework.boot</groupId>
27+
<artifactId>spring-boot-starter-amqp</artifactId>
28+
</dependency>
29+
<dependency>
30+
<groupId>org.springframework.boot</groupId>
31+
<artifactId>spring-boot-starter-web</artifactId>
32+
</dependency>
33+
34+
<!-- https://github.com/Tradeshift/spring-rabbitmq-tuning/wiki -->
35+
<dependency>
36+
<groupId>com.tradeshift</groupId>
37+
<artifactId>spring-rabbitmq-tuning-lib</artifactId>
38+
<version>0.1.5-SNAPSHOT</version>
39+
</dependency>
40+
41+
<dependency>
42+
<groupId>org.springframework.boot</groupId>
43+
<artifactId>spring-boot-devtools</artifactId>
44+
<scope>runtime</scope>
45+
<optional>true</optional>
46+
</dependency>
47+
<dependency>
48+
<groupId>org.springframework.boot</groupId>
49+
<artifactId>spring-boot-starter-test</artifactId>
50+
<scope>test</scope>
51+
</dependency>
52+
</dependencies>
53+
54+
<build>
55+
<plugins>
56+
<plugin>
57+
<groupId>org.springframework.boot</groupId>
58+
<artifactId>spring-boot-maven-plugin</artifactId>
59+
</plugin>
60+
</plugins>
61+
</build>
62+
63+
</project>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env bash
2+
set -e errexit
3+
4+
# can download here: https://rabbitmq.github.io/rabbitmq-perf-test/stable/htmlsingle/
5+
RABBITMQ_PERFTEST=~/dev-tools/perf-tests/rabbitmq-perf-test-2.9.1
6+
7+
# Pre-propulate the queue with 1Mi of messages to test the OrderProcessor throughput
8+
$RABBITMQ_PERFTEST/bin/runjava com.rabbitmq.perf.PerfTest --uri amqp://localhost:5672 \
9+
-y 0 -p \
10+
-s 1000 -C 1000000 \
11+
-u "orders.received" \
12+
-f persistent \
13+
--body order_received.json \
14+
--id "produce-orders-received"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.github.wesleyegberto.springstudy.queueproducer;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.scheduling.annotation.EnableScheduling;
6+
7+
@SpringBootApplication
8+
@EnableScheduling
9+
// When using spring.rabbitmq.enable.custom.autoconfiguration=true this shouldn't be used
10+
//@EnableRabbit
11+
public class QueueProducerApplication {
12+
public static void main(String[] args) {
13+
SpringApplication.run(QueueProducerApplication.class, args);
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.github.wesleyegberto.springstudy.queueproducer.messaging.creation;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.beans.factory.annotation.Value;
7+
import org.springframework.scheduling.annotation.Scheduled;
8+
import org.springframework.stereotype.Component;
9+
10+
import com.github.wesleyegberto.springstudy.queueproducer.model.Order;
11+
import com.github.wesleyegberto.springstudy.queueproducer.model.OrderEvents;
12+
import com.github.wesleyegberto.springstudy.queueproducer.model.OrderSerializer;
13+
import com.tradeshift.amqp.rabbit.handlers.RabbitTemplateHandler;
14+
15+
@Component
16+
class OrderCreator {
17+
private static final Logger LOG = LoggerFactory.getLogger(OrderCreator.class);
18+
19+
@Value("${spring.rabbitmq.custom.order-received.exchange}")
20+
private String exchange;
21+
@Value("${spring.rabbitmq.custom.order-received.queueRoutingKey}")
22+
private String routingKey;
23+
24+
@Autowired
25+
private OrderNumberGenerator numberGenerator;
26+
27+
@Autowired
28+
private RabbitTemplateHandler rabbitTemplateHandler;
29+
@Autowired
30+
private OrderSerializer orderSerializer;
31+
32+
@Scheduled(cron = "*/1 * * * * *")
33+
public void createOrder() {
34+
LOG.info("Generating new order");
35+
var order = new Order(numberGenerator.generateOrderNumber(), 1999);
36+
37+
sendReceivedOrder(order);
38+
}
39+
40+
private void sendReceivedOrder(Order order) {
41+
var message = orderSerializer.serializeAndCreateMessage(order);
42+
43+
LOG.info("{} - Sending order to processing", order.getOrderNumber());
44+
this.rabbitTemplateHandler.getRabbitTemplate(OrderEvents.RECEIVED)
45+
.send(exchange, routingKey, message);
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.github.wesleyegberto.springstudy.queueproducer.messaging.creation;
2+
3+
import java.security.NoSuchAlgorithmException;
4+
import java.security.SecureRandom;
5+
6+
import org.springframework.stereotype.Component;
7+
8+
@Component
9+
public class OrderNumberGenerator {
10+
private SecureRandom RANDOM;
11+
12+
public OrderNumberGenerator() {
13+
try {
14+
RANDOM = SecureRandom.getInstance("SHA1PRNG");
15+
} catch (NoSuchAlgorithmException e) {
16+
}
17+
if (RANDOM == null) {
18+
try {
19+
RANDOM = SecureRandom.getInstanceStrong();
20+
} catch (NoSuchAlgorithmException e1) {
21+
}
22+
}
23+
}
24+
25+
public int generateOrderNumber() {
26+
return Math.abs(RANDOM.nextInt());
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.github.wesleyegberto.springstudy.queueproducer.messaging.invoicing;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
import org.springframework.amqp.core.Message;
6+
import org.springframework.amqp.core.MessageListener;
7+
import org.springframework.amqp.rabbit.annotation.RabbitListener;
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.beans.factory.annotation.Value;
10+
import org.springframework.stereotype.Component;
11+
12+
import com.github.wesleyegberto.springstudy.queueproducer.model.Order;
13+
import com.github.wesleyegberto.springstudy.queueproducer.model.OrderEvents;
14+
import com.github.wesleyegberto.springstudy.queueproducer.model.OrderSerializer;
15+
import com.tradeshift.amqp.annotation.EnableRabbitRetryAndDlq;
16+
import com.tradeshift.amqp.rabbit.handlers.RabbitTemplateHandler;
17+
18+
@Component
19+
public class OrderInvoicer implements MessageListener {
20+
private static final Logger LOG = LoggerFactory.getLogger(OrderInvoicer.class);
21+
22+
@Value("${spring.rabbitmq.custom.order-invoiced.exchange}")
23+
private String exchange;
24+
@Value("${spring.rabbitmq.custom.order-invoiced.queueRoutingKey}")
25+
private String routingKey;
26+
27+
@Autowired
28+
private OrderSerializer orderSerializer;
29+
@Autowired
30+
private RabbitTemplateHandler rabbitTemplateHandler;
31+
32+
@RabbitListener(containerFactory = OrderEvents.PROCESSED, queues = "${spring.rabbitmq.custom.order-processed.queue}")
33+
@EnableRabbitRetryAndDlq(event = OrderEvents.PROCESSED)
34+
public void onMessage(Message message) {
35+
LOG.info("Received message");
36+
37+
var order = orderSerializer.deserialize(message);
38+
if (order == null) {
39+
return;
40+
}
41+
42+
process(order);
43+
sendProcessedOrder(order);
44+
}
45+
46+
private void process(Order order) {
47+
LOG.info("{} - Invoicing order", order.getOrderNumber());
48+
try {
49+
Thread.sleep(300);
50+
} catch (InterruptedException e) {
51+
}
52+
order.setInvoiced();
53+
}
54+
55+
private void sendProcessedOrder(Order order) {
56+
var message = orderSerializer.serializeAndCreateMessage(order);
57+
58+
LOG.info("{} - Sending order to shipping", order.getOrderNumber());
59+
this.rabbitTemplateHandler.getRabbitTemplate(OrderEvents.INVOICED)
60+
.send(exchange, routingKey, message);
61+
}
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.github.wesleyegberto.springstudy.queueproducer.messaging.processing;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
import org.springframework.amqp.core.Message;
6+
import org.springframework.amqp.core.MessageListener;
7+
import org.springframework.amqp.rabbit.annotation.RabbitListener;
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.beans.factory.annotation.Value;
10+
import org.springframework.stereotype.Component;
11+
12+
import com.github.wesleyegberto.springstudy.queueproducer.model.Order;
13+
import com.github.wesleyegberto.springstudy.queueproducer.model.OrderEvents;
14+
import com.github.wesleyegberto.springstudy.queueproducer.model.OrderSerializer;
15+
import com.tradeshift.amqp.annotation.EnableRabbitRetryAndDlq;
16+
import com.tradeshift.amqp.rabbit.handlers.RabbitTemplateHandler;
17+
18+
@Component
19+
public class OrderProcessor implements MessageListener {
20+
private static final Logger LOG = LoggerFactory.getLogger(OrderProcessor.class);
21+
22+
@Value("${spring.rabbitmq.custom.order-processed.exchange}")
23+
private String exchange;
24+
@Value("${spring.rabbitmq.custom.order-processed.queueRoutingKey}")
25+
private String routingKey;
26+
27+
@Autowired
28+
private OrderSerializer orderSerializer;
29+
@Autowired
30+
private RabbitTemplateHandler rabbitTemplateHandler;
31+
32+
/**
33+
* ACK: {"orderNumber":11223344,"orderDate":"2019-09-15T13:18:30.044454","sku":"XPTO-1","total":1999}
34+
* Retry: {"orderNumber":33445566,"orderDate":"2019-09-15T13:18:30.044454","sku":"XPTO-2","total":1999}
35+
* DLQ: {"orderNumber":44332211,"orderDate":"2019-09-15T13:18:30.044454","sku":"XPTO-0","total":1999}
36+
*/
37+
@RabbitListener(containerFactory = OrderEvents.RECEIVED, queues = "${spring.rabbitmq.custom.order-received.queue}")
38+
@EnableRabbitRetryAndDlq(event = OrderEvents.RECEIVED,
39+
directToDlqWhen = { SkuOutOfStockException.class }
40+
)
41+
public void onMessage(Message message) {
42+
LOG.info("Received message");
43+
44+
var order = orderSerializer.deserialize(message);
45+
if (order == null) {
46+
LOG.info("Order is null");
47+
return;
48+
}
49+
50+
process(order);
51+
sendProcessedOrder(order);
52+
}
53+
54+
private void process(Order order) {
55+
LOG.info("{} - SKU {} - Processing order", order.getOrderNumber(), order.getSku());
56+
// try {
57+
// Thread.sleep(250);
58+
// } catch (InterruptedException e) {
59+
// }
60+
61+
if (order.getSku().equals("XPTO-0")) {
62+
LOG.warn("{} - SKU out of stock", order.getOrderNumber());
63+
throw new SkuOutOfStockException("SKU " + order.getSku() + " out of stock");
64+
}
65+
if (order.getSku().equals("XPTO-2")) {
66+
LOG.warn("{} - Error during stock verification", order.getOrderNumber());
67+
throw new RuntimeException("Error during stock verification for SKU " + order.getSku());
68+
}
69+
70+
order.setProcessed();
71+
}
72+
73+
private void sendProcessedOrder(Order order) {
74+
var message = orderSerializer.serializeAndCreateMessage(order);
75+
76+
LOG.info("{} - Sending order to invoicing", order.getOrderNumber());
77+
this.rabbitTemplateHandler.getRabbitTemplate(OrderEvents.PROCESSED)
78+
.send(exchange, routingKey, message);
79+
}
80+
}

0 commit comments

Comments
 (0)