FAQ
Hi,

I needed to route a message from one ActiveMQ broker to one or more remote
ActiveMQ brokers based on some runtime information.

Lets say I've broker "central" and remote brokers "remote1", "remote2", ...
"remoteN".
The number of remote brokers can change over time and I wouldn't want to
configure any beans or any kind of configuration in the activemq.xml of the
"central" broker.

The following what I tried, but it seems to be sending the message always to
the first "remote" server that I used. Couple of points:

0. I putup a POJO bean with RecipientList EIP.
1. topic:Out.RemoteServers is the topic on the "central" broker
2. topic:In.LocalServer is the topic on any "remote" broker.
3. All applications that post messages to "central" broker add a message
header with name "IPAddesses". The header value contain a list of IP
addresses corresponding to the "remote" brokers.
4. I'm using camel version 1.6.1.0

The code looks as follows (trimmed for clarity)

--------
@Consume(uri = "topic:Out.RemoteServers")
@RecipientList()
public Collection<Endpoint> getRoutes(@Header(name = "IPAddresses") String
ips, String body) {
List<Endpoint> dests = new ArrayList<Endpoint>();
try {
// do some validation on IP addresses header and barf.

// The header is delimited by commas.
//
StringTokenizer tokenizer = new StringTokenizer(ips, ",");

CamelContext ctx = new DefaultCamelContext();
while (tokenizer.hasMoreElements()) {
String ip = tokenizer.nextToken();
ActiveMQComponent amq = new ActiveMQComponent(ctx);

logger.info("Setting the broker URL to IP: " + ip);

amq.setBrokerURL("tcp://" + ip + ":61616");

Endpoint ep = amq.createEndpoint("activemq:topic:In.LocalServer");
dests.add(ep);
}
} catch (Exception e) {
// Let our monitoring take care of this..
logger.error("Unexpected exception while routing.", e);
}
return dests;
}

----

Appreciate any help.

cheers
- mdasari

