Showing posts with label Camel. Show all posts
Showing posts with label Camel. Show all posts

Monday, February 15, 2010

Configure the camel-cxf endpoint advance features from URI

As you know CXF provides the advance configuration on the CXF endpoints, such as interceptors, features etc.

In camel-cxf we leverage the CXF configuration which is based on the Spring to provide the same thing as CXF does, but in Camel we have the classical URI configuration which means you can configure the endpoint's by using the URI parameters. URI is easy way for the user as it support the DSL and Spring configuration smoothly, and you can deal with the URI as string to add your customer properties.

How can we configure the interceptor or the features on the camel-cxf endpoints by just setting few option parameters?
The key of the answer is you can set the bus of the camel-cxf endpoint by using the URI option bus.
You can set the features or interceptor on the bus as CXF bus configuration does and then set the camel-cxf endpoint URI like this "cxf://Address?Bus=#cxf&...".

Thursday, March 12, 2009

Set the properties for Camel Context

If you want to do customer configuration on the inner component of Camel 2.0, how can you achieve that? You may say to use the system properties is a easy way.
But if I want to configure the component per camel context, as you know there could be more than one camel context per JVM.
I just introduced a property configuration per camel context in the Camel 2.0, so you want to configure the cachedOutputStream of Camel , you can do it like this.

With the java code

Map<String, String> properties = new HashMap<String, String>();
properties.put(CachedOutputStream.THRESHOLD, "1000");
properties.put(CachedOutputStream.TEMP_DIR, "/tmp/camel");
camelContext..setProperties(properties);



With Spring configuration

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<properties>
<property key="CamelCachedOutputStreamThreshold" value="10000"/>
</properties>
<property key="CamelCachedOutputStreamOutputDirectory" value="/tmp/camel"/>
</properties>
<property key="the key of properties" value="the value as string"/>
</properties>
...
<camelContext>

Monday, February 23, 2009

How to use extra camel componets in servicemix-camel

When I was doing the spring clean up work for fuse ESB 3.x. I came across the issues of using the extra camel components within ESB3.x's servicemix-camel component.

Since Servicemix3's has same hierarchies of the class loaders with the J2EE application server, and the components the class loader is separated with the SU's. And Camel has lots of components, we just include the camel-core and camel-spring components in the servicemix-camel by default. When the user want to use other camel component, they always add the camel-xxx component into their SU lib.
In this way if there is a class which is loaded from the different SU classloader and registered into the camel-core's registry by servicemix-camel component , we will faced on the typical class cast exception in Servicemix3. Basically this exception is caused by the same class is loaded by different class loader.

Let me give you a real world issue.

In this case, when the SU redeployed, it will create a new deployer which will create a application context with the class loader of servicemix-camel component, and then using the SU's class loader to create a camel context.
Since the SU is redeployed, Servicemix will create a new class loader to load the SU's lib jars and resources.
When the SU initial the rmi component, boom , we meet the situation of same component loaded with different class loader, The class cast exception is thrown out.

Note, In Servicemix4 , we will not get that kind of issue , since the OSGI will help us to manage the relationship of the jars :).

The solution is putting the camel-xxx component and third part jars into servicemix-camel component's lib. You need to check out the servicemix-camel component's pom.xml and recompile the servicemix-camel component by adding the camel-xxx component dependency.

Let me take the latest servicemix-camel as an example

1. Checking out the servicemix-camel component's pom


svn co http://svn.apache.org/repos/asf/servicemix/components/engines/servicemix-camel/trunk/pom.xml


2. If you need camel-rmi component , you just put the dependency into the pom.xml


<dependency>
<groupid>org.apache.camel</groupid>
<artifactid>camel-rmi</artifactid>
<version>${camel-version}</version>
</dependency>


3. Running "mvn install" and copy the servicemix-camel-*.zip into the deploy directory

4. Write your servicemix-camel SU, make sure you don't include any camel relates jars into the SU's lib, you can use the <scope>provided</scope> to not packing the artifact.


<dependency>
<groupid>org.apache.camel</groupid>
<artifactid>camel-rmi</artifactid>
<version>${camel-version}</version>
<scope>provided</scope>
</dependency>

