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;
}
}
}