Camel流程扩展探索——多个流程是否可行?

camel框架是一个成熟的流程框架,一般而言我们只是把它应用到一个完整的流程中,而一些逻辑的分支也是在“一个”流程中去控制的。现在如果在流程的源头就需要分支,即拿到源数据,

但是我们需要走不同的流程。(这里不再局限在“一个”流程了!),是否可行呢?下面来探讨。

 

首先,建立流程的配置:

context-route.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:drools="http://drools.org/schema/drools-spring"
	xmlns:camel="http://camel.apache.org/schema/spring"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://drools.org/schema/drools-spring http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-container/drools-spring/src/main/resources/org/drools/container/spring/drools-spring-1.0.0.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
	
	<bean id="fileConverter" class="com.kayak.itmon.web.demo.camel.FileConvertProcessor" />
	<bean id="fileConverter2" class="com.kayak.itmon.web.demo.camel.FileConvertProcessor2" />
	<bean id="fileConverter3" class="com.kayak.itmon.web.demo.camel.FileConvertProcessor3" />
	
	<camelContext id="camel" autoStartup="true" xmlns="http://camel.apache.org/schema/spring">
		 <template id="producerTemplate" />
		<threadPool id="pool" threadName="Thread-dataformat"
			poolSize="50" maxPoolSize="200" maxQueueSize="250" rejectedPolicy="CallerRuns" />
		
		 
		 <route>  
            <from uri="direct://AstartData"/>  
            <process ref="A1"/>  
            <to uri="direct://startA" />
            
        </route> 
        
         <route> 
	        <from uri="direct://startA"/>  
         	<threads executorServiceRef="pool">
         		<process ref="A2" />
         	</threads> 
        </route>
        
        <!-- B流程 -->
         <route>  
            <from uri="direct://BstartData"/>  
            <process ref="B1"/>  
            <to uri="direct://startB" />
        </route> 
        
         <route> 
	        <from uri="direct://startB"/>  
         	<threads executorServiceRef="pool">
         		<process ref="B2" />
         	</threads> 
        </route>
	</camelContext>
	
	<!-- camel的一些bean -->
	<bean id="A1" class="com.kayak.itmon.web.demo.camel.ACamel1"></bean>
	<bean id="A2" class="com.kayak.itmon.web.demo.camel.ACamel2"></bean>
	<bean id="B1" class="com.kayak.itmon.web.demo.camel.BCamel1"></bean>
	<bean id="B2" class="com.kayak.itmon.web.demo.camel.BCamel2"></bean>
</beans>

 

其中,流程类如下

public class ACamel1 implements Processor {

	@Override
	public void process(Exchange exchange) throws Exception {
		String ret = (String) exchange.getIn().getBody();
		System.out.println("进入到A流程的第一步。。 " + ret);
		ret = ret.toUpperCase();
		exchange.getIn().setBody(ret);
	}

}

public class ACamel2 implements Processor {

	@Override
	public void process(Exchange exchange) throws Exception {
		String ret = (String) exchange.getIn().getBody();
		System.out.println("进入到A流程的第二步。。" + ret);
	}

}

public class BCamel1 implements Processor {

	@Override
	public void process(Exchange exchange) throws Exception {
		String ret = (String) exchange.getIn().getBody();
		System.out.println("进入到B流程的第一步。。  " + ret);
		ret = ret + "hahha";
		exchange.getIn().setBody(ret);
	}

}

public class BCamel2 implements Processor {

	@Override
	public void process(Exchange exchange) throws Exception {
		String ret = (String) exchange.getIn().getBody();
		System.out.println("进入到B流程的第二步。。 " + ret);
	}

}

 

在测试类里发起流程:

public static void main(String[] args) {
		ApplicationContext ctx = new FileSystemXmlApplicationContext("WebRoot/WEB-INF/conf/xxxxx/context-route.xml");
		System.out.println(ctx);
		
		ProducerTemplate template = ctx.getBean("producerTemplate", ProducerTemplate.class);
		//template.sendBody("direct://AstartData");
		template.sendBody("direct://AstartData", "okoko");
        template.sendBody("direct://BstartData", "okoko");
		try {
			template.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
}

 

会发现,打印结果如下:

进入到A流程的第一步。。 okoko

进入到A流程的第二步。。OKOKO

进入到B流程的第一步。。  okoko

进入到B流程的第二步。。 okokohahha

 

说明,同一个数据源(这个demo用的是okoko模拟),可以“分发”给若干个(这里是用2个测试)流程来处理,且流程与流程之间拿到的同一数据源,

但他们的处理互不干涉。只要在ProducerTemplate.sendBody("direct://xxx", data); send多个即可

(注:不要嵌套流程,否则容易出错。即在本例中,

<route>  
            <from uri="direct://AstartData"/>  
            <process ref="A1"/>  
            <to uri="direct://startA" />
            <to uri="direct://BstartData" />
</route>

 

构成了嵌套,这是不合理的!direct://AstartData和direct://BstartData(这两个都是流程的源头uri)都应该在java类中启动!)

 

btw, 说下在测试的过程中,出现的一些异常及解决办法吧,记录一下。

 

1)xml里from uri="xxx"里面要加direct://前缀  形如from uri="direct://xxx", 否则会出现异常:

Exception in thread "main" org.apache.camel.RuntimeCamelException: org.apache.camel.FailedToStartRouteException: Failed to start route route4 because of Multiple consumers for the same endpoint is not allowed: Endpoint[direct://start]

at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1316)

at org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:120)