Wednesday, January 21, 2009

What's new in Camel 2.0

I have been asked by lots of friend who are using or going to using Camel, what's new in Camel 2.0.
I just found Claus set up a good wiki page for all these kind informations.
Some high lights includes:

New features:
  • Make more endpoints easily configurable as beans in Spring XML.
  • Improve the DSL
  • ...
API Changes
  • Remove the use of generics on Component, Exchange, Producer, Consumer
  • Change to use verb for EIP action
  • ...


You can find the release notes about Camel 2.0 (Working in progress) here.

Sunday, January 11, 2009

Camel中的几个重要概念之 Processor

Processor

Processor接口是用来表示一个处理消息的类, 这个接口的定义如下。

Processor
package org.apache.camel;
public interface Processor {
void process(Exchange exchange) throws Exception;
}

注意Process()方法中的参数是一个Exchange而不是一个Message。 这样的定义提供了更大的灵活性。例如我们可以在Process方法中调用exchange.getIn()来获取输入的消息,并处理它。 如果在处理过程中发生了错误,我们可以通过调用 exchange.setException() 设置这个异常。

对于一个应用开发这来说,他们可以通过实现Process接口来实现他们的业务逻辑。然后,在Camel内部库中, 这里有很多类通过实现了Process接口来提供EIP book中设计模式的实现。例如 ChoiceProcessor就实现了一个消息路由的模式。它通过使用和if-then-else相当的定义来完成一个消息从一个输入队列到多个输出队列的路由。另一个例子就是FilterProcessor,当通过这个Processor的处理的消息不能满足某个条件时,这个消息将被抛弃。

Camel中的几个重要概念之 Message和Exchange

Message

Message 接口提供了一个对单个消息的抽象,这些消息可以是一个请求,回复或者是一个异常。
对于每个Camel是支持的通讯技术来说,都需要提供一个Message接口的实现。例如JmsMessage就提供了一个Message接口的JMS实现. 在message接口中提供一个get/set方法来访问message id, body 以及message中每个单独header。
而exchange接口则表示了对message exchange的抽象, 也就是说一个请求消息以及与之对应的应答消息或者异常消息肯定会与一个Exchange相关联。对于Camel来说,请求和应答以及异常消息都分别被称为in, out 以及 fault message。
对于每个Camel所支持的通信技术来说来说,都需要一个实现了Exchang接口的的类。 例如JmsExchange 类就提供了一个Exchange接口的JMS实现。对于Exchange接口来说它提供的公共的API很有限。 但是对于实现Exchange的具体的类来说,它可以添加很多与其支持的通讯协议相关操作。
应用层的程序应该很少直接访问Exchange(或者是实现Exchange的类)。由于Camel很多类都大量使用了有关(Exchange)的泛型定义,所有你会在很多的类和方法中看到Exchange接口的身影。

Camel 中的几个重要概念之 CamelContext与CamelTemplate

CamelContext

CamelContext是对Camel 运行时的一个抽象, 一般来说一个应用里面会有一个CamelContext 对象。一个典型的Camel 应用按照下面几个步骤执行。
  1. 创建一个CamelContext对象。
  2. 向CamelContext对象中添加Endpoints或者是Components
  3. 向CamelContext对象中添加路由(routes)规则
  4. 调用CamelContext的start() 方法,这样可以启动Camel内部有关消息发送,接收,处理所使用的线程。
  5. 当调用CamelContext的stop() 方法时,Camel 会将妥善关闭所有endpoint和Camel内部的线程。注意在调用CamelContext.start() 方法时并不一定阻塞, 而是在启动完每个Comonent和Endpoint的内部线程后start() 方法返回。而CamelContext.stop()方法会等待所有Endpoint和Component的内部线程都结束后 stop() 方法才返回。如果你没有在你的Camel 应用程序中调用CamelContext.start() 方法,那么由于内部线程并没有被创建那些消息将不会被处理。 如果你没有在你的Camel应用程序中调用CamelContext.stop()方法,那你你的应用将不会正常退出。如果你在一个JUnit 测试没有调用CamelContext.stop()方法,这可能会造成消息不能被完整地处理,而导致测试运行失败。

