initial commit

This commit is contained in:
waldemar lammert
2026-01-29 11:32:44 +01:00
parent 15ed545880
commit 997504e444
17 changed files with 643 additions and 0 deletions
@@ -0,0 +1,14 @@
package de.dev089.eventproducer;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableRabbit
@SpringBootApplication
public class EventProducerApplication {
public static void main(String[] args) {
SpringApplication.run(EventProducerApplication.class, args);
}
}
@@ -0,0 +1,55 @@
package de.dev089.eventproducer.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.JacksonJsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitConfiguration {
@Value("${rabbit.producer.exchange}")
private String producerExchange;
@Value("${rabbit.producer.queue}")
private String queueName;
@Value("${rabbit.producer.routing-key}")
private String routingKey;
@Bean
public TopicExchange topicExchange() {
return new TopicExchange(producerExchange, true, false);
}
@Bean
public Queue producerQueue() {
return QueueBuilder.durable(queueName).build();
}
@Bean
public Binding queueBinding(Queue producerQueue, TopicExchange topicExchange) {
return BindingBuilder.bind(producerQueue).to(topicExchange).with(routingKey);
}
@Bean
public MessageConverter jacksonConverter() {
return new JacksonJsonMessageConverter();
}
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, MessageConverter jacksonConverter) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(jacksonConverter);
rabbitTemplate.setExchange(producerExchange);
return rabbitTemplate;
}
}
@@ -0,0 +1,28 @@
package de.dev089.eventproducer.producer;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class TopicEventProducer {
private final RabbitTemplate rabbitTemplate;
private final String defaultRoutingKey;
public TopicEventProducer(
RabbitTemplate rabbitTemplate,
@Value("${rabbit.producer.routing-key}") String defaultRoutingKey
) {
this.rabbitTemplate = rabbitTemplate;
this.defaultRoutingKey = defaultRoutingKey;
}
public void publish(String routingKey, Object payload) {
rabbitTemplate.convertAndSend(routingKey, payload);
}
public void publishToDefaultQueue(Object payload) {
rabbitTemplate.convertAndSend(defaultRoutingKey, payload);
}
}
@@ -0,0 +1,52 @@
package de.dev089.eventproducer.web;
import de.dev089.eventproducer.producer.TopicEventProducer;
import de.dev089.eventproducer.web.dto.EventRequest;
import de.dev089.eventproducer.web.dto.MessageRequest;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api/events")
public class EventController {
private final TopicEventProducer topicEventProducer;
public EventController(TopicEventProducer topicEventProducer) {
this.topicEventProducer = topicEventProducer;
}
@PostMapping("/messages")
@ResponseStatus(HttpStatus.ACCEPTED)
public void publishMessage(@Validated @RequestBody MessageRequest request) {
Map<String, Object> envelope = new HashMap<>();
envelope.put("message", request.message());
envelope.put("sentAt", Instant.now().toString());
topicEventProducer.publishToDefaultQueue(envelope);
}
@PostMapping("/{routingKey}")
@ResponseStatus(HttpStatus.ACCEPTED)
public void publish(
@PathVariable String routingKey,
@Validated @RequestBody EventRequest request
) {
Map<String, Object> envelope = new HashMap<>();
envelope.put("eventType", request.eventType());
envelope.put("payload", request.payload());
envelope.put("sentAt", Instant.now().toString());
topicEventProducer.publish(routingKey, envelope);
}
}
@@ -0,0 +1,11 @@
package de.dev089.eventproducer.web.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.util.Map;
public record EventRequest(
@NotBlank String eventType,
@NotNull Map<String, Object> payload
) { }
@@ -0,0 +1,6 @@
package de.dev089.eventproducer.web.dto;
import jakarta.validation.constraints.NotBlank;
public record MessageRequest(@NotBlank String message) {
}
+20
View File
@@ -0,0 +1,20 @@
spring:
application:
name: event-producer
rabbitmq:
host: ${RABBITMQ_HOST}
port: ${RABBITMQ_PORT}
username: ${RABBITMQ_USERNAME}
password: ${RABBITMQ_PASSWORD}
rabbit:
producer:
exchange: dev.insurance.health.request
queue: dev.insurance.health.request.queue
routing-key: dev.insurance.health.request.route
springdoc:
swagger-ui:
path: /swagger-ui
api-docs:
path: /api-docs
@@ -0,0 +1,12 @@
package de.dev089.eventproducer;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class EventProducerApplicationTests {
@Test
void contextLoads() {
}
}