public void testSendAndReceivePubSub() throws Exception {
MessageBus messageBus = getMessageBus();
DirectChannel moduleOutputChannel = new DirectChannel();
// Test pub/sub by emulating how StreamPlugin handles taps
DirectChannel tapChannel = new DirectChannel();
QueueChannel moduleInputChannel = new QueueChannel();
QueueChannel module2InputChannel = new QueueChannel();
QueueChannel module3InputChannel = new QueueChannel();
messageBus.bindProducer("baz.0", moduleOutputChannel, null);
messageBus.bindConsumer("baz.0", moduleInputChannel, null);
moduleOutputChannel.addInterceptor(new WireTap(tapChannel));
messageBus.bindPubSubProducer("tap:baz.http", tapChannel, null);
// A new module is using the tap as an input channel
messageBus.bindPubSubConsumer("tap:baz.http", module2InputChannel, null);
// Another new module is using tap as an input channel
messageBus.bindPubSubConsumer("tap:baz.http", module3InputChannel, null);
Message<?> message = MessageBuilder.withPayload("foo").setHeader(MessageHeaders.CONTENT_TYPE, "foo/bar").build();
boolean success = false;
boolean retried = false;
while (!success) {
moduleOutputChannel.send(message);
Message<?> inbound = moduleInputChannel.receive(5000);
assertNotNull(inbound);
assertEquals("foo", inbound.getPayload());
assertNull(inbound.getHeaders().get(MessageBusSupport.ORIGINAL_CONTENT_TYPE_HEADER));
assertEquals("foo/bar", inbound.getHeaders().get(MessageHeaders.CONTENT_TYPE));
Message<?> tapped1 = module2InputChannel.receive(5000);
Message<?> tapped2 = module3InputChannel.receive(5000);
if (tapped1 == null || tapped2 == null) {
// listener may not have started
assertFalse("Failed to receive tap after retry", retried);
retried = true;
continue;
}
success = true;
assertEquals("foo", tapped1.getPayload());
assertNull(tapped1.getHeaders().get(MessageBusSupport.ORIGINAL_CONTENT_TYPE_HEADER));
assertEquals("foo/bar", tapped1.getHeaders().get(MessageHeaders.CONTENT_TYPE));
assertEquals("foo", tapped2.getPayload());
assertNull(tapped2.getHeaders().get(MessageBusSupport.ORIGINAL_CONTENT_TYPE_HEADER));
assertEquals("foo/bar", tapped2.getHeaders().get(MessageHeaders.CONTENT_TYPE));
}
// delete one tap stream is deleted
messageBus.unbindConsumer("tap:baz.http", module3InputChannel);
Message<?> message2 = MessageBuilder.withPayload("bar").setHeader(MessageHeaders.CONTENT_TYPE, "foo/bar").build();
moduleOutputChannel.send(message2);
// other tap still receives messages
Message<?> tapped = module2InputChannel.receive(5000);
assertNotNull(tapped);
// Removed tap does not
assertNull(module3InputChannel.receive(1000));
// when other tap stream is deleted
messageBus.unbindConsumer("tap:baz.http", module2InputChannel);
// Clean up as StreamPlugin would
messageBus.unbindConsumer("baz.0", moduleInputChannel);