Reputation: 14792
I created a Java class for EIP Event Messages. I expected to receive a Message at Observer.accept(Object o)
when using Camel's Bean component but I get an Event
instead. While this is convenient since I don't have to extract the Event
from the Message
's body myself I don't have access to the message's possible headers and attachments with this.
package name.igb.eip.integration.styles.test;
import java.time.Instant;
import java.util.List;
import java.util.Vector;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.impl.engine.DefaultCamelContextNameStrategy;
import org.apache.camel.model.RouteDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class EventMessageTest {
static final Logger log = LoggerFactory.getLogger( EventMessageTest.class );
public static void main( final String... args ) throws Exception {
try ( CamelContext cc = new DefaultCamelContext(); ) {
cc.setNameStrategy( new DefaultCamelContextNameStrategy( "Messaging Sample" ) );
cc.getRegistry().bind( "Subject", new Subject( "Subject" ) );
cc.getRegistry().bind( "Observer", new Observer( "Observer" ) );
final List<Observer> observers = new Vector<>();
observers.add( new Observer( "Observer 1" ) );
observers.add( new Observer( "Observer 2" ) );
observers.add( new Observer( "Observer 3" ) );
cc.addRoutes( new RouteBuilder() {
@Override
public void configure() {
final RouteDefinition route =
from( "timer:Event?repeatCount=1" )
.log( "creating endpoint " + Subject.class.getSimpleName() + "..." )
.bean( Subject.class ) // Subject.get() returns an Event
.log( "creating..." )
.process().message( m -> {
log.info( "...{}<{}>",
m, m.getBody( Event.class ).getClass().getSimpleName() );
} )
.routeId( "Event route" );
for ( final Observer observer : observers ) {
log.info( "creating endpoint {}...", observer.id );
route
.to( "bean:Observer" ) // this sends Event to Observer
// this alternative sends Message to Observer N
.process().message( m -> {
observer.accept( m );
} );
}
}
} ); // addRoutes( RouteBuilder() )
cc.start();
Thread.sleep( 2000 );
cc.stop();
cc.close();
}
catch ( final Exception e ) {
e.printStackTrace();
}
} // main()
} // EventMessageTest
class Subject implements Supplier<Event> {
String id;
Subject( final String id ) {
this.id = id;
}
@Override
@Handler
public Event get() {
return new Event();
}
} // Subject
class Event {
String id = Instant.now().toString();
} // Event
class Observer implements Consumer<Object> {
String id;
Observer( final String id ) throws Exception {
this.id = id;
}
Observer setId( final String id ) {
this.id = id;
return this;
}
@Override
@Handler
public void accept( final Object o ) {
// Why is o an Event and not a Message here if Observer is created
// by RouteDefinition.to( "bean:Observer" )?
EventMessageTest.log.info( "\n{} receiving {}...",
id, o.getClass().getSimpleName() );
}
} // Observer
19:24:13.404 [main] INFO n.i.e.i.s.test.EventMessageTest$1 - creating endpoint Observer 1...
19:24:13.408 [main] INFO n.i.e.i.s.test.EventMessageTest$1 - creating endpoint Observer 2...
19:24:13.408 [main] INFO n.i.e.i.s.test.EventMessageTest$1 - creating endpoint Observer 3...
19:24:14.553 [Camel (camel-1) thread #1 - timer://Event] INFO Event route - creating endpoint Subject...
19:24:14.559 [Camel (camel-1) thread #1 - timer://Event] INFO Event route - creating...
19:24:14.559 [Camel (camel-1) thread #1 - timer://Event] INFO n.i.e.i.s.test.EventMessageTest$1 - ...Message<Event>
19:24:14.560 [Camel (camel-1) thread #1 - timer://Event] INFO n.i.e.i.styles.test.EventMessageTest -
Observer receiving Event...
19:24:14.560 [Camel (camel-1) thread #1 - timer://Event] INFO n.i.e.i.styles.test.EventMessageTest -
Observer 1 receiving DefaultMessage...
19:24:14.560 [Camel (camel-1) thread #1 - timer://Event] INFO n.i.e.i.styles.test.EventMessageTest -
Observer receiving Event...
19:24:14.560 [Camel (camel-1) thread #1 - timer://Event] INFO n.i.e.i.styles.test.EventMessageTest -
Observer 2 receiving DefaultMessage...
19:24:14.560 [Camel (camel-1) thread #1 - timer://Event] INFO n.i.e.i.styles.test.EventMessageTest -
Observer receiving Event...
19:24:14.560 [Camel (camel-1) thread #1 - timer://Event] INFO n.i.e.i.styles.test.EventMessageTest -
Observer 3 receiving DefaultMessage...
Is this a bug or a feature (and why if it's the latter)?
If I change the following two lines to:
...
class Observer implements Consumer<Message> {
...
public void accept( final Message o ) {
...
I get:
java.lang.ClassCastException: class name.igb.eip.integration.styles.test.Event
cannot be cast to class org.apache.camel.Message (name.igb.eip.integration.styles.test.Event
and org.apache.camel.Message are in unnamed module of loader 'app')
at name.igb.eip.integration.styles.test.Observer.accept(EventMessageTest.java:1)
...
so apparently Camel doesn't look at the Consumer
's type parameter.
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>name.igb</groupId>
<artifactId>eip</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.release>23</maven.compiler.release>
<javaee.version>8.0.1</javaee.version>
<jakarta.enterprise.cdi-api.version>4.1.0</jakarta.enterprise.cdi-api.version>
<weld-se.version>6.0.0.Final</weld-se.version>
<camel.version>4.8.2</camel.version>
<slf4j.version>2.0.16</slf4j.version>
<logback.version>1.5.15</logback.version>
<mockito.version>5.14.2</mockito.version>
<hierarchy-maven-plugin.version>1.4</hierarchy-maven-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${javaee.version}</version>
</dependency>
<dependency>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
<version>${jakarta.enterprise.cdi-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-shaded</artifactId>
<version>${weld-se.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-junit5</artifactId>
<version>${camel.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-componentdsl</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-direct</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-groovy</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-mail</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jms</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-sjms</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-sjms2</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<!-- artifactId>mockito-core</artifactId -->
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<!-- allows the route to be run via 'mvn camel:run' -->
<plugin>
<groupId>org.apache.camel</groupId>
<artifactId>camel-maven-plugin</artifactId>
<version>${camel.version}</version>
</plugin>
<plugin>
<groupId>com.github.exampledriven</groupId>
<artifactId>hierarchy-maven-plugin</artifactId>
<version>${hierarchy-maven-plugin.version}</version>
</plugin>
</plugins>
</build>
</project>
Upvotes: 0
Views: 100