We're using EventNotifier and ExchangeSentEvent to log timing of certain 
direct:// routes and we've run into a problem when using @Produce instead of 
ProducerTemplate.

When sending exchange to producer template, ExchangeSentEvent is fired after 
exchange is sent. Same when it's part of a larger route. Not so much with 
@Produce.

Any guidance on how to use @Produce but still trigger the events?

I've got a unit test below - notifyProxy fails, but the other cases pass. Camel 
2.23.0

Thanks,
Kevin







import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import java.util.EventObject;

import org.apache.camel.Body;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Produce;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultExchange;
import org.apache.camel.management.event.ExchangeSentEvent;
import org.apache.camel.spring.javaconfig.CamelConfiguration;
import org.apache.camel.support.EventNotifierSupport;
import org.apache.camel.test.spring.CamelSpringRunner;
import org.apache.camel.util.EndpointHelper;
import org.apache.camel.util.ServiceHelper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;

@RunWith(CamelSpringRunner.class)
@ContextConfiguration(classes = { CamelConfiguration.class, 
DirectTest.TestConfig.class })
public class DirectTest {
       private static final String NAME = "Doug";
       private static final String EXPECTED = "Hello, 'Doug'";

       @Produce(uri = HelloApi.ROUTE)
       private HelloApi helloApi;

       @Produce(uri = HelloApi.ROUTE)
       private ProducerTemplate helloApiTemplate;

       @Produce(uri = HelloApi.WRAPPED_ROUTE)
       private HelloApi helloApiWrapped;

       @Autowired
       private CamelContext camelContext;
       private HelloSentEventNotifier eventNotifier;

       @Before
       public void setup() throws Exception {
              assertThat(helloApi, notNullValue());
              assertThat(helloApiTemplate, notNullValue());

              eventNotifier = new HelloSentEventNotifier(camelContext);
       }

       @Test
       public void notifyTemplate() {
              eventNotifier.reset();
              Exchange e = new DefaultExchange(camelContext);
              e.getIn().setBody(NAME);
              e = helloApiTemplate.send(e);
              String output = e.getOut().getBody(String.class);
              assertThat(output, equalTo(EXPECTED));
              assertTrue("ExchangeSentEvent not received", 
eventNotifier.notified());
       }

       @Test
       public void notifyProxy() {
              eventNotifier.reset();
              String output = helloApi.sayHello(NAME);
              assertThat(output, equalTo(EXPECTED));
              assertTrue("ExchangeSentEvent not received", 
eventNotifier.notified());
       }

       @Test
       public void notifyWrappedProxy() {
              eventNotifier.reset();
              String output = helloApiWrapped.sayHello(NAME);
              assertThat(output, equalTo(EXPECTED));
              assertTrue("ExchangeSentEvent not received", 
eventNotifier.notified());
       }

       @Configuration
       public static class TestConfig {
              @Bean
              public RouteBuilder builder() {
                     return new RouteBuilder() {
                           @Override
                           public void configure() throws Exception {
                                  from(HelloApi.ROUTE).process(e -> {
                                         String name = 
e.getIn().getBody(String.class);
                                         String output = String.format("Hello, 
'%s'", name);
                                         e.getOut().setBody(output);
                                  });

                                  
from(HelloApi.WRAPPED_ROUTE).to(HelloApi.ROUTE);
                           }
                     };
              }
       }

       public static interface HelloApi {
              public static final String ROUTE = "direct://hello";
              public static final String WRAPPED_ROUTE = ROUTE + "/wrapper";

              public String sayHello(@Body String name);
       }

       public static class HelloSentEventNotifier extends EventNotifierSupport {
              private boolean notified = false;
              private CamelContext camelContext;

              public HelloSentEventNotifier(CamelContext camelContext) {
                     this.camelContext = camelContext;
                     try {
                           ServiceHelper.startService(this);
                           
camelContext.getManagementStrategy().addEventNotifier(this);
                     } catch (Exception e) {
                           throw new RuntimeException(e);
                     }
              }

              @Override
              public void notify(EventObject event) throws Exception {
                     if (event instanceof ExchangeSentEvent) {
                           ExchangeSentEvent sentEvent = 
(ExchangeSentEvent)event;
                if (EndpointHelper.matchEndpoint(camelContext, 
sentEvent.getEndpoint().getEndpointUri(), HelloApi.ROUTE)) {
                    notified = true;
                }
                     }
              }

              @Override
              public boolean isEnabled(EventObject event) {
                     return true;
              }

              public void reset() {
                     notified = false;
              }

              public boolean notified() {
                     return notified;
              }
       }
}

Reply via email to