From 359d8af0b3e9b8595c28ee843e761374c7060b1a Mon Sep 17 00:00:00 2001 From: gothsins Date: Fri, 26 Jun 2026 20:49:56 -0300 Subject: [PATCH] feat: add rabbitmq publisher to transaction service --- pom.xml | 4 +++ .../finance_api/config/RabbitMQConfig.java | 23 ++++++++++++++ .../finance_api/event/TransactionEvent.java | 21 +++++++++++++ .../event/TransactionPublisher.java | 30 +++++++++++++++++++ .../service/TransactionService.java | 14 +++++++++ src/main/resources/application.properties | 8 ++++- 6 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/guilherme/finance_api/config/RabbitMQConfig.java create mode 100644 src/main/java/com/guilherme/finance_api/event/TransactionEvent.java create mode 100644 src/main/java/com/guilherme/finance_api/event/TransactionPublisher.java diff --git a/pom.xml b/pom.xml index 1f3ca8a..bea7224 100644 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,10 @@ h2 test + + org.springframework.boot + spring-boot-starter-amqp + io.jsonwebtoken jjwt-api diff --git a/src/main/java/com/guilherme/finance_api/config/RabbitMQConfig.java b/src/main/java/com/guilherme/finance_api/config/RabbitMQConfig.java new file mode 100644 index 0000000..fb931eb --- /dev/null +++ b/src/main/java/com/guilherme/finance_api/config/RabbitMQConfig.java @@ -0,0 +1,23 @@ +package com.guilherme.finance_api.config; + +import org.springframework.amqp.rabbit.connection.ConnectionFactory; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class RabbitMQConfig { + + @Bean + public Jackson2JsonMessageConverter messageConverter() { + return new Jackson2JsonMessageConverter(); + } + + @Bean + public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) { + RabbitTemplate template = new RabbitTemplate(connectionFactory); + template.setMessageConverter(messageConverter()); + return template; + } +} \ No newline at end of file diff --git a/src/main/java/com/guilherme/finance_api/event/TransactionEvent.java b/src/main/java/com/guilherme/finance_api/event/TransactionEvent.java new file mode 100644 index 0000000..cbad7d3 --- /dev/null +++ b/src/main/java/com/guilherme/finance_api/event/TransactionEvent.java @@ -0,0 +1,21 @@ +package com.guilherme.finance_api.event; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.time.LocalDate; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class TransactionEvent { + private Long id; + private String description; + private BigDecimal amount; + private LocalDate date; + private String type; + private String userEmail; + private String categoryName; +} \ No newline at end of file diff --git a/src/main/java/com/guilherme/finance_api/event/TransactionPublisher.java b/src/main/java/com/guilherme/finance_api/event/TransactionPublisher.java new file mode 100644 index 0000000..b131a1c --- /dev/null +++ b/src/main/java/com/guilherme/finance_api/event/TransactionPublisher.java @@ -0,0 +1,30 @@ +package com.guilherme.finance_api.event; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@RequiredArgsConstructor +public class TransactionPublisher { + + private final RabbitTemplate rabbitTemplate; + + @Value("${rabbitmq.exchange}") + private String exchange; + + @Value("${rabbitmq.routing-key}") + private String routingKey; + + public void publish(TransactionEvent event) { + log.info("📤 Publicando evento na fila: transação '{}' do usuário {}", + event.getDescription(), event.getUserEmail()); + + rabbitTemplate.convertAndSend(exchange, routingKey, event); + + log.info("✅ Evento publicado com sucesso."); + } +} \ No newline at end of file diff --git a/src/main/java/com/guilherme/finance_api/service/TransactionService.java b/src/main/java/com/guilherme/finance_api/service/TransactionService.java index a8f353b..144fdf5 100644 --- a/src/main/java/com/guilherme/finance_api/service/TransactionService.java +++ b/src/main/java/com/guilherme/finance_api/service/TransactionService.java @@ -6,6 +6,8 @@ import com.guilherme.finance_api.entity.Category; import com.guilherme.finance_api.entity.Transaction; import com.guilherme.finance_api.entity.User; +import com.guilherme.finance_api.event.TransactionEvent; +import com.guilherme.finance_api.event.TransactionPublisher; import com.guilherme.finance_api.exception.ResourceNotFoundException; import com.guilherme.finance_api.repository.CategoryRepository; import com.guilherme.finance_api.repository.TransactionRepository; @@ -28,6 +30,7 @@ public class TransactionService { private final TransactionRepository transactionRepository; private final UserRepository userRepository; private final CategoryRepository categoryRepository; + private final TransactionPublisher transactionPublisher; public Page findAll(TransactionFilter filter, Pageable pageable) { String email = SecurityContextHolder.getContext().getAuthentication().getName(); @@ -97,6 +100,17 @@ public TransactionResponse save(TransactionRequest request) { transaction.setCategory(category); Transaction savedTransaction = transactionRepository.save(transaction); + + TransactionEvent event = new TransactionEvent( + savedTransaction.getId(), + savedTransaction.getDescription(), + savedTransaction.getAmount(), + savedTransaction.getDate(), + savedTransaction.getType().name(), + savedTransaction.getUser().getEmail(), + savedTransaction.getCategory() != null ? savedTransaction.getCategory().getName() : null + ); + transactionPublisher.publish(event); return toResponse(savedTransaction); } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index b24ffdc..0a45536 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -6,4 +6,10 @@ spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true jwt.secret=${JWT_SECRET:5b6f8d2a1e4c7f9b3d0e2a5c8f1b4d7e9a2c5f8b1d4e7a0c3f6b9d2e5a8c1f4} -jwt.expiration=${JWT_EXPIRATION:86400000} \ No newline at end of file +jwt.expiration=${JWT_EXPIRATION:86400000} +spring.rabbitmq.host=${RABBITMQ_HOST:localhost} +spring.rabbitmq.port=${RABBITMQ_PORT:5672} +spring.rabbitmq.username=${RABBITMQ_USER:guest} +spring.rabbitmq.password=${RABBITMQ_PASSWORD:guest} +rabbitmq.exchange=transactions.exchange +rabbitmq.routing-key=transactions.created