More info:
I see that VmComponent implementation simply extends the SedaEndpoint and
instead of using its queues:
private final Map<String, QueueReference> queues = new HashMap<String,
QueueReference>();
uses a static map:
protected static final Map<String, QueueReference> QUEUES = new
HashMap<String, QueueReference>();
well, this is ok and smart, but it happen that when you get the consumers
in SedaEndpoint
public Set<SedaConsumer> getConsumers() {
return new HashSet<SedaConsumer>(consumers);
}
it does not returns all the consumers from any camel context.
In my previous example when I was using 1 producer in one context and 2
consumers in two other different contexts, the getConsumers() was returning
a set with only one consumer.
Now I'm starting thinking that this is a bug ;-)
Cristiano
2013/9/4 Cristiano Costantini <[email protected]>
> Hi all again,
> I have investigated the behavior and I get to the conclusion that vm: does
> not support the option "multipleConsumers" between different contexts (on
> the same JVM).
> Could anyone please confirm if this is the expected behavior or if it is a
> bug?
>
> thank you!
> Cristiano
>
>
> PS. Here are my clues and the code I have used to make the test:
>
> 1. if start multiple consumers on "seda:test" or "vm:test" on the same
> CamelContext I get a
> "Failed to start route route2 because of Multiple consumers for the same
> endpoint is not allowed" (Expected Behavior)
>
> 2. if start multiple consumers on "seda:test" from
> different CamelContext I get no errors but no message is exchanged
> (Expected Behavior)
>
> 3. if start multiple consumers on "vm:test" from different CamelContext
> get no errors, and only one consumer get the message (???? I don't if it is
> the desired behavior or if it should work as case 1 as vm: should see that
> there are multiple consumers for the same endpoint)
>
> 4. if start multiple consumers on "seda:test?multipleConsumers=true" or
> "vm:test?multipleConsumers=true" on the same CamelContext t works and each
> consumer get the message (Expected Behavior)
>
> 5. if start multiple consumers on "seda:test?multipleConsumers=true" using
> different CamelContext get no errors and again no message is exchanged
> (Expected Behavior as each camel context is independent)
>
> 6. if start multiple consumers on "vm:test?multipleConsumers=true" using
> different CamelContext I get no errors, but only one consumer get the
> message (Unexpected Behavior!!)
>
>
> Here the class I have used to make the test:
>
> package eu.protectrail.esb.camel;
>
> import org.apache.camel.CamelContext;
> import org.apache.camel.Exchange;
> import org.apache.camel.Processor;
> import org.apache.camel.ProducerTemplate;
> import org.apache.camel.builder.RouteBuilder;
> import org.apache.camel.impl.DefaultCamelContext;
>
> public class CamelSedaVmTests {
>
> public static class TestConsumer {
> private final String id;
> private final CamelContext context;
>
> public TestConsumer(String id, CamelContext context) {
> this.id = id;
> this.context = context;
> };
>
> public void registerRoutes(final String endpoint) throws Exception {
> context.addRoutes(new RouteBuilder() {
> @Override
> public void configure() {
> from(endpoint).process(new Processor() {
> @Override
> public void process(Exchange exchange) throws Exception {
> System.out.println(id + " has received " +
> exchange.getIn().getBody(String.class));
> }
> });
> }
> });
> }
>
> }
> public static class TestProducer {
>
> private final CamelContext context;
>
> public TestProducer(CamelContext context) {
> this.context = context;
> };
>
> public void produce(String body, String endpoint) {
> ProducerTemplate template = context.createProducerTemplate();
> template.sendBody(endpoint, body);
> }
> }
>
> public static void main(String[] args) throws Exception {
>
> // NOTE: uncomment the endpoint to test and set shareContext value to
> // true to use the same camel context for all the routes
>
> // final String endpoint = "seda:test";
> // final String endpoint = "vm:test";
> // final String endpoint = "seda:test?multipleConsumers=true";
> final String endpoint = "vm:test?multipleConsumers=true";
> boolean shareContext = false;
>
> TestConsumer consumerOne;
> TestConsumer consumerTwo;
> TestProducer producer;
>
> if (!shareContext) {
> // Test using 3 different contexts for the 2 consumer and the
> producer
> DefaultCamelContext contextUno = new DefaultCamelContext();
> DefaultCamelContext contextDue = new DefaultCamelContext();
> DefaultCamelContext contextProducer = new DefaultCamelContext();
>
> consumerOne = new TestConsumer("one", contextUno);
> consumerTwo = new TestConsumer("two", contextDue);
> producer = new TestProducer(contextProducer);
>
> contextUno.start();
> contextDue.start();
> contextProducer.start();
>
> } else {
> // Test using the same contexts for consumer and producers
> DefaultCamelContext sameContext = new DefaultCamelContext();
> consumerOne = new TestConsumer("one", sameContext);
> consumerTwo = new TestConsumer("two", sameContext);
> producer = new TestProducer(sameContext);
>
> sameContext.start();
> }
>
> consumerOne.registerRoutes(endpoint);
> consumerTwo.registerRoutes(endpoint);
>
> Thread.sleep(1000);
> System.out.println("-- START --");
> producer.produce("foo", endpoint);
>
> Thread.sleep(1000);
> producer.produce("bar", endpoint);
>
> Thread.sleep(1000);
> producer.produce("baz", endpoint);
>
> System.out.println("-- END --");
> }
> }
>
>
>
> 2013/9/4 Cristiano Costantini <[email protected]>
>
>> Hi All,
>>
>> I've switched and endpoint using seda: with options
>> multipleConsumers=true and waitForTaskToComplete=Never to using vm:
>> component.
>>
>> After this, the application does not respect anymore the
>> multipleConsumers=true options and two concurrent consumer steal the
>> message.
>>
>> I may have other issue which I'm going to investigate, but to avoid waste
>> time I please ask you if I'm missing some detail by switching from seda: to
>> vm: (it is the first time I use vm: and I was expecting the same behavior
>> of the seda:endpoint)
>>
>> I'm using Camel 2.10.6 inside Servicemix 4.5.2.
>>
>> Thank you very much!
>>
>> Cristiano
>>
>
>