Camel blueprint + karaf 企业总线架构

来源:互联网 发布:js防水涂料施工图集 编辑:程序博客网 时间:2024/05/21 06:25
Camel和Karaf都是apache的顶级应用。相信玩开源的人对apache顶级项目内心都有着崇敬的心情。最近的项目中有幸使用到了这两个框架。愿意与大家分享一下。 
Camel的强大不仅仅体现着配置路由上,他对很多开源中间件的集成也是So Nice. 可以说他的成功也是由于封装了真么多的中间件。真是功德无量啊! 
我在项目里使用到的中间件有Open mq 和 Netty。相信对于使用通讯中间件的朋友对这两个都不会太陌生。 
Camel 原生默认的MQ是ActiveMQ。要换成Open MQ还真费了一些周折呢。 
难点一,org.apache.camel.component.jms.JmsComponent需要自己实现JMSFactory并作为参数提供。 
可参见代码OpenMQConnectionFactory。 
难点二,properties文件的读取:将所有可变参数都放置于jar之外方便OSGI热部署。camel-blueprint 与Spring规范略有差异。参见blueprint-context-netty-loadbalancer.xml 
难点三,OSGI日志:默认的karaf日志都生成在karaf.log里。但是项目中需要分多个文件日志。参见修改Karaf.base/etc/org.ops4j.pax.logging.cfg 

标签:Apache Camel Karaf Blueprints Netty

代码片段(3)[全屏查看所有代码]

1. [代码]blueprint-context-netty-loadbalancer.xml     

01<?xml version="1.0" encoding="UTF-8"?>
02<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
03    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"
04    xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
05    xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws"xmlns:camel="http://camel.apache.org/schema/blueprint"
06    xsi:schemaLocation="
07            http://www.springframework.org/schema/beans
08            http://www.springframework.org/schema/beans/spring-beans.xsd
09      http://www.springframework.org/schema/context
10      http://www.springframework.org/schema/context/spring-context.xsd
11      http://www.osgi.org/xmlns/blueprint/v1.0.0
12      http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
13 
14 
15 
16    <bean id="properties"
17        class="org.apache.camel.component.properties.PropertiesComponent">
18        <property name="location" value="file:${karaf.base}/deploy/camel-loadbalance.properties" />
19    <bean id="service"
20        class="cn.com.cardinfo.service.nocardpayment.action.PackageAction" />
21    <bean id="logService"class="cn.com.cardinfo.service.nocardpayment.action.LogAction" />
22    <!-- open mq config -->
23    <bean id="openmq" class="org.apache.camel.component.jms.JmsComponent">
24        <property name="connectionFactory" ref="mqConnectionFactory" />
25    </bean>
26    <bean id="mqConnectionFactory"
27        class="cn.com.cardinfo.service.nocardpayment.jmsfactory.OpenMQConnectionFactory"
28        scope="singleton">
29        <property name="configuration">
30            <props>
31                <prop key="imqAddressList">localhost:7676</prop>
32                <prop key="imqDefaultPassword">admin</prop>
33                <prop key="imqDefaultUsername">admin</prop>
34                <prop key="imqAddressListBehavior">PRIORITY</prop>
35            </props>
36        </property>
37    </bean>
38    <camelContext xmlns="http://camel.apache.org/schema/blueprint">
39        <route id="tcpReceiver">
40            <from
41                uri="netty:tcp://{{balance.host}}:{{balance.port}}?textline=true&amp;delimiter=NULL&amp;noReplyLogLevel=ERROR" />
42            <bean ref="service" method="createReport" />
43            <to uri="direct:loadbalance" />
44        </route>
45 
46        <route id="JmsReceiver">
47            <from
48                uri="openmq:queue:{{queue}}?exchangePattern={{exchangePattern}}&amp;replyTo={{replyTo}}&amp;replyToType={{replyToType}}&amp;concurrentConsumers={{concurrentConsumers}}&amp;maxConcurrentConsumers={{maxConcurrentConsumers}}"></from>
49            <bean ref="service" method="createReport" />
50            <to uri="direct:loadbalance" />
51        </route>
52 
53        <route id="loadbalancer">
54            <from uri="direct:loadbalance" />
55            <loadBalance>
56                <roundRobin />
57                <camel:to uri="netty:tcp://{{node.host1}}:{{node.port1}}?sync=true" />
58                <camel:to uri="netty:tcp://{{node.host2}}:{{node.port2}}?sync=true" />
59            </loadBalance>
60            <bean ref="logService" method="log" />
61            <log message="${body}" />
62        </route>
63    </camelContext>
64</blueprint>

