diff --git a/dina-base-api/pom.xml b/dina-base-api/pom.xml
index ac73f1083..822dfbecc 100644
--- a/dina-base-api/pom.xml
+++ b/dina-base-api/pom.xml
@@ -8,7 +8,7 @@
io.github.aafc-bicoe
dina-base-parent
- 0.116
+ 0.117
dina-base-api
@@ -144,7 +144,7 @@
io.github.aafc-bicoe
dina-test-support
- 0.116
+ 0.117
test
diff --git a/dina-client/pom.xml b/dina-client/pom.xml
index 4c5343764..a63ab76d8 100644
--- a/dina-client/pom.xml
+++ b/dina-client/pom.xml
@@ -8,7 +8,7 @@
io.github.aafc-bicoe
dina-base-parent
- 0.116
+ 0.117
dina-client
diff --git a/dina-messaging/pom.xml b/dina-messaging/pom.xml
index a87b50681..e30671f40 100644
--- a/dina-messaging/pom.xml
+++ b/dina-messaging/pom.xml
@@ -8,7 +8,7 @@
io.github.aafc-bicoe
dina-base-parent
- 0.116
+ 0.117
dina-messaging
@@ -35,6 +35,12 @@
${testcontainers.version}
test
+
+ io.github.aafc-bicoe
+ dina-test-support
+ 0.117
+ test
+
diff --git a/dina-messaging/src/main/java/ca/gc/aafc/dina/messaging/config/RabbitMQConfig.java b/dina-messaging/src/main/java/ca/gc/aafc/dina/messaging/config/RabbitMQConfig.java
index c4b9c84b8..9165bb3c5 100644
--- a/dina-messaging/src/main/java/ca/gc/aafc/dina/messaging/config/RabbitMQConfig.java
+++ b/dina-messaging/src/main/java/ca/gc/aafc/dina/messaging/config/RabbitMQConfig.java
@@ -9,20 +9,25 @@
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
+import java.util.Optional;
import javax.inject.Inject;
+import lombok.extern.log4j.Log4j2;
/**
* Configuration of RabbitMQ related beans
*/
+@Log4j2
@Configuration
@Conditional(MessagingConfigurationCondition.class)
public class RabbitMQConfig {
private final RabbitMQProperties rmqProps;
+ private final RabbitTemplate.ReturnsCallback returnCallback;
@Inject
- public RabbitMQConfig(RabbitMQProperties rmqProps) {
+ public RabbitMQConfig(RabbitMQProperties rmqProps, Optional returnCallback) {
this.rmqProps = rmqProps;
+ this.returnCallback = returnCallback.orElse(null);
}
@Bean
@@ -31,6 +36,9 @@ protected ConnectionFactory createConnectionFactory() {
cachingConnectionFactory.setUsername(rmqProps.getUsername());
cachingConnectionFactory.setPassword(rmqProps.getPassword());
+ // allow to get messages that can't be delivered back
+ cachingConnectionFactory.setPublisherReturns(true);
+
if(rmqProps.getPort() > 0) {
cachingConnectionFactory.setPort(rmqProps.getPort());
}
@@ -48,6 +56,16 @@ public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(createMessageConverter());
+ // tell RabbitMQ that messages need to be delivered
+ rabbitTemplate.setMandatory(true);
+
+ if (returnCallback != null) {
+ rabbitTemplate.setReturnsCallback(returnCallback);
+ } else {
+ rabbitTemplate.setReturnsCallback(
+ returned -> log.error("Can't deliver message {}", returned.getMessage()));
+ }
+
return rabbitTemplate;
}
diff --git a/dina-messaging/src/main/java/ca/gc/aafc/dina/messaging/message/ObjectExportNotification.java b/dina-messaging/src/main/java/ca/gc/aafc/dina/messaging/message/ObjectExportNotification.java
index 27356a282..c73989c2f 100644
--- a/dina-messaging/src/main/java/ca/gc/aafc/dina/messaging/message/ObjectExportNotification.java
+++ b/dina-messaging/src/main/java/ca/gc/aafc/dina/messaging/message/ObjectExportNotification.java
@@ -3,12 +3,16 @@
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
+import lombok.Data;
import lombok.Getter;
+import lombok.NoArgsConstructor;
import ca.gc.aafc.dina.messaging.DinaMessage;
@Builder
@AllArgsConstructor
+@Data
+@NoArgsConstructor
@Getter
public class ObjectExportNotification implements DinaMessage {
diff --git a/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/ConsumerProducerIT.java b/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/ConsumerProducerIT.java
index 84a40fef9..8967ff03e 100644
--- a/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/ConsumerProducerIT.java
+++ b/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/ConsumerProducerIT.java
@@ -6,8 +6,6 @@
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
@@ -31,7 +29,6 @@
"dina.messaging.isConsumer=true"
}
)
-@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class ConsumerProducerIT {
public static final RabbitMQContainer rabbitMQContainer = new RabbitMQContainer("rabbitmq:3.8.20-management-alpine");
diff --git a/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/ErrorHandlingProducerIT.java b/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/ErrorHandlingProducerIT.java
new file mode 100644
index 000000000..d5d187738
--- /dev/null
+++ b/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/ErrorHandlingProducerIT.java
@@ -0,0 +1,91 @@
+package ca.gc.aafc.dina.messaging;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javax.inject.Inject;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.springframework.amqp.core.ReturnedMessage;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
+import org.testcontainers.containers.RabbitMQContainer;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@SpringBootTest(
+ properties = {
+ "dina.messaging.isProducer=true",
+ "dina.messaging.isConsumer=false"
+ }
+)
+@Import(ErrorHandlingProducerIT.RabbitTemplateTestConfig.class)
+public class ErrorHandlingProducerIT {
+
+ public static final RabbitMQContainer rabbitMQContainer = new RabbitMQContainer("rabbitmq:3.8.20-management-alpine");
+
+ @Inject
+ private RabbitTemplateTestConfig rabbitTemplateTestConfig;
+
+ @Inject
+ private RabbitTemplate rabbitTemplate;
+
+ @BeforeAll
+ static void beforeAll() {
+ rabbitMQContainer.start();
+ }
+
+ @AfterAll
+ static void afterAll() {
+ rabbitMQContainer.stop();
+ }
+
+ @DynamicPropertySource
+ static void registerRabbitMQProperties(DynamicPropertyRegistry registry) {
+ registry.add("rabbitmq.host", rabbitMQContainer::getHost);
+ registry.add("rabbitmq.port", rabbitMQContainer::getAmqpPort);
+ registry.add("rabbitmq.username", rabbitMQContainer::getAdminUsername);
+ registry.add("rabbitmq.password", rabbitMQContainer::getAdminPassword);
+ }
+
+ @Test
+ public void sendMessageToNonExistentQueue_receiverReceives() throws InterruptedException {
+ DinaTestMessage myMessage = new DinaTestMessage("test-message Queue non-existing");
+ rabbitTemplate.convertAndSend("non-existing", myMessage);
+
+ assertTrue(rabbitTemplateTestConfig.getLatch().await(1000, TimeUnit.MILLISECONDS));
+ assertNotNull(rabbitTemplateTestConfig.getReturnedMessage());
+ }
+
+ @TestConfiguration
+ public static class RabbitTemplateTestConfig {
+
+ private final CountDownLatch latch = new CountDownLatch(1);
+ private ReturnedMessage returnedMessage;
+
+ public CountDownLatch getLatch() {
+ return latch;
+ }
+
+ public ReturnedMessage getReturnedMessage() {
+ return returnedMessage;
+ }
+
+ @Bean
+ public RabbitTemplate.ReturnsCallback returnCallback() {
+ return m -> {
+ returnedMessage = m;
+ latch.countDown();
+ };
+ }
+ }
+}
diff --git a/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/MessagingTestApplication.java b/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/MessagingTestApplication.java
new file mode 100644
index 000000000..0445577e2
--- /dev/null
+++ b/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/MessagingTestApplication.java
@@ -0,0 +1,8 @@
+package ca.gc.aafc.dina.messaging;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+
+@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
+public class MessagingTestApplication {
+}
diff --git a/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/consumer/RabbitMQTestConsumer.java b/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/consumer/RabbitMQTestConsumer.java
index 33d2957ea..48fdbc65e 100644
--- a/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/consumer/RabbitMQTestConsumer.java
+++ b/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/consumer/RabbitMQTestConsumer.java
@@ -4,11 +4,13 @@
import lombok.Getter;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import ca.gc.aafc.dina.messaging.DinaTestMessage;
@Component
+@ConditionalOnProperty(prefix = "dina.messaging", name = "isConsumer", havingValue = "true")
public class RabbitMQTestConsumer implements RabbitMQMessageConsumer {
@Getter
diff --git a/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/consumer/RabbitMQTestConsumerQueue2.java b/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/consumer/RabbitMQTestConsumerQueue2.java
index 55a52db98..0dbd071c3 100644
--- a/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/consumer/RabbitMQTestConsumerQueue2.java
+++ b/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/consumer/RabbitMQTestConsumerQueue2.java
@@ -1,6 +1,7 @@
package ca.gc.aafc.dina.messaging.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import ca.gc.aafc.dina.messaging.DinaTestMessage;
@@ -9,6 +10,7 @@
import lombok.Getter;
@Component
+@ConditionalOnProperty(prefix = "dina.messaging", name = "isConsumer", havingValue = "true")
public class RabbitMQTestConsumerQueue2 implements RabbitMQMessageConsumer {
@Getter
diff --git a/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/message/ObjectExportNotificationIT.java b/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/message/ObjectExportNotificationIT.java
new file mode 100644
index 000000000..ec13d3fad
--- /dev/null
+++ b/dina-messaging/src/test/java/ca/gc/aafc/dina/messaging/message/ObjectExportNotificationIT.java
@@ -0,0 +1,28 @@
+package ca.gc.aafc.dina.messaging.message;
+
+import java.util.UUID;
+
+import org.junit.jupiter.api.Test;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+import ca.gc.aafc.dina.testsupport.TestResourceHelper;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class ObjectExportNotificationIT {
+
+ @Test
+ public void testSerDe() throws JsonProcessingException {
+
+ ObjectExportNotification oen = ObjectExportNotification.builder()
+ .uuid(UUID.randomUUID())
+ .username("user")
+ .toa("toa").build();
+
+ String asJson = TestResourceHelper.OBJECT_MAPPER.writeValueAsString(oen);
+
+ ObjectExportNotification oen2 = TestResourceHelper.OBJECT_MAPPER.readValue(asJson, ObjectExportNotification.class);
+ assertEquals(oen, oen2);
+ }
+}
diff --git a/dina-search/pom.xml b/dina-search/pom.xml
index 8cb2605fb..c1febdf00 100644
--- a/dina-search/pom.xml
+++ b/dina-search/pom.xml
@@ -8,7 +8,7 @@
io.github.aafc-bicoe
dina-base-parent
- 0.116
+ 0.117
dina-search
diff --git a/dina-test-support/pom.xml b/dina-test-support/pom.xml
index 41f3081e5..164113a77 100644
--- a/dina-test-support/pom.xml
+++ b/dina-test-support/pom.xml
@@ -9,7 +9,7 @@
io.github.aafc-bicoe
dina-base-parent
- 0.116
+ 0.117
dina-test-support
diff --git a/dina-workbook/pom.xml b/dina-workbook/pom.xml
index 0948ff9dd..666fc9c7e 100644
--- a/dina-workbook/pom.xml
+++ b/dina-workbook/pom.xml
@@ -8,7 +8,7 @@
io.github.aafc-bicoe
dina-base-parent
- 0.116
+ 0.117
dina-workbook
diff --git a/pom.xml b/pom.xml
index d62c37278..dedf927e8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
io.github.aafc-bicoe
dina-base-parent
- 0.116
+ 0.117
pom