CamelTemplate

Camel曾经使用一个叫CamelClient的类来发送消息, 后来为了和其他的open-source项目类似功能的模块例如Spring中 TransactionTemplate 和 JmsTemplate, 命名一致而改名为CamelTemplate。
这个CamelTemplate(注现在已经改名为ProducerTemplate)类对CamelContext进行了一个简单的封装。在CamelTemplate中有向一个Endpoint(将在Endpoint中讨论)发送Message或者Exchange的方法, 这部分的内容将在 Message和Exchange中进行讨论。 CamelTemplate提供了一条向Camel内部路由中的Endpoint发送消息的道路, 这样消息就可以在Camel内部的路由规则(参考 Routes,RouteBuilders 和JAVA DSL)里面流动而到达指定的目标节点了。

Camel中的几个重要概念之 Endpoint

前段时间和一些朋友聊过Apache Camel, 他们都反映一个问题就是有关Camel构架的介绍文档很少。其实在Camel发行包中所带的文档Camel Manual 就有一段对Camel内部设计有一个比较好的介绍。我在这里把其中大部分的内容翻译成了中文,希望能对大家了解Camel有所帮助。

Endpoint
Endpoint这个词以前经常被用来描述进程间通信。例如,在客户端与服务器之间的通讯,客户端是一个Endpoint和服务器是另外一个Endpoint。根据不同的情况下,一个Endpoint可能指的地址,如一个TCP通信的(主机:端口)对,也可能是指与这个地址相对应的一个软件实体。例如,如果大家使用“ www.example.com:80 ”来描述一个Endpoint。这些Endpoint可能是指实际的端口上的主机名称(即地址) ,也可能是指与地址相关的的网页服务器(即在这个地址之上运行的软件地址) 。通常情况下,这种地址和在这个地址之上运行的软件之前的区别并不是一个重要问题。

一些中间件技术可以使一些软件实体的绑定在相同的物理地址上。例如, CORBA是一种面向对象的远程过程调用( RPC )的中间件标准。如果一个CORBA的服务器进程包含几个对象,客户端可以与这些在同一物理地址(主机:端口)之上的任意对象进行通讯 ,但当客户端想与特定对象进行通讯是, 需要指定这个对象的逻辑地址(在CORBA中称为IOR)。 IOR是由物理地址(主机:端口) ,以及一个唯一识别的对象在其服务器进程标识所组成。 (IOR还包含了与此本次讨论无关其他一些额外的信息。)当谈论CORBA的时候,有些人可能会使用“endpoint”来描述CORBA的服务器的物理地址,而其他人可能使用Endpoint来描述一个CORBA对象的逻辑地址,和其他人可能会使用这个词来描述下面这些:

  • CORBA的服务器进程的物理地址(主机:端口)
  • CORBA对象的逻辑地址(主机:端口加上编号)
  • CORBA的服务器进程(相对重量级的软件实体)
  • 一个基于CORBA对象(一个轻量级的软件实体)

正因为如此,你可以看到Endpoint这个词至少在两方面是模糊的。首先,它可能是指一个地址或联络软件实体在该地址。其次,粒度上可能是模糊的:一个重量级与轻量级的软件实体,或物理地址与逻辑地址。了解了Endpoint这个名词在不同场景下的不同描述可以帮助我们更好地理解为什么Camel中的Endpoint。

Camel中的Endpoint支持许多不同的通信技术。以下是Camel所支持Endpoint。

  • 一个JMS队列。
  • 一个Web服务。
  • 一个文件。文件可能听起来不是一个典型的Endoint端点。但是你可以这么想,一些应用系统会把信息写到一个文件中,然后另一个应用程序可能读取该文件获得这一信息。
  • 一个FTP服务器。
  • 一个电子邮件地址。客户可以发送邮件到电子邮件地址,和一台服务器可以读取的这个从邮件服务器传入的邮件。
  • 一个POJO (普通旧Java对象)。