at org.apache.camel.spring.CamelContextFactoryBean.onApplicationEvent(CamelContextFactoryBean.java:280)

at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:151)

at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:128)

at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:331)

at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:773)

at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)

at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:140)

at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:84)

at com.kayak.itmon.web.demo.camel.CamelStart.main(CamelStart.java:9)

Caused by: org.apache.camel.FailedToStartRouteException: Failed to start route route4 because of Multiple consumers for the same endpoint is not allowed: Endpoint[direct://start]

at org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRouteConsumers(DefaultCamelContext.java:2019)

at org.apache.camel.impl.DefaultCamelContext.doStartRouteConsumers(DefaultCamelContext.java:1995)

at org.apache.camel.impl.DefaultCamelContext.safelyStartRouteServices(DefaultCamelContext.java:1923)

at org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRoutes(DefaultCamelContext.java:1702)

at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:1583)

at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:1444)

at org.apache.camel.spring.SpringCamelContext.doStart(SpringCamelContext.java:179)

at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:60)

at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:1412)

at org.apache.camel.spring.SpringCamelContext.maybeStart(SpringCamelContext.java:228)

at org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:118)

... 9 more

 

2)不要有相同的uri="direct://xxx"  否则会出现异常:

Exception in thread "main" org.apache.camel.RuntimeCamelException: org.apache.camel.FailedToCreateRouteException: Failed to create route route1: Route[[From[AstartData]] -> [process[ref:A1], To[direct://st... because of No endpoint could be found for: AstartData, please check your classpath contains the needed Camel component jar.

at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1316)

at org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:120)

at org.apache.camel.spring.CamelContextFactoryBean.onApplicationEvent(CamelContextFactoryBean.java:280)

at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:151)

at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:128)

at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:331)

at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:773)

at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)

at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:140)

at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:84)

at com.kayak.itmon.web.demo.camel.CamelStart.main(CamelStart.java:9)

Caused by: org.apache.camel.FailedToCreateRouteException: Failed to create route route1: Route[[From[AstartData]] -> [process[ref:A1], To[direct://st... because of No endpoint could be found for: AstartData, please check your classpath contains the needed Camel component jar.

at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:177)

at org.apache.camel.impl.DefaultCamelContext.startRoute(DefaultCamelContext.java:722)

at org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:1789)

at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:1575)

at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:1444)

at org.apache.camel.spring.SpringCamelContext.doStart(SpringCamelContext.java:179)

at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:60)

at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:1412)

at org.apache.camel.spring.SpringCamelContext.maybeStart(SpringCamelContext.java:228)

at org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:118)

... 9 more

Caused by: org.apache.camel.NoSuchEndpointException: No endpoint could be found for: AstartData, please check your classpath contains the needed Camel component jar.

at org.apache.camel.util.CamelContextHelper.getMandatoryEndpoint(CamelContextHelper.java:52)

at org.apache.camel.model.RouteDefinition.resolveEndpoint(RouteDefinition.java:187)

at org.apache.camel.impl.DefaultRouteContext.resolveEndpoint(DefaultRouteContext.java:108)

at org.apache.camel.impl.DefaultRouteContext.resolveEndpoint(DefaultRouteContext.java:114)

at org.apache.camel.model.FromDefinition.resolveEndpoint(FromDefinition.java:72)

at org.apache.camel.impl.DefaultRouteContext.getEndpoint(DefaultRouteContext.java:90)

at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:857)

at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:172)

... 18 more

 

3)java代码里templete.sendBody("direct://xxxx")必须要加第2个参数 如:templete.sendBody("direct://xxxx", data) 否则会出现异常:

Exception in thread "main" java.lang.IllegalArgumentException: defaultEndpoint must be specified

at org.apache.camel.util.ObjectHelper.notNull(ObjectHelper.java:294)

at org.apache.camel.impl.DefaultProducerTemplate.getMandatoryDefaultEndpoint(DefaultProducerTemplate.java:445)

at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:342)

at com.kayak.itmon.web.demo.camel.CamelStart.main(CamelStart.java:13)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值