2. [代码][Java]代码     

01import java.util.Properties;
02 
03import javax.jms.JMSException;
04 
05import com.sun.messaging.InvalidPropertyException;
06import com.sun.messaging.jmq.jmsclient.JMSXAQueueConnectionFactoryImpl;
07 
08public class OpenMQConnectionFactory extends JMSXAQueueConnectionFactoryImpl {
09 
10    private static final long serialVersionUID = 1L;
11    private Properties configuration;
12 
13    public void setConfiguration(Properties configuration) {
14        this.configuration = configuration;
15    }
16 
17    /**
18     * Returns a single configuration property value given the property name.
19     *
20     * @param propname
21     *            The name of the configuration property.
22     *
23     * @return The value of the configuration property <code>propname</code>.
24     *
25     * @exception InvalidPropertyException
26     *                If an invalid property name is being requested. The
27     *                Exception string is the name of the invalid property.
28     */
29    @Override
30    public String getProperty(String propname) throws JMSException {
31        if (propname == null) {
32            throw new InvalidPropertyException(propname);
33        }
34        // Convert JMQ prefix if present to imq prefix
35        if ((propname.length() > 3) && (propname.startsWith("JMQ"))) {
36            propname = "imq" + propname.substring(3);
37        }
38        String propval = (String) configuration.get(propname);
39        if (propval == null) {
40            super.getProperty(propname);
41        }
42        if (propval == null) {
43            throw new InvalidPropertyException(propname);
44        }
45        return propval;
46    }
47 
48}

3. [代码]log conf     

01# Root logger
02log4j.rootLogger=INFO, out, osgi:*
03log4j.throwableRenderer=org.apache.log4j.OsgiThrowableRenderer
04 
05# To avoid flooding the log when using DEBUG level on an ssh connection and doing log:tail
06log4j.logger.org.apache.sshd.server.channel.ChannelSession = INFO
07 
08# CONSOLE appender not used by default
09log4j.appender.stdout=org.apache.log4j.ConsoleAppender
10log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
11log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %-32.32C %4L | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n
12 
13# File appender
14log4j.appender.out=org.apache.log4j.RollingFileAppender
15log4j.appender.out.layout=org.apache.log4j.PatternLayout
16log4j.appender.out.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %-32.32C %4L | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n
17log4j.appender.out.file=${karaf.data}/log/karaf.log
18log4j.appender.out.append=true
19log4j.appender.out.maxFileSize=1MB
20log4j.appender.out.maxBackupIndex=10
21 
22# Sift appender
23log4j.appender.sift=org.apache.log4j.sift.MDCSiftingAppender
24log4j.appender.sift.key=bundle.name
25log4j.appender.sift.default=karaf
26log4j.appender.sift.appender=org.apache.log4j.FileAppender
27log4j.appender.sift.appender.layout=org.apache.log4j.PatternLayout
28log4j.appender.sift.appender.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %-32.32C %4L | %m%n
29log4j.appender.sift.appender.file=${karaf.data}/log/$\\{bundle.name\\}.log
30log4j.appender.sift.appender.append=true
31 
32# nocard appender
33log4j.appender.nocard=org.apache.log4j.RollingFileAppender
34log4j.appender.nocard.layout=org.apache.log4j.PatternLayout
35log4j.appender.nocard.layout.ConversionPattern=%d{ISO8601} | %-32.32C{1} | %m%n
36log4j.appender.nocard.file=${karaf.data}/log/nocard.log
37log4j.appender.nocard.append=true
38 
39# mpi appender
40log4j.appender.mpi=org.apache.log4j.RollingFileAppender
41log4j.appender.mpi.layout=org.apache.log4j.PatternLayout
42log4j.appender.mpi.layout.ConversionPattern=%d{ISO8601} | %-32.32C{1} | %m%n
43log4j.appender.mpi.file=${karaf.data}/log/mpi.log
44log4j.appender.mpi.append=true
45 
46#Log nocardpayment commands to separate file
47log4j.logger.cn.com.cardinfo.service.nocardpayment=INFO, nocard
48log4j.additivity.cn.com.cardinfo.service.nocardpayment=false
49 
50#Log mpi commands to separate file
51log4j.logger.mpi=INFO, mpi
52log4j.additivity.mpi=false

原创粉丝点击