0
votes

I have a Spring Integration (4.3) application and i have a JMS receiver which sends the received message to a ServiceActivator.

I am trying to Wiretap a channel, and send the JMS message to Logger (which in this case is Service Activator as well)

I get a strange behavior with the code below.

Every odd message sent (first, third) - it only goes to the logger.

Every even message sent (second, fourth, etc) - only goes to the ServiceActivator that is supposed to do some work and in the future sent the message downstream.

Here are logs

2018-07-23 16:14:43.278 INFO 16532 --- [ container-1] zzz : MSG1

Received via barChannel: MSG2

How can i change my code so all messages go both to the logger and the ServiceActivator that is supposed to do the work?

Thanks a lot in advance

@Bean
public ConnectionFactory jmsConnectionFactory() {
    return new ActiveMQConnectionFactory("tcp://localhost:61616");
}


@Bean
public JmsMessageDrivenEndpoint inbound() {
    JmsMessageDrivenEndpoint jmsMessageDrivenEndpoint = new JmsMessageDrivenEndpoint(container(), listener());
    jmsMessageDrivenEndpoint.setSessionAcknowledgeMode("transacted");
    jmsMessageDrivenEndpoint.setAutoStartup(true);
    return jmsMessageDrivenEndpoint;
}

@Bean
public DefaultMessageListenerContainer container() {
    DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();
    container.setConnectionFactory(jmsConnectionFactory());
    container.setDestinationName("foo.bar");
    return container;
}

@Bean
public ChannelPublishingJmsMessageListener listener() {
    ChannelPublishingJmsMessageListener listener = new ChannelPublishingJmsMessageListener();
    listener.setRequestChannelName("myLogChannel");
    return listener;
}

@ServiceActivator(inputChannel = "myLogChannel")
public void bar(String in) {
    System.out.println("Received via barChannel: " + in);
}

@Bean
public MessageChannel TappingChannel(MessageChannel myLogChannel) {
    DirectChannel d = new DirectChannel();
    d.addInterceptor(new WireTap("myLogChannel"));
    return d;
}

@Bean
@ServiceActivator(inputChannel = "myLogChannel")
public MessageHandler logger() {
    LoggingHandler loggingHandler = new LoggingHandler(LoggingHandler.Level.INFO.name());
    loggingHandler.setLoggerName("zzz");
    return loggingHandler;
}

@Bean
public MessageChannel myLogChannel() {
    return new DirectChannel();
}

EDIT: Here is the original code that works

@Bean
public MessageChannel toRouter() {
    return new DirectChannel();
}

@Bean
public ConnectionFactory jmsConnectionFactory() {
    return new ActiveMQConnectionFactory("tcp://localhost:61616");
}


@Bean
public JmsMessageDrivenEndpoint inbound(ConnectionFactory jmsConnectionFactory) {
    return new JmsMessageDrivenEndpoint(container(jmsConnectionFactory), listener());
}

@Bean
public DefaultMessageListenerContainer container(ConnectionFactory jmsConnectionFactory) {
    DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();
    container.setConnectionFactory(jmsConnectionFactory);
    container.setDestinationName("foo.bar");
    return container;
}

@Bean
public ChannelPublishingJmsMessageListener listener() {
    ChannelPublishingJmsMessageListener listener = new ChannelPublishingJmsMessageListener();
    listener.setRequestChannelName("toRouter");
    return listener;
}

@ServiceActivator(inputChannel = "toRouter")
public void bar(String in) {
    System.out.println("Received via barChannel: " + in);
}

I want to do the Wiretap logging on this code

1

1 Answers

1
votes

You have a mess in your config.

First of all you have two @ServiceActivator for the same myLogChannel DirectChannel. By default it uses a round-robin dispatching strategy. That's why you see that odd/even behavior between your two consumers on the same channel.

You separate TappingChannel doesn't bring any value and it is out of use at all. No one sends message to this channel: you send to the listener.setRequestChannelName("myLogChannel"); directly though... Therefore a WireTap isn't performed at all as well.

I'm not sure how to help you since it isn't clear what you are going to use as a main channel and what should be used from the wire-tap.

UPDATE

So, you need to configure that new WireTap("myLogChannel") on this toRouter channel.