0
votes

i need to pass some parameters on the properties of the Exchange object. As far as i know and read about it, it's better to create my parameters on the exchange properties, because the headers of the message can change during routing. Camel is creating new exchange from route to route, but not preserving history of any of my parameters.

Now some context: I'm using Camel (2.16.1) deployed on WebLogic 12C

The relevant Maven part:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <camel.version>2.16.1</camel.version>
  </properties>

  <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.1.6.RELEASE</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-spring</artifactId>
            <version>${camel.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-cxf</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-test-spring</artifactId>
            <version>${camel.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.ejb</groupId>
            <artifactId>ejb-api</artifactId>
            <version>3.0</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.13</version>
        </dependency>
    </dependencies>

The Camel Context:

<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route>
        <from uri="file:/Users/user/camel-test/in?noop=false" />
        <process ref="TestProcess"/>
        <to uri="file:/Users/user/camel-test/out" />
    </route>
    <route>
        <from uri="file:/Users/user/camel-test/out?noop=false" />
        <process ref="TestProcess"/>
        <to uri="jms:CamelServer/CamelJMSModule!CamelQueue" />
    </route>
</camelContext>

As you can see i'm using a class called TestProcess, to affect the Exchange object like this:

package com.test.camel;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;

public class TestProcess implements Processor {

    public void process(Exchange exchange) throws Exception {

        //Just to get the Exchange ID, this ID is changing between routes
        System.out.println(exchange.getExchangeId());

        //The first time i try to get my custom property should return null of course
        System.out.println(exchange.getProperty("MY_PARAMETER_ID"));

        //So if my property does not exist in properties i will create it
        if(exchange.getProperty("MY_PARAMETER_ID") == null) {
            exchange.setProperty("MY_PARAMETER_ID", "SOME_VALUE");  
        }
    }
}

My problem is: I never get my property on properties during all routing. My goal is to set some properties when Camel starts to route my message, and have those properties available till the end of process.

The class TestProcess demonstrates how i trying to access the properties. I also tried on the XML like, not working as well:

<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route>
        <from uri="file:/Users/user/camel-test/in?noop=false" />
        <setProperty propertyName="MY_PARAMETER_ID">
                <simple>some-value</simple>
        </setProperty>
        <to uri="file:/Users/user/camel-test/out" />
    </route>
    <route>
        <from uri="file:/Users/user/camel-test/out?noop=false" />
        <log message="MY_PARAMETER_ID = ${header.MY_PARAMETER_ID}" />
        <to uri="jms:CamelServer/CamelJMSModule!CamelQueue" />
    </route>
</camelContext>

UPDATE: After a couple of you say that it was not possible to send property/header attributes from a file endpoint, just jms or direct, i tried using JMS but i still have the same problem, as you can see on the context:

<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route>
        <from uri="jms:CamelServer/CamelJMSModule!ReceiverQueue" />
        <setProperty propertyName="MY_PARAMETER_ID">
            <simple>some-value</simple>
        </setProperty>
        <to uri="jms:CamelServer/CamelJMSModule!CamelQueue" />
    </route>
    <route>
        <from uri="jms:CamelServer/CamelJMSModule!CamelQueue" />
        <log message="MY_PARAMETER_ID = ${header.MY_PARAMETER_ID}" />
        <to uri="jms:CamelServer/CamelJMSModule!FinalQueue" />
    </route>
</camelContext>

Any ideas? What i'm doing wrong?

With the example where i'm only using JMS, the only attribute that didn't change from on Exchange object to the other is the:

exchange.getIn().getHeader("breadcrumbId")

According to Camel documentation this is:

Camel 2.8: An unique id used for tracking messages across transports.

But this breadcrumbId only remains the same with JMS routes NOT with FILE routes.

Thanks!

2
Didn't understand the problem: the exchange properties your set are not available further down the route?Fritz Duchardt
Yes @FritzDuchardt, indeed.rodrigocoelho
Camel provides a setProperty tag to add properties to the exchange from the route definition xml. Did you try that?Fritz Duchardt
Yes, i really need a class (TestProcess) to create my properties, but yes i tried <setProperty/>, not working as well.rodrigocoelho
Do you mean that the properties you set in route 1(from(file:/Users/user/camel-test/in?noop=false)) are not visible/available in route2 (file:/Users/user/camel-test/out?noop=false) ? I think providing header/property information between 2 file endpoints is not possible, but you can use for example direct endpoints.soilworker

2 Answers

0
votes

Routing header/property values between 2 routes via file endpoints is not possible. Use for example direct endpoints or jms to communicate between 2 routes.

See http://camel.apache.org/direct.html or http://camel.apache.org/jms.html for more information.

-1
votes

Since you are using a new version of camel, this seems have happened. http://camel.apache.org/property.html

From Camel 2.15 onwards the property language has been renamed to exchangeProperty to avoid ambiguity, confusion and clash with properties as a general term. So use exchangeProperty instead of property when using Camel 2.15 onwards.

<route>
  <from uri="direct:a" />
  <recipientList>
    <exchangeProperty>myProperty</exchangeProperty>
  </recipientList>
</route>

Try in the xml dsl accessing the exchange property using the field instead.