diff --git a/pom.xml b/pom.xml
index ea1f061..e51acbd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@
edu.stanford.protege
webprotege-ipc
- 0.10.3-SNAPSHOT
+ 1.0.1
webprotege-ipc
Inter Process Communication framework
@@ -57,7 +57,7 @@
edu.stanford.protege
webprotege-common
- 0.9.5
+ 0.9.6
diff --git a/src/main/java/edu/stanford/protege/webprotege/ipc/impl/RabbitMQEventDispatcher.java b/src/main/java/edu/stanford/protege/webprotege/ipc/impl/RabbitMQEventDispatcher.java
index 31e97a8..c412b4a 100644
--- a/src/main/java/edu/stanford/protege/webprotege/ipc/impl/RabbitMQEventDispatcher.java
+++ b/src/main/java/edu/stanford/protege/webprotege/ipc/impl/RabbitMQEventDispatcher.java
@@ -8,6 +8,7 @@
import edu.stanford.protege.webprotege.ipc.EventDispatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
@@ -49,9 +50,9 @@ public void dispatchEvent(Event event) {
var projectId = ((ProjectEvent) event).projectId().value();
message.getMessageProperties().getHeaders().put(PROJECT_ID, projectId);
}
- eventRabbitTemplate.send(message);
- logger.info("Sent event message");
- } catch (JsonProcessingException e) {
+ eventRabbitTemplate.convertAndSend(RabbitMQEventsConfiguration.EVENT_EXCHANGE, "", message);
+ logger.info("Sent event message!");
+ } catch (JsonProcessingException | AmqpException e) {
logger.info("Could not serialize event: {}", e.getMessage(), e);
}
diff --git a/src/main/java/edu/stanford/protege/webprotege/ipc/impl/RabbitMQEventHandlerWrapper.java b/src/main/java/edu/stanford/protege/webprotege/ipc/impl/RabbitMQEventHandlerWrapper.java
index 79d5749..51b527c 100644
--- a/src/main/java/edu/stanford/protege/webprotege/ipc/impl/RabbitMQEventHandlerWrapper.java
+++ b/src/main/java/edu/stanford/protege/webprotege/ipc/impl/RabbitMQEventHandlerWrapper.java
@@ -32,7 +32,7 @@ public void onMessage(Message message) {
EventHandler eventHandler = eventHandlers.stream()
.filter(handler -> {
String channel = String.valueOf(message.getMessageProperties().getHeaders().get(CHANNEL));
- return handler.getChannelName().equals(channel);
+ return channel.contains(handler.getChannelName());
}).findFirst()
.orElse(null);
if(eventHandler != null) {
diff --git a/src/main/java/edu/stanford/protege/webprotege/ipc/impl/RabbitMQEventsConfiguration.java b/src/main/java/edu/stanford/protege/webprotege/ipc/impl/RabbitMQEventsConfiguration.java
new file mode 100644
index 0000000..bb2c9f2
--- /dev/null
+++ b/src/main/java/edu/stanford/protege/webprotege/ipc/impl/RabbitMQEventsConfiguration.java
@@ -0,0 +1,85 @@
+package edu.stanford.protege.webprotege.ipc.impl;
+
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import edu.stanford.protege.webprotege.common.Event;
+import edu.stanford.protege.webprotege.ipc.EventHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.FanoutExchange;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.rabbit.connection.ConnectionFactory;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Configuration
+public class RabbitMQEventsConfiguration {
+ private final static Logger logger = LoggerFactory.getLogger(RabbitMQEventsConfiguration.class);
+
+ @Value("${webprotege.rabbitmq.timeout}")
+ public Long rabbitMqTimeout;
+
+ @Value("${webprotege.rabbitmq.eventsqueue:EVENTS_QUEUE}")
+ public String eventsQueue;
+
+
+ public static final String EVENT_EXCHANGE = "webprotege-event-exchange";
+
+
+ @Autowired(required = false)
+ private List> eventHandlers = new ArrayList<>();
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ @Bean
+ public Queue eventsQueue() {
+ return new Queue(eventsQueue, true);
+ }
+
+
+ @Bean
+ FanoutExchange eventExchange() {
+ return new FanoutExchange(EVENT_EXCHANGE, true, false);
+ }
+
+
+ @Bean(name = "eventRabbitTemplate")
+ public RabbitTemplate eventRabbitTemplate(ConnectionFactory connectionFactory) {
+ RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
+ rabbitTemplate.setReplyTimeout(rabbitMqTimeout);
+ rabbitTemplate.setExchange(EVENT_EXCHANGE);
+ return rabbitTemplate;
+ }
+
+ @Bean
+ @ConditionalOnProperty(havingValue = "true", prefix = "webprotege.rabbitmq", name = "event-subscribe")
+ public SimpleMessageListenerContainer eventsListenerContainer(ConnectionFactory connectionFactory) {
+ logger.info("[RabbitMQEventConfiguration] Listening to event queue {}", eventsQueue);
+ SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
+ container.setConnectionFactory(connectionFactory);
+ container.setQueueNames(eventsQueue);
+ container.setMessageListener(new RabbitMQEventHandlerWrapper(eventHandlers, objectMapper));
+ return container;
+ }
+
+ @Bean
+ @ConditionalOnProperty(havingValue = "true", prefix = "webprotege.rabbitmq", name = "event-subscribe")
+ public Binding binding(Queue eventsQueue, FanoutExchange fanoutExchange) {
+ logger.info("[RabbitMQEventConfiguration] Binding to event queue {}", eventsQueue);
+
+ return BindingBuilder.bind(eventsQueue).to(fanoutExchange);
+ }
+
+
+}
diff --git a/src/main/java/edu/stanford/protege/webprotege/ipc/impl/RabbitMqConfiguration.java b/src/main/java/edu/stanford/protege/webprotege/ipc/impl/RabbitMqConfiguration.java
index a4cea42..f425d9f 100644
--- a/src/main/java/edu/stanford/protege/webprotege/ipc/impl/RabbitMqConfiguration.java
+++ b/src/main/java/edu/stanford/protege/webprotege/ipc/impl/RabbitMqConfiguration.java
@@ -5,13 +5,11 @@
import com.rabbitmq.client.Channel;
import edu.stanford.protege.webprotege.authorization.GetAuthorizationStatusRequest;
import edu.stanford.protege.webprotege.authorization.GetAuthorizationStatusResponse;
-import edu.stanford.protege.webprotege.common.Event;
import edu.stanford.protege.webprotege.common.Request;
import edu.stanford.protege.webprotege.common.Response;
import edu.stanford.protege.webprotege.ipc.CommandExecutor;
-import org.springframework.context.ApplicationContext;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import edu.stanford.protege.webprotege.ipc.CommandHandler;
-import edu.stanford.protege.webprotege.ipc.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
@@ -33,6 +31,7 @@
import java.util.concurrent.TimeoutException;
@Configuration
+@ConditionalOnProperty(prefix = "webprotege.rabbitmq", name = "commands-subscribe", havingValue = "true", matchIfMissing = true)
public class RabbitMqConfiguration {
private final static Logger logger = LoggerFactory.getLogger(RabbitMqConfiguration.class);
@@ -50,56 +49,41 @@ public class RabbitMqConfiguration {
public static final String COMMANDS_EXCHANGE = "webprotege-exchange";
- public static final String EVENT_EXCHANGE = "webprotege-event-exchange";
-
- public static final String EVENT_QUEUE = "webprotege-event-queue";
@Autowired
private ConnectionFactory connectionFactory;
- @Autowired(required = false)
- private List> eventHandlers = new ArrayList<>();
-
+ @Autowired
+ private ObjectMapper objectMapper;
@Autowired(required = false)
private List> handlers = new ArrayList<>();
-
- @Autowired
- private ApplicationContext applicationContext;
-
- @Autowired
- private ObjectMapper objectMapper;
-
@Autowired
private CommandExecutor authorizationStatusExecutor;
@Bean
+ @ConditionalOnProperty(prefix = "webprotege.rabbitmq", name = "commands-subscribe", havingValue = "true", matchIfMissing = true)
Queue msgQueue() {
return new Queue(getCommandQueue(), true);
}
@Bean
+ @ConditionalOnProperty(prefix = "webprotege.rabbitmq", name = "commands-subscribe", havingValue = "true", matchIfMissing = true)
Queue replyQueue() {
return new Queue(getCommandResponseQueue(), true);
}
@Bean
- public Queue eventsQueue() {
- return new Queue(EVENT_QUEUE, true);
- }
-
- @Bean
+ @ConditionalOnProperty(prefix = "webprotege.rabbitmq", name = "commands-subscribe", havingValue = "true", matchIfMissing = true)
DirectExchange exchange() {
return new DirectExchange(COMMANDS_EXCHANGE, true, false);
}
- @Bean
- FanoutExchange eventExchange() {
- return new FanoutExchange(EVENT_EXCHANGE, true, false);
- }
+
@Bean(name = "rabbitTemplate")
+ @ConditionalOnProperty(prefix = "webprotege.rabbitmq", name = "commands-subscribe", havingValue = "true", matchIfMissing = true)
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setReplyTimeout(rabbitMqTimeout);
@@ -108,29 +92,15 @@ public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
}
@Bean(name = "asyncRabbitTemplate")
+ @ConditionalOnProperty(prefix = "webprotege.rabbitmq", name = "commands-subscribe", havingValue = "true", matchIfMissing = true)
public AsyncRabbitTemplate asyncRabbitTemplate(@Qualifier("rabbitTemplate") RabbitTemplate rabbitTemplate, SimpleMessageListenerContainer replyListenerContainer) {
return new AsyncRabbitTemplate(rabbitTemplate, replyListenerContainer, getCommandResponseQueue());
}
- @Bean(name = "eventRabbitTemplate")
- public RabbitTemplate eventRabbitTemplate(ConnectionFactory connectionFactory) {
- RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
- rabbitTemplate.setReplyTimeout(rabbitMqTimeout);
- rabbitTemplate.setExchange(EVENT_EXCHANGE);
- rabbitTemplate.setUseDirectReplyToContainer(false);
- return rabbitTemplate;
- }
- @Bean
- public SimpleMessageListenerContainer eventsListenerContainer(ConnectionFactory connectionFactory, Queue eventsQueue, @Qualifier("eventRabbitTemplate") RabbitTemplate eventRabbitTemplate) {
- SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
- container.setConnectionFactory(connectionFactory);
- container.setQueueNames(EVENT_QUEUE);
- container.setMessageListener(new RabbitMQEventHandlerWrapper(eventHandlers, objectMapper));
- return container;
- }
@Bean
+ @ConditionalOnProperty(prefix = "webprotege.rabbitmq", name = "commands-subscribe", havingValue = "true", matchIfMissing = true)
public SimpleMessageListenerContainer replyListenerContainer(ConnectionFactory connectionFactory, Queue replyQueue) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
@@ -139,11 +109,13 @@ public SimpleMessageListenerContainer replyListenerContainer(ConnectionFactory c
}
@Bean
+ @ConditionalOnProperty(prefix = "webprotege.rabbitmq", name = "commands-subscribe", havingValue = "true", matchIfMissing = true)
public RabbitMqCommandHandlerWrapper rabbitMqCommandHandlerWrapper(){
return new RabbitMqCommandHandlerWrapper<>(handlers, objectMapper, authorizationStatusExecutor);
}
@Bean
+ @ConditionalOnProperty(prefix = "webprotege.rabbitmq", name = "commands-subscribe", havingValue = "true", matchIfMissing = true)
public SimpleMessageListenerContainer messageListenerContainers() {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setQueueNames(getCommandQueue());
@@ -152,28 +124,8 @@ public SimpleMessageListenerContainer messageListenerContainers() {
return container;
}
- @Bean
- public List eventsBindings(FanoutExchange fanoutExchange, Queue eventsQueue) {
- var response = new ArrayList();
-
- try (Connection connection = connectionFactory.createConnection();
- Channel channel = connection.createChannel(true)) {
- channel.exchangeDeclare(EVENT_EXCHANGE, "fanout", true);
- channel.queueDeclare(EVENT_QUEUE, true, false, false, null);
-
- for(EventHandler eventHandler : eventHandlers) {
- channel.queueBind(eventsQueue.getName(), fanoutExchange.getName(), eventHandler.getChannelName());
- response.add(BindingBuilder.bind(eventsQueue).to(fanoutExchange));
- }
- } catch (IOException | TimeoutException e) {
- logger.error("Error initialize bindings", e);
- }
-
-
- return response;
- }
-
@PostConstruct
+ @ConditionalOnProperty(prefix = "webprotege.rabbitmq", name = "commands-subscribe", havingValue = "true", matchIfMissing = true)
public void createBindings() {
try (Connection connection = connectionFactory.createConnection();
Channel channel = connection.createChannel(true)) {
@@ -190,6 +142,7 @@ public void createBindings() {
} catch (IOException |TimeoutException e) {
logger.error("Error initialize bindings", e);
+ throw new RuntimeException("Error initialize bindings", e);
}
}
diff --git a/src/test/java/edu/stanford/protege/webprotege/ipc/CommandExecutionException_Tests.java b/src/test/java/edu/stanford/protege/webprotege/ipc/CommandExecutionException_Tests.java
index 9a2b425..0f1dea2 100644
--- a/src/test/java/edu/stanford/protege/webprotege/ipc/CommandExecutionException_Tests.java
+++ b/src/test/java/edu/stanford/protege/webprotege/ipc/CommandExecutionException_Tests.java
@@ -7,6 +7,7 @@
import org.springframework.boot.test.json.JacksonTester;
import org.springframework.http.HttpStatus;
import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
import java.io.IOException;
@@ -20,6 +21,7 @@
@SpringBootTest
@AutoConfigureJsonTesters
@ContextConfiguration(classes = WebProtegeIpcApplication.class)
+@TestPropertySource(properties = "webprotege.rabbitmq.commands-subscribe=false")
public class CommandExecutionException_Tests extends IntegrationTestsExtension {
@Autowired
diff --git a/src/test/java/edu/stanford/protege/webprotege/ipc/CommandExecutor_CommandHandler_ExceptionThrowing_TestsCase.java b/src/test/java/edu/stanford/protege/webprotege/ipc/CommandExecutor_CommandHandler_ExceptionThrowing_TestsCase.java
index 56bae1a..263029b 100644
--- a/src/test/java/edu/stanford/protege/webprotege/ipc/CommandExecutor_CommandHandler_ExceptionThrowing_TestsCase.java
+++ b/src/test/java/edu/stanford/protege/webprotege/ipc/CommandExecutor_CommandHandler_ExceptionThrowing_TestsCase.java
@@ -31,7 +31,6 @@
* 2022-02-09
*/
@SpringBootTest
-@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class CommandExecutor_CommandHandler_ExceptionThrowing_TestsCase extends IntegrationTestsExtension {
@Autowired
diff --git a/src/test/java/edu/stanford/protege/webprotege/ipc/CommandExecutor_CommandHandler_Test.java b/src/test/java/edu/stanford/protege/webprotege/ipc/CommandExecutor_CommandHandler_Test.java
index 255178c..2797062 100644
--- a/src/test/java/edu/stanford/protege/webprotege/ipc/CommandExecutor_CommandHandler_Test.java
+++ b/src/test/java/edu/stanford/protege/webprotege/ipc/CommandExecutor_CommandHandler_Test.java
@@ -31,7 +31,6 @@
* 2021-08-03
*/
@SpringBootTest
-@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class CommandExecutor_CommandHandler_Test extends IntegrationTestsExtension {
@Autowired
diff --git a/src/test/java/edu/stanford/protege/webprotege/ipc/EventHandler_TestCase.java b/src/test/java/edu/stanford/protege/webprotege/ipc/EventHandler_TestCase.java
index 4c8671d..9025fa0 100644
--- a/src/test/java/edu/stanford/protege/webprotege/ipc/EventHandler_TestCase.java
+++ b/src/test/java/edu/stanford/protege/webprotege/ipc/EventHandler_TestCase.java
@@ -10,6 +10,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.test.context.TestPropertySource;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
@@ -25,6 +26,7 @@
* 2022-02-08
*/
@SpringBootTest(classes = WebProtegeIpcApplication.class)
+@TestPropertySource(properties = "webprotege.rabbitmq.event-subscribe=true")
public class EventHandler_TestCase extends IntegrationTestsExtension {
public static CountDownLatch countDownLatch;
diff --git a/src/test/java/edu/stanford/protege/webprotege/ipc/IntegrationTestsExtension.java b/src/test/java/edu/stanford/protege/webprotege/ipc/IntegrationTestsExtension.java
index d4e5081..1e4f954 100644
--- a/src/test/java/edu/stanford/protege/webprotege/ipc/IntegrationTestsExtension.java
+++ b/src/test/java/edu/stanford/protege/webprotege/ipc/IntegrationTestsExtension.java
@@ -1,9 +1,12 @@
package edu.stanford.protege.webprotege.ipc;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.RabbitMQContainer;
@@ -21,6 +24,7 @@
@SpringBootTest(properties = {"spring.mongodb.embedded.version=5.0.6"})
@AutoConfigureWebTestClient
@Testcontainers
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class IntegrationTestsExtension {
private static Logger logger = LoggerFactory.getLogger(IntegrationTestsExtension.class);
@@ -36,4 +40,14 @@ static void configure(DynamicPropertyRegistry registry) {
registry.add("spring.rabbitmq.host", rabbitContainer::getHost);
registry.add("spring.rabbitmq.port", rabbitContainer::getAmqpPort);
}
+
+ @BeforeAll
+ public static void containerSetUp(){
+ rabbitContainer.start();
+ }
+
+ @AfterAll
+ public static void containerTearDown(){
+ rabbitContainer.stop();
+ }
}