ESB构架的MULE

ESB构架的MULE(声明:本文章来自飞马扬鞭的博客 http://hi.baidu.com/luohuazju,尊重作者的知识产权,向原作者致敬!)

mule,就是传说中的一个ESB构架的实现,初步试用了一下,感觉它圈地圈得厉害,把 AXISXFIREPOP3,SMTP,SOCKET,HTTP,JMS等通信连接方式都包括进来,可能是为了一些和老系统的接口 下载的地址是: http://mule.codehaus.org/display/MULE/Home 下载后放置在路径: D:/tool/mule- 1.4.1 配置MULE_HOME PATH里面把BIN加入进去 在路径D:/tool/mule-1.4.1/conf下有个配置文件 wrapper.conf 打开后修改 wrapper.java.classpath.2=%MULE_HOME%/lib/user/*.jar wrapper.java.classpath.3=%MULE_HOME%/lib/boot/*.jar wrapper.java.classpath.4=E:/project/megaeyes/Mail2Jms/WebRoot/WEB-INF/classes 这里配置的是MULE启动的时候要加载的JAR包和CLASSPATH 我的项目是MAIL2JMS,所以我直接指向了自己的CLASS目录,这样我的任何修改都直接生效了, 另外可以执行他的例子,ECHO.BAT 仿造他的例子,我自己写了一个从邮件服务器JAMES上收到信息后转发给ACTIVE-MQ的东东 类比较少,一一贴出来,实现类EmailManagerImpl.java: package com.megaeyes.service.impl; import org.mule.components.simple.LogComponent; import org.mule.umo.UMOEventContext; import com.megaeyes.service.EmailManager; /** * * @author sillycat.luo * */ public class EmailManagerImpl extends LogComponent implements EmailManager { public Object onCall(UMOEventContext context) throws Exception { // 调用基类打印出日志 // super.onCall(context); // 调用transfer 得到对象 Object o = context.getTransformedMessage(); return o; } } 消息类,MessageBean.java: /* * Created on 2007-7-23 11:40:12 * @author hejing */ package com.megaeyes.sms.gateway.databean; import java.io.Serializable; public class MessageBean implements Serializable{     private static final long serialVersionUID = -1353347933934679190L;     private String topic;           //标题     private String msgSrcID;        //消息来源编号     private String msgTypeID;       //消息类型编号     private String deviceName;      //设备名称     private String deviceTypeName; //设备类型名称     private String deviceIP;        //设备IP     private String msgTypeName;     //消息类型名称     private String msgID;           //消息流水号     private String severityName;    //告警级别名称     private String faultTime;       //故障产生时间     private String content;         //内容             /**      * @return Returns the content.      */     public String getContent() {         return content;     }     /**      * @param content The content to set.      */     public void setContent(String content) {         this.content = content;     }     /**      * @return Returns the topic.      */     public String getTopic() {         return topic;     }     /**      * @param topic The topic to set.      */     public void setTopic(String topic) {         this.topic = topic;     }     /**      * @return Returns the deviceIP.      */     public String getDeviceIP() {         return deviceIP;     }     /**      * @param deviceIP The deviceIP to set.      */     public void setDeviceIP(String deviceIP) {         this.deviceIP = deviceIP;     }     /**      * @return Returns the deviceName.      */     public String getDeviceName() {         return deviceName;     }     /**      * @param deviceName The deviceName to set.      */     public void setDeviceName(String deviceName) {         this.deviceName = deviceName;     }     /**      * @return Returns the deviceTypeName.      */     public String getDeviceTypeName() {         return deviceTypeName;     }     /**      * @param deviceTypeName The deviceTypeName to set.      */     public void setDeviceTypeName(String deviceTypeName) {         this.deviceTypeName = deviceTypeName;     }     /**      * @return Returns the faultTime.      */     public String getFaultTime() {         return faultTime;     }     /**      * @param faultTime The faultTime to set.      */     public void setFaultTime(String faultTime) {         this.faultTime = faultTime;     }     /**      * @return Returns the msgID.      */     public String getMsgID() {         return msgID;     }     /**      * @param msgID The msgID to set.      */     public void setMsgID(String msgID) {         this.msgID = msgID;     }     /**      * @return Returns the msgSrcID.      */     public String getMsgSrcID() {         return msgSrcID;     }     /**      * @param msgSrcID The msgSrcID to set.      */     public void setMsgSrcID(String msgSrcID) {         this.msgSrcID = msgSrcID;     }     /**      * @return Returns the msgTypeID.      */     public String getMsgTypeID() {         return msgTypeID;     }     /**      * @param msgTypeID The msgTypeID to set.      */     public void setMsgTypeID(String msgTypeID) {         this.msgTypeID = msgTypeID;     }     /**      * @return Returns the msgTypeName.      */     public String getMsgTypeName() {         return msgTypeName;     }     /**      * @param msgTypeName The msgTypeName to set.      */     public void setMsgTypeName(String msgTypeName) {         this.msgTypeName = msgTypeName;     }     /**      * @return Returns the severityName.      */     public String getSeverityName() {         return severityName;     }     /**      * @param severityName The severityName to set.      */     public void setSeverityName(String severityName) {         this.severityName = severityName;     }     } 转换邮件信息的类EmailMessageTransformer.java: package com.megaeyes.utils; import java.io.IOException; import javax.mail.BodyPart; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMultipart; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dom4j.Document; import org.mule.transformers.AbstractTransformer; import org.mule.umo.transformer.TransformerException; import com.megaeyes.sms.gateway.databean.MessageBean; /** * BEAN转换类 * * @author sillycat.luo * */ public class EmailMessageTransformer extends AbstractTransformer { protected Log log = LogFactory.getLog(EmailMessageTransformer.class); public EmailMessageTransformer() { // 初始化要注册的对象类型 registerSourceType(MimeBodyPart.class); registerSourceType(Message.class); registerSourceType(String.class); setReturnClass(String.class); } /** * 实际调用转化类的方法 */ protected Object doTransform(Object src, String encoding)    throws TransformerException { MimeBodyPart mail = null; if (src instanceof MimeBodyPart) {    mail = (MimeBodyPart) src; } else {    log.error("email transfer should get MimeBodyPart src!"); } String returnString = ""; MessageBean message = null; try {    Object o = mail.getContent();    if (o instanceof String) {     returnString = (String) o;    } else if (o instanceof MimeMultipart) {     MimeMultipart mime = (MimeMultipart) o;     if (mime != null) {      BodyPart body = mime.getBodyPart(0);      if (body != null) {       returnString = (String) body.getContent();      }     }    } else {     log       .error("there is unknow part from the MimebodyPart.getContent");    } } catch (IOException e) {    log.error(e); } catch (MessagingException e) {    log.error("e"); } // transform string 2 object message = transFromString2Message(returnString); return message; } /** * 转化类的工具类 * * @param src *            String like <root><name>sillycat.luo</name></root> * @return MessageBean Object */ private MessageBean transFromString2Message(String src) { MessageBean message = null; if (StringUtil.isBlank(src)) {    log.error("src 2 transfer can't be null");    return message; } Document doc = XmlFileUtil.getDocumentSaxByXmlStr(src); if (doc != null) {    message = new MessageBean();    message.setMsgSrcID(XmlFileUtil.getStringValue("MsgSrcID", doc));    message.setMsgTypeID(XmlFileUtil.getStringValue("FaultType", doc));    message      .setDeviceName(XmlFileUtil        .getStringValue("DeviceName", doc));    message.setDeviceTypeName(XmlFileUtil.getStringValue("DeviceType",      doc));    message.setDeviceIP(XmlFileUtil.getStringValue("DeviceIp", doc));    message.setMsgTypeName(XmlFileUtil.getStringValue("FaultTypeName",      doc));    message.setMsgID(XmlFileUtil.getStringValue("FaultID", doc));    message      .setSeverityName(XmlFileUtil        .getStringValue("Severity", doc));    message.setFaultTime(XmlFileUtil.getStringValue("FaultTime", doc)); } else {    log.error("xml doc string dom4j parse error!"); } return message; } } 最主要的配置文件拉,email-config.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mule-configuration PUBLIC "-//MuleSource //DTD mule-configuration XML V1.0//EN"                                 "http://mule.mulesource.org/dtds/mule-configuration.dtd"> <mule-configuration id="Mule_Echo_Sample" version="1.0"> <description>This is the email mule ESB system</description> <connector name="activeMQConnector" className="org.mule.providers.jms.JmsConnector"> <properties>    <property name="connectionFactoryJndiName"     value="ConnectionFactory" />    <property name="jndiInitialFactory"     value="com.megaeyes.utils.ActiveMQInitialContextFactory" />    <property name="specification" value="1.1" />    <property name="jndiDestinations" value="true" />    <property name="jndiProviderUrl"     value="tcp://localhost:61616" />    <map name="connectionFactoryProperties">     <property name="brokerURL"      value="tcp://localhost:61616" />    </map> </properties> </connector> <transformers> <transformer name="JMSMessageToString"    className="com.megaeyes.utils.JMSMessageTransformer"    returnClass="java.lang.String" /> <transformer name="HttpRequestToSoapRequest"    className="org.mule.providers.soap.transformers.HttpRequestToSoapRequest" /> <transformer name="EmailMessageTransformer"    className="com.megaeyes.utils.EmailMessageTransformer">    <properties>     <property name="checkFrequency" value="2000" />     <property name="deleteReadMessages" value="true" />    </properties> </transformer> </transformers> <model name="emailSample"> <mule-descriptor name="MailUM"    implementation="com.megaeyes.service.impl.EmailManagerImpl">    <inbound-router>     <endpoint address="pop3://carl:kaishi@sillycat.com"      transformers="EmailMessageTransformer" />    </inbound-router>    <outbound-router>     <router      className="org.mule.routing.outbound.OutboundPassThroughRouter">      <endpoint address="jms://ConnectionFactory"       connector="activeMQConnector" />     </router>    </outbound-router> </mule-descriptor> <!--    <mule-descriptor name="ReSumeUM"    implementation="com.megaeyes.service.impl.EmailManagerImpl">    <inbound-router>    <endpoint address="jms://ConnectionFactory"    connector="activeMQConnector" transformers="JMSMessageToString"/>    </inbound-router>    <outbound-router>       <router    className="org.mule.routing.outbound.OutboundPassThroughRouter">    <endpoint address="stream://System.out" />    </router>    </outbound-router>    </mule-descriptor> --> </model> </mule-configuration> 一个批处理执行文件,email.bat: @echo off call "%MULE_HOME%/bin/mule.bat" -config ./email-config.xml 这样就可以运行了,启动后会拦截所有发送到carl@sillycat.com的邮件内容,然后拼装成为MessageBean.java放置在activeMQ queue里面。

最近又要使用MULE了。 其实我不是很喜欢这个东东,因为用的人少,资料比较少。

这次的应用主要是需要在受到POP3的邮件后,对取道邮件内容,根据邮件内容,连接数据库 查询资料,根据这个资料判断进入哪个ENDPOINT 比较以前的MULE,增加了如下两个内容: 1、连接ORACLE数据库 2、在执行ENDPOINT的时候增加了一个判断 3、顺道把ACTIVEMQ的配置修改到了SPRING

注意: 比较郁闷的是,一些比如ORACLE的驱动,IBATISJAR包都要拷贝到MULELIBUSER里面去,不然会找不到类

主要针对MULE的配置文件,email-config.xml做了修改: <container-context    className="org.mule.extras.spring.SpringContainerContext"    name="spring">    <properties>     <property name="configFile"      value="classpath:/applicationContext.xml" />    </properties> </container-context>

配置了,启动MULE的时候,启动SPRINGCONTAINER <connector name="activeMQConnector"    className="org.mule.providers.jms.JmsConnector">    <properties>     <property name="specification" value="1.1" />     <container-property name="connectionFactory"      reference="activeMqConnectionFactory" container="spring" />    </properties> </connector>

ACTIVEMQ的配置转移到了SPRING的配置文件:applicationContext.xml中。

<model name="emailSample">    <mule-descriptor name="EmailActiveMQUM"     implementation="com.megaeyes.service.impl.EmailActiveMQManagerImpl">     <inbound-router>      <endpoint name="pop3email"       address="pop3://gateway:megaeyes@192.168.10.103"       transformers="EmailMessageTransformer">       <properties>        <property name="checkFrequency" value="10000" />        <property name="deleteReadMessages"         value="true" />       </properties>      </endpoint>     </inbound-router>     <outbound-router>      <router       className="com.megaeyes.utils.TransactionJoiningRouter">       <endpoint name="fileEndpoint" address="file:///d:/logs">        <properties>         <property name="filename" value="emailActiveMQ.txt" />         <property name="outputAppend" value="true" />        </properties>       </endpoint>       <endpoint name="jmsEndpointOne" address="jms://MessageOne"        connector="activeMQConnector" />       <endpoint name="jmsEndpointTwo" address="jms://MessageTwo"        connector="activeMQConnector" />      </router>     </outbound-router>    </mule-descriptor> </model> ENDPOINT里面的OUTBOUND-ROUTER做了改变,改为用自己类来处理: com.megaeyes.utils.TransactionJoiningRouter 这里加入了根据内容来判断选择不同的ENDPOINT的机制,选择把结果存放到不同的队列MESSAGEONE或者MESSAGETWO

在自己写的类 com.megaeyes.utils.TransactionJoiningRouter.java中: UMOEndpoint endpoint = getEndpoint(i, message);

     MessageBean o = (MessageBean) message.getPayload();      // System.out.println("message class name: "      // + o.getClass().getName());      // System.out.println("endpoint name: " + endpoint.getName());      // TODO use the name of the endpoint to check if proess      if (endpoint.getName().equalsIgnoreCase("fileEndpoint")) {       continue;      }      endpoint.setRemoteSync(false);      try {       dispatch(session, message, endpoint);      } catch (UMOException e) {       throw new CouldNotRouteOutboundMessageException(message,         endpoint); } 可以得到MESSAGE中传递过来的信息,根据信息判断是否需要dispatch当前的ENDPOINT,当然ENDPOINT的名字在这里也可以得到

贴出完整的email-config.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mule-configuration PUBLIC "-//MuleSource //DTD mule-configuration XML V1.0//EN"                                 "http://mule.mulesource.org/dtds/mule-configuration.dtd">

<mule-configuration id="Mule_Echo_Sample" version="1.0">

<description>This is the email mule ESB system</description>

<container-context    className="org.mule.extras.spring.SpringContainerContext"    name="spring">    <properties>     <property name="configFile"      value="classpath:/applicationContext.xml" />    </properties> </container-context>

<connector name="activeMQConnector"    className="org.mule.providers.jms.JmsConnector">    <properties>     <property name="specification" value="1.1" />     <container-property name="connectionFactory"      reference="activeMqConnectionFactory" container="spring" />    </properties> </connector>

<!-- <connector name="jdbcConnector"    className="org.mule.providers.jdbc.JdbcConnector">    <properties>     <container-property name="dataSource" reference="dataSource"      container="spring" />    </properties> </connector> -->

<transformers>    <transformer name="JMSMessageToString"     className="com.megaeyes.utils.JMSMessageTransformer"     returnClass="java.lang.String" />    <transformer name="HttpRequestToSoapRequest"     className="org.mule.providers.soap.transformers.HttpRequestToSoapRequest" />    <transformer name="EmailMessageTransformer"     className="com.megaeyes.utils.EmailMessageTransformer">    </transformer> </transformers>

<model name="emailSample">    <mule-descriptor name="EmailActiveMQUM"     implementation="com.megaeyes.service.impl.EmailActiveMQManagerImpl">     <inbound-router>      <endpoint name="pop3email"       address="pop3://gateway:megaeyes@192.168.10.103"       transformers="EmailMessageTransformer">       <properties>        <property name="checkFrequency" value="10000" />        <property name="deleteReadMessages"         value="true" />       </properties>      </endpoint>     </inbound-router>     <outbound-router>      <router       className="com.megaeyes.utils.TransactionJoiningRouter">       <endpoint name="fileEndpoint" address="file:///d:/logs">        <properties>         <property name="filename" value="emailActiveMQ.txt" />         <property name="outputAppend" value="true" />        </properties>       </endpoint>       <endpoint name="jmsEndpointOne" address="jms://MessageOne"        connector="activeMQConnector" />       <endpoint name="jmsEndpointTwo" address="jms://MessageTwo"        connector="activeMQConnector" />      </router>     </outbound-router>    </mule-descriptor> </model> </mule-configuration>

applicationContext.xml配置文件其实和spring的配置文件很相似: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans default-autowire="byName"> <bean id="activeMqConnectionFactory"    class="org.apache.activemq.ActiveMQConnectionFactory">    <property name="brokerURL">     <value>tcp://localhost:61616</value>    </property> </bean>

<bean id="dataSource"    class="org.apache.commons.dbcp.BasicDataSource"    destroy-method="close">    <property name="driverClassName">     <value>oracle.jdbc.driver.OracleDriver</value>    </property>    <property name="url">     <value>jdbc:oracle:thin:@192.168.10.11:1688:test</value>    </property>    <property name="username">     <value>dev</value>    </property>    <property name="password">     <value>dev</value>    </property> </bean>

<bean id="sqlMapClient"    class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">    <property name="configLocation">     <value>classpath:/sqlmap-config.xml</value>    </property>    <property name="useTransactionAwareDataSource" value="true"></property> </bean> <bean id="emailJmsDao"    class="com.megaeyes.dao.impl.EmailJmsDaoImpl" /> </beans>

自己的判断类TransactionJoiningRouter.java:

package com.megaeyes.utils;

import org.mule.impl.MuleMessage; import org.mule.routing.outbound.FilteringOutboundRouter; import org.mule.umo.UMOException; import org.mule.umo.UMOMessage; import org.mule.umo.UMOSession; import org.mule.umo.endpoint.UMOEndpoint; import org.mule.umo.routing.CouldNotRouteOutboundMessageException; import org.mule.umo.routing.RoutingException;

import com.megaeyes.sms.gateway.databean.MessageBean;

public class TransactionJoiningRouter extends FilteringOutboundRouter {

public UMOMessage route(UMOMessage message, UMOSession session,     boolean synchronous) throws RoutingException {    final int endpointsCount = endpoints.size();    if (endpoints == null || endpointsCount == 0) {

   }    if (enableCorrelation != ENABLE_CORRELATION_NEVER) {     boolean correlationSet = message.getCorrelationId() != null;     if (correlationSet       && (enableCorrelation == ENABLE_CORRELATION_IF_NOT_SET)) {      logger        .debug("CorrelationId is already set, not setting Correlation group size");     } else {      // the correlationId will be set by the AbstractOutboundRouter      message.setCorrelationGroupSize(endpointsCount);     }    }    MessageBean o = (MessageBean) message.getPayload();

   String mobileNumberStr = o.getTargetNumber();

   if (StringUtil.isNotBlank(mobileNumberStr)) {     // 透传,分析号码     String[] mobileNumbers = mobileNumberStr.split(",");     if (mobileNumbers != null && mobileNumbers.length > 0) {      for (int j = 0; j < mobileNumbers.length; j++) {       String temp = mobileNumbers[j];       System.out.println(j + " temp number :" + temp);       if (checkIfMobilePhoneNumber(temp)) {        //update the targetNumber        MessageBean tMessage = (MessageBean)o.clone();        tMessage.setTargetNumber(temp);        UMOMessage tObj = new MuleMessage(tMessage);        //手机号码 放队列1        processMethod(tObj, session, endpointsCount, "jmsEndpointOne");       }else{        MessageBean tMessage = (MessageBean)o.clone();        tMessage.setTargetNumber(temp);        UMOMessage tObj = new MuleMessage(tMessage);        //小灵通号码 放队列2        processMethod(tObj, session, endpointsCount, "jmsEndpointTwo");       }      }     }    } else {     // 不透传 放队列1     processMethod(message, session, endpointsCount, "jmsEndpointOne");    }

   return null; }

private void processMethod(UMOMessage message, UMOSession session,     int endpointsCount, String methodName)     throws CouldNotRouteOutboundMessageException {    synchronized (endpoints) {     for (int i = 0; i < endpointsCount; i++) {

     UMOEndpoint endpoint = getEndpoint(i, message);

     if (!endpoint.getName().equalsIgnoreCase(methodName)) {       continue;      }

     endpoint.setRemoteSync(false);      try {       dispatch(session, message, endpoint);      } catch (UMOException e) {       throw new CouldNotRouteOutboundMessageException(message,         endpoint);      }     }    } }

// 小灵通   区号+电话号(78位) // 手机     手机号码一定是13**********11位数 private boolean checkIfMobilePhoneNumber(String mobileNumber) {    boolean flag = false;    if(StringUtil.isBlank(mobileNumber)){     return flag;    }    if(mobileNumber.startsWith("0")){     //小灵通     flag = false;    }else{     //手机     flag = true;    }    return flag; } }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值