I am using the Apache ZooKeeper component (version 2.10.1) and I have two 
routes defined: one using a zookeeper consumer endpoint and one using a 
zookeeper producer endpoint. Each route works fine on its own, but I get an 
exception when I have both together. The URI parameters on my consumer endpoint 
seem to be affecting the behaviour of my producer endpoint.

The problem seems to be caused by this code in the ZooKeeperComponent class:

    protected Endpoint createEndpoint(String uri, String remaining, Map 
parameters) throws Exception {
        if (getCamelContext() == null) {
            throw new CamelException("No Camel context has been provided to 
this zookeeper component");
        }

        ZooKeeperConfiguration config = getConfiguration();
        extractConfigFromUri(uri, config);
        setProperties(config, parameters);

        return new ZooKeeperEndpoint(uri, this, config.copy());
    }


This retrieves a configuration settings wrapper object that is stored in the 
component, adds to it the settings from the endpoint being created, and then 
stores a copy in the new endpoint. Surely this code should copy the component 
configuration, and then change the *copy* and store it in the endpoint, as 
follows:

        // Below I have added ".copy()"
        ZooKeeperConfiguration config = getConfiguration().copy();
        extractConfigFromUri(uri, config);
        setProperties(config, parameters);

        // Below I have changed "config.copy()" to "config"
        return new ZooKeeperEndpoint(uri, this, config); 


This change fixes the problem for the sample code below:

CamelContext camel = new DefaultCamelContext();
camel.addRoutes(new RouteBuilder() {
    @Override
    public void configure() {
        // Get message containing children of zookeeper node /agents whenever
        // there is a change
        from("zookeeper://127.0.0.1:2181/agents?listChildren=true&repeat=true")
        .to("mock:children");

        // Create a zookeeper sequence node /agents/agentX (where X is a
        // zero-padded 10 digit integer)
        from("direct:createSequenceNode")
        
.to("zookeeper://127.0.0.1:2181/agents/agent?create=true&createMode=EPHEMERAL_SEQUENTIAL")
        .to("mock:createdNode");
    }});

    camel.start();
    MockEndpoint mock = camel.getEndpoint("mock:createdNode", 
MockEndpoint.class);
    mock.expectedMessageCount(1);
    mock.message(0).body().contains("/agents/agent0");
    ProducerTemplate template = camel.createProducerTemplate();
    template.sendBody("direct:createSequenceNode", ExchangePattern.InOut, 
"irrelevant");
    mock.assertIsSatisfied();
}


Here is the exception I get (if I don't change the ZooKeeperComponent code as 
shown above). The zookeeper producer endpoint seems to be performing a 
getChildren operation, even though the "listChildren" URI parameter appears 
only on the consumer endpoint. As part of that operation it tries to read from 
the the path /agents/agent, which doesn't exist because the node was created as 
a sequence node and so had a zero-padded 10 digit number appended to its path.

Exception in thread "main" org.apache.camel.CamelExecutionException: Exception 
occurred during execution on the exchange: Exchange[Message: [Body is null]]
        at 
org.apache.camel.util.ObjectHelper.wrapCamelExecutionException(ObjectHelper.java:1237)
        at 
org.apache.camel.util.ExchangeHelper.extractResultBody(ExchangeHelper.java:509)
        at 
org.apache.camel.impl.DefaultProducerTemplate.extractResultBody(DefaultProducerTemplate.java:442)
        at 
org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:120)
        at 
org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:136)
        at bdi.BdiCamel.main(BdiCamel.java:107)
Caused by: org.apache.zookeeper.KeeperException$NoNodeException: 
KeeperErrorCode = NoNode for /agents/agent
        at org.apache.zookeeper.KeeperException.create(KeeperException.java:102)
        at org.apache.zookeeper.KeeperException.create(KeeperException.java:42)
        at org.apache.zookeeper.ZooKeeper.getChildren(ZooKeeper.java:1369)
        at org.apache.zookeeper.ZooKeeper.getChildren(ZooKeeper.java:1404)
        at 
org.apache.camel.component.zookeeper.operations.GetChildrenOperation.getResult(GetChildrenOperation.java:40)
        at 
org.apache.camel.component.zookeeper.operations.ZooKeeperOperation.get(ZooKeeperOperation.java:71)
        at 
org.apache.camel.component.zookeeper.ZookeeperProducer.listChildren(ZookeeperProducer.java:101)
        at 
org.apache.camel.component.zookeeper.ZookeeperProducer.process(ZookeeperProducer.java:73)
...


Regards,
Stephen

Reply via email to