--
View this message in context: http://old.nabble.com/How-to-route-a-message-to-remote-ActiveMQ-broker%28s%29-dynamically--tp28273566p28273566.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Search Discussions

  • Willem Jiang at Apr 19, 2010 at 3:23 am
    You created a new CamelContext and a ActiveMQComponent( for each new
    endpoint, that are expensive operation, maybe you can use a
    ActiveMQComponent cache with IPAddress as the index.

    Can you try to use the latest released version of Camel 1.x (Camel
    1.6.2) to see if the issue still there?

    Willem

    mdasari wrote:
    Hi,

    I needed to route a message from one ActiveMQ broker to one or more remote
    ActiveMQ brokers based on some runtime information.

    Lets say I've broker "central" and remote brokers "remote1", "remote2", ...
    "remoteN".
    The number of remote brokers can change over time and I wouldn't want to
    configure any beans or any kind of configuration in the activemq.xml of the
    "central" broker.

    The following what I tried, but it seems to be sending the message always to
    the first "remote" server that I used. Couple of points:

    0. I putup a POJO bean with RecipientList EIP.
    1. topic:Out.RemoteServers is the topic on the "central" broker
    2. topic:In.LocalServer is the topic on any "remote" broker.
    3. All applications that post messages to "central" broker add a message
    header with name "IPAddesses". The header value contain a list of IP
    addresses corresponding to the "remote" brokers.
    4. I'm using camel version 1.6.1.0

    The code looks as follows (trimmed for clarity)

    --------
    @Consume(uri = "topic:Out.RemoteServers")
    @RecipientList()
    public Collection<Endpoint> getRoutes(@Header(name = "IPAddresses") String
    ips, String body) {
    List<Endpoint> dests = new ArrayList<Endpoint>();
    try {
    // do some validation on IP addresses header and barf.

    // The header is delimited by commas.
    //
    StringTokenizer tokenizer = new StringTokenizer(ips, ",");

    CamelContext ctx = new DefaultCamelContext();
    while (tokenizer.hasMoreElements()) {
    String ip = tokenizer.nextToken();
    ActiveMQComponent amq = new ActiveMQComponent(ctx);

    logger.info("Setting the broker URL to IP: " + ip);

    amq.setBrokerURL("tcp://" + ip + ":61616");

    Endpoint ep = amq.createEndpoint("activemq:topic:In.LocalServer");
    dests.add(ep);
    }
    } catch (Exception e) {
    // Let our monitoring take care of this..
    logger.error("Unexpected exception while routing.", e);
    }
    return dests;
    }

    ----

    Appreciate any help.

    cheers
    - mdasari
  • Mdasari at Apr 19, 2010 at 5:28 pm
    Thanks Willem for your comments. I posted a simpler version of my code. My
    actual code was adding a camel Component (ActiveMQComponent) by using
    CamelContext.addComponent and I'm trying to retrieve the component by
    calling getComponent. The key is hash of the IP address, basically like
    CamelContext::getOrCreateComponent. At the moment it seems to be creating a
    new component every time though. I can work around by my own cache or some
    other means.

    But my real issue is usage of wrong IP address for delivery of the messages,
    it must be caching the first Endpoint there some where and using it again
    and again.

    I tried with version 1.6.2 there is no change in the behavior. I wonder if
    there is something wrong with my usage of Endpoint.

    Are there any other ways of implementing remote broker RecipientList EIP?

    cheers
    - mdasari



    willem.jiang wrote:
    You created a new CamelContext and a ActiveMQComponent( for each new
    endpoint, that are expensive operation, maybe you can use a
    ActiveMQComponent cache with IPAddress as the index.

    Can you try to use the latest released version of Camel 1.x (Camel
    1.6.2) to see if the issue still there?

    Willem

    mdasari wrote:
    Hi,

    I needed to route a message from one ActiveMQ broker to one or more
    remote
    ActiveMQ brokers based on some runtime information.

    Lets say I've broker "central" and remote brokers "remote1", "remote2",
    ...
    "remoteN".
    The number of remote brokers can change over time and I wouldn't want to
    configure any beans or any kind of configuration in the activemq.xml of
    the
    "central" broker.

    The following what I tried, but it seems to be sending the message always
    to
    the first "remote" server that I used. Couple of points:

    0. I putup a POJO bean with RecipientList EIP.
    1. topic:Out.RemoteServers is the topic on the "central" broker
    2. topic:In.LocalServer is the topic on any "remote" broker.
    3. All applications that post messages to "central" broker add a message
    header with name "IPAddesses". The header value contain a list of IP
    addresses corresponding to the "remote" brokers.
    4. I'm using camel version 1.6.1.0

    The code looks as follows (trimmed for clarity)

    --------
    @Consume(uri = "topic:Out.RemoteServers")
    @RecipientList()
    public Collection<Endpoint> getRoutes(@Header(name = "IPAddresses")
    String
    ips, String body) {
    List<Endpoint> dests = new ArrayList<Endpoint>();
    try {
    // do some validation on IP addresses header and barf.

    // The header is delimited by commas.
    //
    StringTokenizer tokenizer = new StringTokenizer(ips, ",");

    CamelContext ctx = new DefaultCamelContext();
    while (tokenizer.hasMoreElements()) {
    String ip = tokenizer.nextToken();
    ActiveMQComponent amq = new ActiveMQComponent(ctx);

    logger.info("Setting the broker URL to IP: " + ip);

    amq.setBrokerURL("tcp://" + ip + ":61616");

    Endpoint ep = amq.createEndpoint("activemq:topic:In.LocalServer");
    dests.add(ep);
    }
    } catch (Exception e) {
    // Let our monitoring take care of this..
    logger.error("Unexpected exception while routing.", e);
    }
    return dests;
    }

    ----

    Appreciate any help.

    cheers
    - mdasari
    --
    View this message in context: http://old.nabble.com/How-to-route-a-message-to-remote-ActiveMQ-broker%28s%29-dynamically--tp28273566p28287719.html
    Sent from the Camel - Users mailing list archive at Nabble.com.
  • Willem Jiang at Apr 20, 2010 at 1:34 am
    After digging the code, I found why your first "remote server" can
    receive the message.

    There is a ProducerCache for the RecipientList and it only take the
    endpoint's uri as the key(in camel the uri is the key of endpoint), and
    all your remote endpoint are with the same uri.

    For your case, you need to use CamelContext.addComponent to add the new
    ActiveMQComponent with differnent schema name like
    activemq + [hash of the IP address], then you create the endpoint with
    the name "activemq+[hash of the IP address]:topic:In.LocalServer".

    Willem

    mdasari wrote:
    Thanks Willem for your comments. I posted a simpler version of my code. My
    actual code was adding a camel Component (ActiveMQComponent) by using
    CamelContext.addComponent and I'm trying to retrieve the component by
    calling getComponent. The key is hash of the IP address, basically like
    CamelContext::getOrCreateComponent. At the moment it seems to be creating a
    new component every time though. I can work around by my own cache or some
    other means.

    But my real issue is usage of wrong IP address for delivery of the messages,
    it must be caching the first Endpoint there some where and using it again
    and again.

    I tried with version 1.6.2 there is no change in the behavior. I wonder if
    there is something wrong with my usage of Endpoint.

    Are there any other ways of implementing remote broker RecipientList EIP?

    cheers
    - mdasari



    willem.jiang wrote:
    You created a new CamelContext and a ActiveMQComponent( for each new
    endpoint, that are expensive operation, maybe you can use a
    ActiveMQComponent cache with IPAddress as the index.

    Can you try to use the latest released version of Camel 1.x (Camel
    1.6.2) to see if the issue still there?

    Willem

    mdasari wrote:
    Hi,

    I needed to route a message from one ActiveMQ broker to one or more
    remote
    ActiveMQ brokers based on some runtime information.

    Lets say I've broker "central" and remote brokers "remote1", "remote2",
    ...
    "remoteN".
    The number of remote brokers can change over time and I wouldn't want to
    configure any beans or any kind of configuration in the activemq.xml of
    the
    "central" broker.

    The following what I tried, but it seems to be sending the message always
    to
    the first "remote" server that I used. Couple of points:

    0. I putup a POJO bean with RecipientList EIP.
    1. topic:Out.RemoteServers is the topic on the "central" broker
    2. topic:In.LocalServer is the topic on any "remote" broker.
    3. All applications that post messages to "central" broker add a message
    header with name "IPAddesses". The header value contain a list of IP
    addresses corresponding to the "remote" brokers.
    4. I'm using camel version 1.6.1.0

    The code looks as follows (trimmed for clarity)

    --------
    @Consume(uri = "topic:Out.RemoteServers")
    @RecipientList()
    public Collection<Endpoint> getRoutes(@Header(name = "IPAddresses")
    String
    ips, String body) {
    List<Endpoint> dests = new ArrayList<Endpoint>();
    try {
    // do some validation on IP addresses header and barf.

    // The header is delimited by commas.
    //
    StringTokenizer tokenizer = new StringTokenizer(ips, ",");

    CamelContext ctx = new DefaultCamelContext();
    while (tokenizer.hasMoreElements()) {
    String ip = tokenizer.nextToken();
    ActiveMQComponent amq = new ActiveMQComponent(ctx);

    logger.info("Setting the broker URL to IP: " + ip);

    amq.setBrokerURL("tcp://" + ip + ":61616");

    Endpoint ep = amq.createEndpoint("activemq:topic:In.LocalServer");
    dests.add(ep);
    }
    } catch (Exception e) {
    // Let our monitoring take care of this..
    logger.error("Unexpected exception while routing.", e);
    }
    return dests;
    }

    ----

    Appreciate any help.

    cheers
    - mdasari
  • Mdasari at Apr 21, 2010 at 11:30 pm
    Thanks for the reply. In summary it works now.

    I actually tried this approach before and it didn't work then but now it
    works due to minor change. It appears
    org.apache.camel.impl.DefaultComponent.createEndpoint(...) doesn't like
    numeric name, when I tried earlier I used numeric hash off the IP address.
    It ran into following exception, and I assumed the URI schema has to follow
    naming convention used in the http://camel.apache.org/uris.html


    INFO | jvm 1 | 2010/04/16 18:18:04 | java.net.URISyntaxException:
    Illegal character in scheme name at index 0: 1466722955:topic:In.Servers
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    java.net.URI$Parser.fail(Unknown Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    java.net.URI$Parser.checkChars(Unknown Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    java.net.URI$Parser.checkChar(Unknown Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    java.net.URI$Parser.parse(Unknown Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at java.net.URI.<init>(Unknown
    Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    org.apache.camel.impl.DefaultComponent.createEndpoint(DefaultComponent.java:63)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    com.mycompany.infra.myrouter.MyRouterBean.getRoutes(MyRouterBean.java:73)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    java.lang.reflect.Method.invoke(Unknown Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    org.apache.camel.component.bean.MethodInfo.invoke(MethodInfo.java:163)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    org.apache.camel.component.bean.MethodInfo$1.proceed(MethodInfo.java:92)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:118)

    Now by prefixing "activemq" to the hash it works.


    Regarding your ProducerCache and RecipientList comment, isn't that a bug?

    thanks for the help.

    cheers
    - mdasari






    willem.jiang wrote:
    After digging the code, I found why your first "remote server" can
    receive the message.

    There is a ProducerCache for the RecipientList and it only take the
    endpoint's uri as the key(in camel the uri is the key of endpoint), and
    all your remote endpoint are with the same uri.

    For your case, you need to use CamelContext.addComponent to add the new
    ActiveMQComponent with differnent schema name like
    activemq + [hash of the IP address], then you create the endpoint with
    the name "activemq+[hash of the IP address]:topic:In.LocalServer".

    Willem

    mdasari wrote:
    Thanks Willem for your comments. I posted a simpler version of my code.
    My
    actual code was adding a camel Component (ActiveMQComponent) by using
    CamelContext.addComponent and I'm trying to retrieve the component by
    calling getComponent. The key is hash of the IP address, basically like
    CamelContext::getOrCreateComponent. At the moment it seems to be creating
    a
    new component every time though. I can work around by my own cache or
    some
    other means.

    But my real issue is usage of wrong IP address for delivery of the
    messages,
    it must be caching the first Endpoint there some where and using it again
    and again.

    I tried with version 1.6.2 there is no change in the behavior. I wonder
    if
    there is something wrong with my usage of Endpoint.

    Are there any other ways of implementing remote broker RecipientList EIP?

    cheers
    - mdasari



    willem.jiang wrote:
    You created a new CamelContext and a ActiveMQComponent( for each new
    endpoint, that are expensive operation, maybe you can use a
    ActiveMQComponent cache with IPAddress as the index.

    Can you try to use the latest released version of Camel 1.x (Camel
    1.6.2) to see if the issue still there?

    Willem

    mdasari wrote:
    Hi,

    I needed to route a message from one ActiveMQ broker to one or more
    remote
    ActiveMQ brokers based on some runtime information.

    Lets say I've broker "central" and remote brokers "remote1", "remote2",
    ...
    "remoteN".
    The number of remote brokers can change over time and I wouldn't want
    to
    configure any beans or any kind of configuration in the activemq.xml of
    the
    "central" broker.

    The following what I tried, but it seems to be sending the message
    always
    to
    the first "remote" server that I used. Couple of points:

    0. I putup a POJO bean with RecipientList EIP.
    1. topic:Out.RemoteServers is the topic on the "central" broker
    2. topic:In.LocalServer is the topic on any "remote" broker.
    3. All applications that post messages to "central" broker add a
    message
    header with name "IPAddesses". The header value contain a list of IP
    addresses corresponding to the "remote" brokers.
    4. I'm using camel version 1.6.1.0

    The code looks as follows (trimmed for clarity)

    --------
    @Consume(uri = "topic:Out.RemoteServers")
    @RecipientList()
    public Collection<Endpoint> getRoutes(@Header(name = "IPAddresses")
    String
    ips, String body) {
    List<Endpoint> dests = new ArrayList<Endpoint>();
    try {
    // do some validation on IP addresses header and barf.

    // The header is delimited by commas.
    //
    StringTokenizer tokenizer = new StringTokenizer(ips, ",");

    CamelContext ctx = new DefaultCamelContext();
    while (tokenizer.hasMoreElements()) {
    String ip = tokenizer.nextToken();
    ActiveMQComponent amq = new ActiveMQComponent(ctx);

    logger.info("Setting the broker URL to IP: " + ip);

    amq.setBrokerURL("tcp://" + ip + ":61616");

    Endpoint ep = amq.createEndpoint("activemq:topic:In.LocalServer");
    dests.add(ep);
    }
    } catch (Exception e) {
    // Let our monitoring take care of this..
    logger.error("Unexpected exception while routing.", e);
    }
    return dests;
    }

    ----

    Appreciate any help.

    cheers
    - mdasari
    --
    View this message in context: http://old.nabble.com/How-to-route-a-message-to-remote-ActiveMQ-broker%28s%29-dynamically--tp28273566p28322585.html
    Sent from the Camel - Users mailing list archive at Nabble.com.
  • Willem Jiang at Apr 22, 2010 at 1:37 am
    Hi,

    You need to turn the hashNumber into a String and put it after
    "activemq" instead of using it directly.

    I can reproduce the error by setting the component name with
    "123activemq", and the error is gone when I use "activemq123".

    Willem

    mdasari wrote:
    Thanks for the reply. In summary it works now.

    I actually tried this approach before and it didn't work then but now it
    works due to minor change. It appears
    org.apache.camel.impl.DefaultComponent.createEndpoint(...) doesn't like
    numeric name, when I tried earlier I used numeric hash off the IP address.
    It ran into following exception, and I assumed the URI schema has to follow
    naming convention used in the http://camel.apache.org/uris.html


    INFO | jvm 1 | 2010/04/16 18:18:04 | java.net.URISyntaxException:
    Illegal character in scheme name at index 0: 1466722955:topic:In.Servers
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    java.net.URI$Parser.fail(Unknown Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    java.net.URI$Parser.checkChars(Unknown Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    java.net.URI$Parser.checkChar(Unknown Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    java.net.URI$Parser.parse(Unknown Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at java.net.URI.<init>(Unknown
    Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    org.apache.camel.impl.DefaultComponent.createEndpoint(DefaultComponent.java:63)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    com.mycompany.infra.myrouter.MyRouterBean.getRoutes(MyRouterBean.java:73)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    java.lang.reflect.Method.invoke(Unknown Source)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    org.apache.camel.component.bean.MethodInfo.invoke(MethodInfo.java:163)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    org.apache.camel.component.bean.MethodInfo$1.proceed(MethodInfo.java:92)
    INFO | jvm 1 | 2010/04/16 18:18:04 | at
    org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:118)

    Now by prefixing "activemq" to the hash it works.


    Regarding your ProducerCache and RecipientList comment, isn't that a bug?

    thanks for the help.

    cheers
    - mdasari






    willem.jiang wrote:
    After digging the code, I found why your first "remote server" can
    receive the message.

    There is a ProducerCache for the RecipientList and it only take the
    endpoint's uri as the key(in camel the uri is the key of endpoint), and
    all your remote endpoint are with the same uri.

    For your case, you need to use CamelContext.addComponent to add the new
    ActiveMQComponent with differnent schema name like
    activemq + [hash of the IP address], then you create the endpoint with
    the name "activemq+[hash of the IP address]:topic:In.LocalServer".

    Willem

    mdasari wrote:
    Thanks Willem for your comments. I posted a simpler version of my code.
    My
    actual code was adding a camel Component (ActiveMQComponent) by using
    CamelContext.addComponent and I'm trying to retrieve the component by
    calling getComponent. The key is hash of the IP address, basically like
    CamelContext::getOrCreateComponent. At the moment it seems to be creating
    a
    new component every time though. I can work around by my own cache or
    some
    other means.

    But my real issue is usage of wrong IP address for delivery of the
    messages,
    it must be caching the first Endpoint there some where and using it again
    and again.

    I tried with version 1.6.2 there is no change in the behavior. I wonder
    if
    there is something wrong with my usage of Endpoint.

    Are there any other ways of implementing remote broker RecipientList EIP?

    cheers
    - mdasari



    willem.jiang wrote:
    You created a new CamelContext and a ActiveMQComponent( for each new
    endpoint, that are expensive operation, maybe you can use a
    ActiveMQComponent cache with IPAddress as the index.

    Can you try to use the latest released version of Camel 1.x (Camel
    1.6.2) to see if the issue still there?

    Willem

    mdasari wrote:
    Hi,

    I needed to route a message from one ActiveMQ broker to one or more
    remote
    ActiveMQ brokers based on some runtime information.

    Lets say I've broker "central" and remote brokers "remote1", "remote2",
    ...
    "remoteN".
    The number of remote brokers can change over time and I wouldn't want
    to
    configure any beans or any kind of configuration in the activemq.xml of
    the
    "central" broker.

    The following what I tried, but it seems to be sending the message
    always
    to
    the first "remote" server that I used. Couple of points:

    0. I putup a POJO bean with RecipientList EIP.
    1. topic:Out.RemoteServers is the topic on the "central" broker
    2. topic:In.LocalServer is the topic on any "remote" broker.
    3. All applications that post messages to "central" broker add a
    message
    header with name "IPAddesses". The header value contain a list of IP
    addresses corresponding to the "remote" brokers.
    4. I'm using camel version 1.6.1.0

    The code looks as follows (trimmed for clarity)

    --------
    @Consume(uri = "topic:Out.RemoteServers")
    @RecipientList()
    public Collection<Endpoint> getRoutes(@Header(name = "IPAddresses")
    String
    ips, String body) {
    List<Endpoint> dests = new ArrayList<Endpoint>();
    try {
    // do some validation on IP addresses header and barf.

    // The header is delimited by commas.
    //
    StringTokenizer tokenizer = new StringTokenizer(ips, ",");

    CamelContext ctx = new DefaultCamelContext();
    while (tokenizer.hasMoreElements()) {
    String ip = tokenizer.nextToken();
    ActiveMQComponent amq = new ActiveMQComponent(ctx);

    logger.info("Setting the broker URL to IP: " + ip);

    amq.setBrokerURL("tcp://" + ip + ":61616");

    Endpoint ep = amq.createEndpoint("activemq:topic:In.LocalServer");
    dests.add(ep);
    }
    } catch (Exception e) {
    // Let our monitoring take care of this..
    logger.error("Unexpected exception while routing.", e);
    }
    return dests;
    }

    ----

    Appreciate any help.

    cheers
    - mdasari
  • Ext2 at Apr 22, 2010 at 5:35 am
    Hi:
    Camel policy is very useful to define some custom wrapper features;
    But in camel 2.2 , it seems the policy only apply on the whole route; And it
    cannot define a policy on a special processor, is this true?
    And does camel 2.x support some mechanism to support define custom
    policy for specified processor(not the whole route)?
  • Willem Jiang at Apr 22, 2010 at 5:56 am
    No, you can apply the police per processor.
    The new added camel-spring-security is based on this camel policy feature.

    Willem

    ext2 wrote:
    Hi:
    Camel policy is very useful to define some custom wrapper features;
    But in camel 2.2 , it seems the policy only apply on the whole route; And it
    cannot define a policy on a special processor, is this true?
    And does camel 2.x support some mechanism to support define custom
    policy for specified processor(not the whole route)?

  • Ext2 at Apr 22, 2010 at 6:25 am

    Willem wrote:
    No, you can apply the police per processor.
    The new added camel-spring-security is based on this camel policy feature.
    how to configure such policy using spring? Or just dsl?

    Willem

    ext2 wrote:
    Hi:
    Camel policy is very useful to define some custom wrapper features;
    But in camel 2.2 , it seems the policy only apply on the whole route; And it
    cannot define a policy on a special processor, is this true?
    And does camel 2.x support some mechanism to support define custom
    policy for specified processor(not the whole route)?

  • Ext2 at Apr 22, 2010 at 6:38 am
    Thanks Willem:

    I got it; and using this feature I could define custom transaction range in
    a single route(need not separate them in different route just for
    transaction purpose);



    Willem wrote:
    No, you can apply the police per processor.
    The new added camel-spring-security is based on this camel policy feature.
    how to configure such policy using spring? Or just dsl?

    Willem

    ext2 wrote:
    Hi:
    Camel policy is very useful to define some custom wrapper features;
    But in camel 2.2 , it seems the policy only apply on the whole route; And it
    cannot define a policy on a special processor, is this true?
    And does camel 2.x support some mechanism to support define custom
    policy for specified processor(not the whole route)?

  • Ext2 at Apr 22, 2010 at 7:09 am
    Hi:

    The camel's transaction required the transacted-error-handler, but try-catch
    required no-error-handler. They will conflict; following is a sample that
    the try-catch cannot works while using transaction. but I am not sure if
    this is bug or just a camel's limit?

    For example, the following route :

    <doTry>
    <policy ref="PROPAGATION_REQUIRED">
    <pipeline>
    <to uri="ibatis:table.add?statementType=Insert"/>
    <bean ref="errorbean" method="raiseError"/>
    </pipeline>
    </policy>
    <doCatch>
    <exception>java.lang.Exception</exception>
    <bean ref="mybean" method="foo"/>
    </doCatch>

    As for normal understanding: the errorbean(just after ibatis) raise error,
    so the pipeline will marked as rollback status, but the exception is still
    exist, and the catch clause will be execute.And in camel, doCatch cannot be
    execute;
  • Claus Ibsen at Apr 22, 2010 at 7:27 am
    Move the <policy> before the <doTry>

    On Thu, Apr 22, 2010 at 9:08 AM, ext2 wrote:

    Hi:

    The camel's transaction required the transacted-error-handler, but try-catch
    required no-error-handler. They will conflict; following is a sample that
    the try-catch cannot works while using transaction. but I am not sure if
    this is bug or just a camel's limit?

    For example, the following route :

    <doTry>
    <policy ref="PROPAGATION_REQUIRED">
    <pipeline>
    <to uri="ibatis:table.add?statementType=Insert"/>
    <bean ref="errorbean" method="raiseError"/>
    </pipeline>
    </policy>
    <doCatch>
    <exception>java.lang.Exception</exception>
    <bean ref="mybean" method="foo"/>
    </doCatch>

    As for normal understanding: the errorbean(just after ibatis) raise error,
    so the pipeline will marked as rollback status, but the exception is still
    exist, and the catch clause will be execute.And in camel, doCatch cannot be
    execute;



    --
    Claus Ibsen
    Apache Camel Committer

    Author of Camel in Action: http://www.manning.com/ibsen/
    Open Source Integration: http://fusesource.com
    Blog: http://davsclaus.blogspot.com/
    Twitter: http://twitter.com/davsclaus
  • Ext2 at Apr 22, 2010 at 7:38 am
    Thanks Claus Ibsen:

    If we just consider this example, move policy before doTry could resolve it; but If we consider another situation:
    <doTry>
    ..some other operation ..
    <policy ref="...>
    transaction operations
    </policy>
    <docatch>
    </docatch>
    </dotry>

    At this time, I cannot move policy to <doTry/> easily; and also, if transaction operations raise exception, the doCatch cannot catch it;


    Claus Ibsen wrote:
    Move the <policy> before the <doTry>
    On Thu, Apr 22, 2010 at 9:08 AM, ext2 wrote:

    Hi:

    The camel's transaction required the transacted-error-handler, but try-catch
    required no-error-handler. They will conflict; following is a sample that
    the try-catch cannot works while using transaction. but I am not sure if
    this is bug or just a camel's limit?

    For example, the following route :

    <doTry>
    <policy ref="PROPAGATION_REQUIRED">
    <pipeline>
    <to uri="ibatis:table.add?statementType=Insert"/>
    <bean ref="errorbean" method="raiseError"/>
    </pipeline>
    </policy>
    <doCatch>
    <exception>java.lang.Exception</exception>
    <bean ref="mybean" method="foo"/>
    </doCatch>

    As for normal understanding: the errorbean(just after ibatis) raise error,
    so the pipeline will marked as rollback status, but the exception is still
    exist, and the catch clause will be execute.And in camel, doCatch cannot be
    execute;



    --
    Claus Ibsen
    Apache Camel Committer

    Author of Camel in Action: http://www.manning.com/ibsen/
    Open Source Integration: http://fusesource.com
    Blog: http://davsclaus.blogspot.com/
    Twitter: http://twitter.com/davsclaus
  • Willem Jiang at Apr 22, 2010 at 8:56 am
    How about using the onExeption[1] ?
    It works within the ErrorHandler, and it can do the same thing as
    doTry... doCatch does.

    [1]http://camel.apache.org/exception-clause.html

    Willem

    ext2 wrote:
    Thanks Claus Ibsen:

    If we just consider this example, move policy before doTry could resolve it; but If we consider another situation:
    <doTry>
    ..some other operation ..
    <policy ref="...>
    transaction operations
    </policy>
    <docatch>
    </docatch>
    </dotry>

    At this time, I cannot move policy to <doTry/> easily; and also, if transaction operations raise exception, the doCatch cannot catch it;


    Claus Ibsen wrote:
    Move the <policy> before the <doTry>
    On Thu, Apr 22, 2010 at 9:08 AM, ext2 wrote:

    Hi:

    The camel's transaction required the transacted-error-handler, but try-catch
    required no-error-handler. They will conflict; following is a sample that
    the try-catch cannot works while using transaction. but I am not sure if
    this is bug or just a camel's limit?

    For example, the following route :

    <doTry>
    <policy ref="PROPAGATION_REQUIRED">
    <pipeline>
    <to uri="ibatis:table.add?statementType=Insert"/>
    <bean ref="errorbean" method="raiseError"/>
    </pipeline>
    </policy>
    <doCatch>
    <exception>java.lang.Exception</exception>
    <bean ref="mybean" method="foo"/>
    </doCatch>

    As for normal understanding: the errorbean(just after ibatis) raise error,
    so the pipeline will marked as rollback status, but the exception is still
    exist, and the catch clause will be execute.And in camel, doCatch cannot be
    execute;

  • Ext2 at Apr 22, 2010 at 10:02 am
    Thanks willem:

    It seems that the onException has a little different difference to
    try-catch;

    That's :
    try-catch could recover the exception and continue to execute next processor
    in pipeline
    But on-Exception always stop execute when exception occurs in pipeline

    I am not very sure about this(But according the camel 2.2's source code ,it
    does so, and I have tried a simple sample to prove this); if it does only
    works as such means, the onException cannot replace try-catch completely;


    Willem wrote:
    How about using the onExeption[1] ?
    It works within the ErrorHandler, and it can do the same thing as
    doTry... doCatch does.
    [1]http://camel.apache.org/exception-clause.html

    Willem

    ext2 wrote:
    Thanks Claus Ibsen:

    If we just consider this example, move policy before doTry could resolve
    it; but If we consider another situation:
    <doTry>
    ..some other operation ..
    <policy ref="...>
    transaction operations
    </policy>
    <docatch>
    </docatch>
    </dotry>

    At this time, I cannot move policy to <doTry/> easily; and also, if
    transaction operations raise exception, the doCatch cannot catch it;

    Claus Ibsen wrote:
    Move the <policy> before the <doTry>
    On Thu, Apr 22, 2010 at 9:08 AM, ext2 wrote:

    Hi:

    The camel's transaction required the transacted-error-handler, but
    try-catch
    required no-error-handler. They will conflict; following is a sample that
    the try-catch cannot works while using transaction. but I am not sure if
    this is bug or just a camel's limit?

    For example, the following route :

    <doTry>
    <policy ref="PROPAGATION_REQUIRED">
    <pipeline>
    <to uri="ibatis:table.add?statementType=Insert"/>
    <bean ref="errorbean" method="raiseError"/>
    </pipeline>
    </policy>
    <doCatch>
    <exception>java.lang.Exception</exception>
    <bean ref="mybean" method="foo"/>
    </doCatch>

    As for normal understanding: the errorbean(just after ibatis) raise
    error,
    so the pipeline will marked as rollback status, but the exception is
    still
    exist, and the catch clause will be execute.And in camel, doCatch cannot
    be
    execute;

  • Ext2 at Oct 13, 2010 at 4:45 am
    Can I configure sync or asynchronous for individual processor in spring?
    If so , I could separate the CPU-cost actions and IO-Cost actions in
    different thread more clearly;
  • Willem Jiang at Oct 14, 2010 at 6:29 am
    There is a sync option which you can use the let the component to be
    sync or async.

    For the processor, if it does not implement AsyncProcessor interface, it
    will be ran synchronously.

    You can find more information the component which support the async
    option here[1].

    [1]http://camel.apache.org/asynchronous-routing-engine.html

    From Camel 2.4.0, we did some work to make the camel asyn
    On 10/13/10 12:45 PM, ext2 wrote:
    Can I configure sync or asynchronous for individual processor in spring?
    If so , I could separate the CPU-cost actions and IO-Cost actions in
    different thread more clearly;



    --
    Willem
    ----------------------------------
    Open Source Integration: http://www.fusesource.com
    Blog: http://willemjiang.blogspot.com (English)
    http://jnn.javaeye.com (Chinese)
    Twitter: http://twitter.com/willemjiang
  • Willem Jiang at Apr 22, 2010 at 7:17 am

    ext2 wrote:
    Thanks Willem:

    I got it; and using this feature I could define custom transaction range in
    a single route(need not separate them in different route just for
    transaction purpose);
    I'm afraid you cannot configure the transaction per process, as Camel
    transaction is based on Spring, and it uses thread location to hold the
    transaction information. You may need to do something yourself to
    implement the feature.
    Willem wrote:
    No, you can apply the police per processor.
    The new added camel-spring-security is based on this camel policy feature.
    how to configure such policy using spring? Or just dsl?

    Willem

    ext2 wrote:
    Hi:
    Camel policy is very useful to define some custom wrapper features;
    But in camel 2.2 , it seems the policy only apply on the whole route; And it
    cannot define a policy on a special processor, is this true?
    And does camel 2.x support some mechanism to support define custom
    policy for specified processor(not the whole route)?




  • Willem Jiang at Apr 22, 2010 at 7:28 am

    ext2 wrote:
    Thanks Willem:

    I got it; and using this feature I could define custom transaction range in
    a single route(need not separate them in different route just for
    transaction purpose);
    I just checked the code, the SpringTransactionPolicy is setting a new
    TransactionErrorHandler per route , not just wrapping the processor, so
    it works per route. If you want to change this , you need to write your
    owner TransactionPolicy.
    Willem wrote:
    No, you can apply the police per processor.
    The new added camel-spring-security is based on this camel policy feature.
    how to configure such policy using spring? Or just dsl?

    Willem

    ext2 wrote:
    Hi:
    Camel policy is very useful to define some custom wrapper features;
    But in camel 2.2 , it seems the policy only apply on the whole route; And it
    cannot define a policy on a special processor, is this true?
    And does camel 2.x support some mechanism to support define custom
    policy for specified processor(not the whole route)?




  • Willem Jiang at Apr 22, 2010 at 6:50 am

    ext2 wrote:
    Willem wrote:
    No, you can apply the police per processor.
    The new added camel-spring-security is based on this camel policy feature.
    how to configure such policy using spring? Or just dsl?
    Please check out the camel-spring-security example[1].

    <policy ref=xxx> or .policy("xxx").


    [1]https://cwiki.apache.org/confluence/display/CAMEL/Spring+Security+Example
    Willem

    ext2 wrote:
    Hi:
    Camel policy is very useful to define some custom wrapper features;
    But in camel 2.2 , it seems the policy only apply on the whole route; And it
    cannot define a policy on a special processor, is this true?
    And does camel 2.x support some mechanism to support define custom
    policy for specified processor(not the whole route)?


  • Ashwin Karpe at Apr 20, 2010 at 4:09 pm
    Hi,

    A better approach would be to create connection objects for the remote
    brokers and have them stored in JNDI or LDAP (if it is an embedded broker,
    have the app creating the broker store a connection object in JNDI/LDAP).

    The camel route can then simple grab a reference and send a message to the
    endpoint.

    You have a very interesting/non-traditional use-case here. Creating these
    connections on the fly in a camel route may not be the best approach.
    Providing an ability to select the best/optimal connection object and
    invoking on it is the better and more scalable way forward.

    Hope this helps.

    Cheers,

    Ashwin...



    mdasari wrote:
    Thanks Willem for your comments. I posted a simpler version of my code. My
    actual code was adding a camel Component (ActiveMQComponent) by using
    CamelContext.addComponent and I'm trying to retrieve the component by
    calling getComponent. The key is hash of the IP address, basically like
    CamelContext::getOrCreateComponent. At the moment it seems to be creating
    a new component every time though. I can work around by my own cache or
    some other means.

    But my real issue is usage of wrong IP address for delivery of the
    messages, it must be caching the first Endpoint there some where and using
    it again and again.

    I tried with version 1.6.2 there is no change in the behavior. I wonder if
    there is something wrong with my usage of Endpoint.

    Are there any other ways of implementing remote broker RecipientList EIP?

    cheers
    - mdasari



    willem.jiang wrote:
    You created a new CamelContext and a ActiveMQComponent( for each new
    endpoint, that are expensive operation, maybe you can use a
    ActiveMQComponent cache with IPAddress as the index.

    Can you try to use the latest released version of Camel 1.x (Camel
    1.6.2) to see if the issue still there?

    Willem

    mdasari wrote:
    Hi,

    I needed to route a message from one ActiveMQ broker to one or more
    remote
    ActiveMQ brokers based on some runtime information.

    Lets say I've broker "central" and remote brokers "remote1", "remote2",
    ...
    "remoteN".
    The number of remote brokers can change over time and I wouldn't want to
    configure any beans or any kind of configuration in the activemq.xml of
    the
    "central" broker.

    The following what I tried, but it seems to be sending the message
    always to
    the first "remote" server that I used. Couple of points:

    0. I putup a POJO bean with RecipientList EIP.
    1. topic:Out.RemoteServers is the topic on the "central" broker
    2. topic:In.LocalServer is the topic on any "remote" broker.
    3. All applications that post messages to "central" broker add a message
    header with name "IPAddesses". The header value contain a list of IP
    addresses corresponding to the "remote" brokers.
    4. I'm using camel version 1.6.1.0

    The code looks as follows (trimmed for clarity)

    --------
    @Consume(uri = "topic:Out.RemoteServers")
    @RecipientList()
    public Collection<Endpoint> getRoutes(@Header(name = "IPAddresses")
    String
    ips, String body) {
    List<Endpoint> dests = new ArrayList<Endpoint>();
    try {
    // do some validation on IP addresses header and barf.

    // The header is delimited by commas.
    //
    StringTokenizer tokenizer = new StringTokenizer(ips, ",");

    CamelContext ctx = new DefaultCamelContext();
    while (tokenizer.hasMoreElements()) {
    String ip = tokenizer.nextToken();
    ActiveMQComponent amq = new ActiveMQComponent(ctx);

    logger.info("Setting the broker URL to IP: " + ip);

    amq.setBrokerURL("tcp://" + ip + ":61616");

    Endpoint ep = amq.createEndpoint("activemq:topic:In.LocalServer");
    dests.add(ep);
    }
    } catch (Exception e) {
    // Let our monitoring take care of this..
    logger.error("Unexpected exception while routing.", e);
    }
    return dests;
    }

    ----

    Appreciate any help.

    cheers
    - mdasari

    -----
    ---
    Ashwin Karpe, Principal Consultant, PS - Opensource Center of Competence
    Progress Software Corporation
    14 Oak Park Drive
    Bedford, MA 01730
    ---
    +1-972-304-9084 (Office)
    +1-972-971-1700 (Mobile)
    ----
    Blog: http://opensourceknowledge.blogspot.com/


    --
    View this message in context: http://old.nabble.com/How-to-route-a-message-to-remote-ActiveMQ-broker%28s%29-dynamically--tp28273566p28287892.html
    Sent from the Camel - Users mailing list archive at Nabble.com.
  • Ext2 at Apr 22, 2010 at 7:46 am
    Thanks Willem:

    You are right;
    It seems I must do something else to support the feature(define custom
    transaction-section in single route).

    And the real problem is not only the spring's transaction-template, but also
    the camel's transaction support ;
    the camel's transaction always ask for transacted-error-handler, and they
    will sometimes conflict with other error-handle mechanism(etc: try-catch);


    Willem wrote;
    ext2 wrote:
    Thanks Willem:

    I got it; and using this feature I could define custom transaction range in
    a single route(need not separate them in different route just for
    transaction purpose);
    I'm afraid you cannot configure the transaction per process, as Camel
    transaction is based on Spring, and it uses thread location to hold the
    transaction information. You may need to do something yourself to
    implement the feature.
    Willem wrote:
    No, you can apply the police per processor.
    The new added camel-spring-security is based on this camel policy
    feature.
    how to configure such policy using spring? Or just dsl?

    Willem

    ext2 wrote:
    Hi:
    Camel policy is very useful to define some custom wrapper features;
    But in camel 2.2 , it seems the policy only apply on the whole route; And it
    cannot define a policy on a special processor, is this true?
    And does camel 2.x support some mechanism to support define custom
    policy for specified processor(not the whole route)?




  • Claus Ibsen at Apr 22, 2010 at 12:24 pm
    Hi

    I am opening up this in Camel 2.3.0 so you can use Policy at per
    processor level.

    I have created a ticket to track it
    https://issues.apache.org/activemq/browse/CAMEL-2667


    On Thu, Apr 22, 2010 at 9:45 AM, ext2 wrote:


    Thanks Willem:

    You are right;
    It seems I must do something else to support the feature(define custom
    transaction-section in single route).

    And the real problem is not only the spring's transaction-template, but also
    the camel's transaction support ;
    the camel's transaction always ask for transacted-error-handler, and they
    will sometimes conflict with other error-handle mechanism(etc: try-catch);


    Willem wrote;
    ext2 wrote:
    Thanks Willem:

    I got it; and using this feature I could define custom transaction range in
    a single route(need not separate them in different route just for
    transaction purpose);
    I'm afraid you cannot configure the transaction per process, as Camel
    transaction is based on Spring, and it uses thread location to hold the
    transaction information. You may need to do something yourself to
    implement the feature.
    Willem wrote:
    No, you can apply the police per processor.
    The new added camel-spring-security is based on this camel policy
    feature.
    how to configure such policy using spring? Or just dsl?

    Willem

    ext2 wrote:
    Hi:
    Camel policy is very useful to define some custom wrapper features;
    But in camel 2.2 , it seems the policy only apply on the whole route; And it
    cannot define a policy on a special processor, is this true?
    And does camel 2.x support some mechanism to support define custom
    policy for specified processor(not the whole route)?







    --
    Claus Ibsen
    Apache Camel Committer

    Author of Camel in Action: http://www.manning.com/ibsen/
    Open Source Integration: http://fusesource.com
    Blog: http://davsclaus.blogspot.com/
    Twitter: http://twitter.com/davsclaus

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupusers @
categoriescamel
postedApr 17, '10 at 1:51a
activeOct 14, '10 at 6:29a
posts23
users5
websitecamel.apache.org

People

Translate

site design / logo © 2022 Grokbase