servicemix 实例 -- 参考open source ESBs in action这本书
1. 项目结构
2. bean服务处理单元
1)Person类
1 package esb.chapter3; 2 3 import java.io.StringWriter; 4 5 import javax.xml.transform.Result; 6 import javax.xml.transform.Source; 7 import javax.xml.transform.Transformer; 8 import javax.xml.transform.TransformerConfigurationException; 9 import javax.xml.transform.TransformerException; 10 import javax.xml.transform.TransformerFactory; 11 import javax.xml.transform.stream.StreamResult; 12 13 import org.jibx.runtime.JiBXException; 14 15 import esb.util.framework.JiBXUtil; 16 17 public class Person { 18 19 private String customerNumber; 20 private String firstName; 21 private String lastName; 22 private String street; 23 private String city; 24 private String state; 25 private String zip; 26 private String phone; 27 28 public String toString(){ 29 return "[custNum=" + customerNumber + ", firstName=" + firstName 30 + ", lastName=" + lastName + ", city=" + city + " ]"; 31 } 32 33 //省略setter,getter方法 81 83 public static void main(String[] args) throws JiBXException, TransformerException { 84 85 86 Person person = new Person(); 87 88 person.setCustomerNumber("0001"); 89 person.setFirstName("wentang"); 90 person.setLastName("xu"); 91 person.setStreet("street-1"); 92 person.setCity("city-1"); 93 person.setState("state-1"); 94 person.setZip("111111"); 95 person.setPhone("11111111111"); 96 97 Source source = JiBXUtil.marshalDocument(person, "utf-8"); 98 99 /* 100 * Source => XML 101 */ 102 TransformerFactory transformerFactory = TransformerFactory.newInstance(); 103 Transformer transformer = transformerFactory.newTransformer(); 104 105 StringWriter sw = new StringWriter(); 106 transformer.transform(source, new StreamResult(sw)); 107 108 System.out.println("result:\n" + sw.toString()); 109 } 110 }
2) SimpleTransformerBean类
1 package esb.chapter3; 2 3 import javax.annotation.Resource; 4 import javax.jbi.component.ComponentContext; 5 import javax.jbi.messaging.DeliveryChannel; 6 import javax.jbi.messaging.ExchangeStatus; 7 import javax.jbi.messaging.MessageExchange; 8 import javax.jbi.messaging.MessagingException; 9 import javax.jbi.messaging.NormalizedMessage; 10 import javax.jbi.servicedesc.ServiceEndpoint; 11 import javax.xml.namespace.QName; 12 13 import org.apache.commons.logging.Log; 14 import org.apache.commons.logging.LogFactory; 15 import org.apache.servicemix.MessageExchangeListener; 16 import org.jibx.runtime.JiBXException; 17 18 import esb.util.framework.JiBXUtil; 19 20 public class SimpleTransformerBean implements MessageExchangeListener { 21 22 private static final Log LOGGER = LogFactory.getLog(SimpleTransformerBean.class); 23 24 @Resource 25 private DeliveryChannel channel; 26 27 @Resource 28 private ComponentContext compContext; 29 30 @Override 31 public void onMessageExchange(MessageExchange exchange) throws MessagingException { 32 33 if (exchange.getStatus() != ExchangeStatus.ACTIVE) return; 34 35 try { 36 /* 37 * 从in中解析出Person对象 38 */ 39 Person p = (Person) JiBXUtil.unmarshalDocument(exchange.getMessage("in").getContent(), Person.class); 40 LOGGER.info("receive person " + p.getFirstName() + " " + p.getLastName()); 41 p.setFirstName("John"); 42 43 exchange.setStatus(ExchangeStatus.DONE); 44 channel.send(exchange); 45 46 ServiceEndpoint targetEndpoint = compContext.getEndpoint( 47 new QName("http://opensourceesb/chapter3/", "JMSProviderService"), 48 "outQueueWriter"); 49 MessageExchange exch = channel.createExchangeFactory(targetEndpoint).createInOnlyExchange(); 50 NormalizedMessage normalizedMsg = exch.createMessage(); 51 normalizedMsg.setContent(JiBXUtil.marshalDocument(p, "UTF-8")); 52 exch.setMessage(normalizedMsg, "in"); 53 channel.send(exch); 54 } catch (JiBXException e) { 55 LOGGER.error("JBI bean exception: ", e); 56 throw new MessagingException("Error transforming object to or from XML"); 57 } 58 } 59 }
3) Jibx工具转换类
1 package esb.util.framework; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.ByteArrayOutputStream; 5 import java.io.StringReader; 6 import java.io.StringWriter; 7 8 import javax.xml.transform.Source; 9 import javax.xml.transform.Transformer; 10 import javax.xml.transform.TransformerException; 11 import javax.xml.transform.TransformerFactory; 12 import javax.xml.transform.dom.DOMSource; 13 import javax.xml.transform.stream.StreamResult; 14 import javax.xml.transform.stream.StreamSource; 15 16 import org.jibx.runtime.BindingDirectory; 17 import org.jibx.runtime.IMarshallingContext; 18 import org.jibx.runtime.IUnmarshallingContext; 19 import org.jibx.runtime.JiBXException; 20 import org.w3c.dom.Node; 21 22 public class JiBXUtil { 23 24 public static Object unmarshalDocument(Node node, Class targetClass) throws JiBXException { 25 return unmarshalDocument(new DOMSource(node), targetClass); 26 } 27 28 /** 29 * 从源source中解封出目标类targetClass对象 30 * @param source 31 * @param targetClass 32 * @return 33 * @throws JiBXException 34 */ 35 public static Object unmarshalDocument(Source source, Class targetClass) throws JiBXException { 36 Object result = null; 37 try { 38 IUnmarshallingContext ctx = BindingDirectory.getFactory(targetClass).createUnmarshallingContext(); 39 //toString(source), 把Source对象转换为XML字符串形式 40 result = ctx.unmarshalDocument(new StringReader(toString(source))); 41 } catch (Exception e) { 42 throw new JiBXException("Error unmarshalling XML to Object", e); 43 } 44 return result; 45 } 46 47 /** 48 * 把对象src根据encoding编码封送到Source对象中 49 * @param src 50 * @param encoding -- utf-8 51 * @return 52 * @throws JiBXException 53 */ 54 public static Source marshalDocument(Object src, String encoding) throws JiBXException { 55 Source result = null; 56 57 try { 58 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 59 IMarshallingContext ctx = BindingDirectory.getFactory(src.getClass()).createMarshallingContext(); 60 ctx.marshalDocument(src, encoding, null, bOut); 61 result = new StreamSource(new ByteArrayInputStream(bOut.toByteArray())); 62 } catch (Exception e) { 63 throw new JiBXException("Error marshalling XML to Object", e); 64 } 65 return result; 66 } 67 68 /** 69 * 把Source对象转换为XML字符串形式 70 * @param source 71 * @return 72 * @throws TransformerException 73 */ 74 private static String toString(Source source) throws TransformerException { 75 TransformerFactory tf = TransformerFactory.newInstance(); 76 StringWriter sw = new StringWriter(); 77 Transformer trans = tf.newTransformer(); 78 trans.transform(source, new StreamResult(sw)); 79 String result = sw.toString(); 80 System.out.println("result " + result); 81 return result; 82 } 83 }
4) Person => XML 映射文件, mapping.xml
1 <binding> 2 <mapping name="person" class="esb.chapter3.Person"> 3 <value name="customer-number" field="customerNumber" /> 4 <value name="first-name" field="firstName" /> 5 <value name="last-name" field="lastName" /> 6 <value name="street" field="street" /> 7 <value name="city" field="city" /> 8 <value name="state" field="state" /> 9 <value name="zip" field="zip" /> 10 <value name="phone" field="phone" /> 11 </mapping> 12 </binding>
5) 对eclipse项目z_servicemix/bin目录下的.class文件,进行绑定再编译
<?xml version="1.0" encoding="UTF-8"?> <project name="JiBX-compiler" default="bind-compile" basedir="."> <property name="jibx-lib" value="D:/osesbinaction/libraries/jibx/lib" /> <taskdef name="bind" classname="org.jibx.binding.ant.CompileTask" classpath="D:/osesbinaction/libraries/jibx/lib/jibx-bind.jar" /> <target name="bind-compile"> <bind verbose="true" load="true" binding="resources/chapter3/mapping.xml"> <classpath> <pathelement path="bin"/> <pathelement location="${jibx-lib}/jibx-run.jar"/> </classpath> </bind> </target> </project>
6) 运行Person类main方法。查看转换效果
7) xbean.xml
1 <beans xmlns:bean="http://servicemix.apache.org/bean/1.0" 2 xmlns:esb="http://opensourceesb/chapter3/"> 3 4 5 <classpath> 6 <location>.</location> 7 <location>bcel.jar</location> 8 <location>jibx-bind.jar</location> 9 <location>jibx-extras.jar</location> 10 <location>jibx-run.jar</location> 11 <location>qdox-1.6.1.jar</location> 12 <location>stax-api.jar</location> 13 <location>wstx-asl.jar</location> 14 <location>xmlpull_1_1_4.jar</location> 15 <location>xpp3.jar</location> 16 </classpath> 17 18 <bean:endpoint service="esb:beanService" endpoint="beanEndpoint" 19 bean="#SimpleTransformer" /> 20 21 <bean id="SimpleTransformer" class="esb.chapter3.SimpleTransformerBean" /> 22 </beans>
8)chapter3-bean-su服务单元目录结构
打包:jar cvf chapter3-bean-su.zip .
2 文件轮询绑定组件配置 chapter3-file-su
xbean.xml
1 <beans xmlns="http://xbean.org/schemas/spring/1.0" 2 xmlns:file="http://servicemix.apache.org/file/1.0" 3 xmlns:esb="http://opensourceesb/chapter3/"> 4 5 <file:sender service="esb:fileSender" 6 endpoint="simpleFromJMSSender" 7 directory="chapter3/out"> 8 </file:sender> 9 10 <file:poller service="esb:filePoller" 11 endpoint="simpleToJMSPoller" 12 targetService="esb:JMSProviderService" 13 targetEndpoint="inQueueWriter" 14 file="chapter3/in" 15 period="2000"> 16 </file:poller> 17 </beans>
目录结构:
打包: jar cvf chapter3-file-su.zip .
3. JMS绑定组件 chapter3-jms-su
xbean.xml
1 <beans xmlns:jms="http://servicemix.apache.org/jms/1.0" 2 xmlns:esb="http://opensourceesb/chapter3/"> 3 4 5 <!-- esb:filePoller[simpleFromJMSSender] 6 => esb:JMSProviderService[inQueueWriter] 7 => inQueue队列 8 => esb:JMSConsumerService[inQueueReader] 9 => esb:beanService[beanEndpoint] 10 11 目录chapter/in => 文件轮询绑定组件 12 => 消息提供者 => 队列 => 消息消费者 ###通过JMS连接了filepoller文件轮询组件和bean服务处理单元 13 => 转到bean服务处理单元 14 --> 15 <jms:provider service="esb:JMSProviderService" 16 endpoint="inQueueWriter" 17 destinationName="inQueue" 18 connectionFactory="#connectionFactory" /> 19 <jms:consumer service="esb:JMSConsumerService" 20 endpoint="inQueueReader" 21 targetService="esb:beanService" 22 targetEndpoint="beanEndpoint" 23 destinationName="inQueue" 24 connectionFactory="#connectionFactory" /> 25 26 27 <!-- esb:beanService[beanEndpoint] 28 => esb:JMSProviderService[outQueueWriter] 消息提供者 29 => outQueue队列 30 => esb:JMSConsumerService[inQueueReader2] 消息消费者 31 => esb:fileSender[simpleFromJMSSender] 32 33 bean服务处理单元 34 => 消息提供者 => outQueue队列 => 消息消费者 ####通过JMS使服务处理单元与文件绑定组件间能够通信 35 => 文件发送绑定组件 => chapter3/out目录 36 --> 37 <jms:provider service="esb:JMSProviderService" 38 endpoint="outQueueWriter" 39 destinationName="outQueue" 40 connectionFactory="#connectionFactory" /> 41 <jms:consumer service="esb:JMSConsumerService" 42 endpoint="inQueueReader2" 43 targetService="esb:fileSender" 44 targetEndpoint="simpleFromJMSSender" 45 destinationName="outQueue" 46 connectionFactory="#connectionFactory"/> 47 48 49 <bean id="connectionFactory" 50 class="org.apache.activemq.ActiveMQConnectionFactory"> 51 <property name="brokerURL" value="tcp://localhost:61616" /> 52 </bean> 53 </beans>
打包: jar chapter3-jms-su.zip .
4. 服务装配(装配服务单元和绑定组件)
装配描述文件 META-INF/jbi.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <jbi xmlns="http://java.sun.com/xml/ns/jbi" version="1.0"> 3 <service-assembly> 4 5 <identification> 6 <name>Chapter3-JMSBindingService</name> 7 <description>Example showing the jms binding component</description> 8 </identification> 9 10 11 <service-unit> 12 <identification> 13 <name>SU-BEAN</name> 14 <description>The bean component</description> 15 </identification> 16 <target> 17 <artifacts-zip>chapter3-bean-su.zip</artifacts-zip> 18 <component-name>servicemix-bean</component-name> 19 </target> 20 </service-unit> 21 22 23 <service-unit> 24 <identification> 25 <name>SU-JMS-Queue</name> 26 <description>A number of ftp pollers and senders</description> 27 </identification> 28 <target> 29 <artifacts-zip>chapter3-jms-su.zip</artifacts-zip> 30 <component-name>servicemix-jms</component-name> 31 </target> 32 </service-unit> 33 34 <service-unit> 35 <identification> 36 <name>SU-JMS-File</name> 37 <description>A number of file pollers and senders files 38 </description> 39 </identification> 40 <target> 41 <artifacts-zip>chapter3-file-su.zip</artifacts-zip> 42 <component-name>servicemix-file</component-name> 43 </target> 44 </service-unit> 45 </service-assembly> 46 </jbi>
打包装配文件 jar cvf chapter3-jms-sa.zip META-INF chapter3-*-su.zip
部署装配文件chapter3-jms-sa.zip,把其拷贝到servicemix-3.2.1/hotdeploy目录下
启动 servicemix ESB
D:\osesbinaction\esb\apache-servicemix-3.2.1>bin\servicemix Starting Apache ServiceMix ESB: 3.2.1 Loading Apache ServiceMix from servicemix.xml on the CLASSPATH INFO - ConnectorServerFactoryBean - JMX connector available at: service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi INFO - JBIContainer - ServiceMix 3.2.1 JBI Container (ServiceMix) is starting INFO - JBIContainer - For help or more informations please see: http://incubator.apache.org/servicemix/ INFO - ComponentMBeanImpl - Initializing component: #SubscriptionManager# INFO - jetty - Logging to org.apache.servicemix.http.jetty.JCLLogger@72f3a4a1 via org.apache.servicemix.http.jetty.JCLLogger INFO - DeploymentService - Restoring service assemblies ###### ## 设置组件运行状态,并实例化组件 ##### INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-bean to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-bean INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-camel to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-camel INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-cxf-bc to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-cxf-bc INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-cxf-se to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-cxf-se INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-drools to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-drools INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-eip to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-eip INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-file to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-file INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-ftp to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-ftp INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-http to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-http INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-jms to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-jms INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-jsr181 to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-jsr181 INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-lwcontainer to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-lwcontainer INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-quartz to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-quartz 1 name = quartz.properties INFO - SimpleThreadPool - Job execution threads will use class loader of thread: main INFO - QuartzScheduler - Quartz Scheduler v.1.5.2 created. INFO - RAMJobStore - RAMJobStore initialized. INFO - StdSchedulerFactory - Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource fil e in Quartz package: 'quartz.properties' INFO - StdSchedulerFactory - Quartz scheduler version: 1.5.2 INFO - QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started. INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-saxon to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-saxon INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-script to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-script INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-truezip to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-truezip INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-wsn2005 to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-wsn2005 INFO - ComponentMBeanImpl - Setting running state for Component: servicemix-xmpp to Started INFO - ComponentMBeanImpl - Initializing component: servicemix-xmpp ## 启动部署的服务装配组件 INFO - ServiceAssemblyLifeCycle - Starting service assembly: Chapter3-JMSBindingService INFO - ServiceUnitLifeCycle - Initializing service unit: SU-BEAN INFO - ServiceUnitLifeCycle - Initializing service unit: SU-JMS-Queue INFO - ServiceUnitLifeCycle - Initializing service unit: SU-JMS-File INFO - ServiceUnitLifeCycle - Starting service unit: SU-BEAN INFO - ServiceUnitLifeCycle - Starting service unit: SU-JMS-Queue INFO - ServiceUnitLifeCycle - Starting service unit: SU-JMS-File INFO - JBIContainer - ServiceMix JBI Container (ServiceMix) started INFO - JDBCAdapterFactory - Database driver recognized: [apache_derby_embedded_jdbc_driver] INFO - LogTask - Logging system reconfigured using file: file:/D:/osesbinaction/esb/apache-servicemix-3.2.1/conf/log4j.xml
在chapter3/in目录下拖入一个person.xml文件,控制台相关输出:
result <?xml version="1.0" encoding="UTF-8"?><person> <customer-number>123</customer-number> <first-name>John</first-name> <last-name>Doe</last-name> <street>1st Street</street> <city>New York</city> <state>NY</state> <zip>567898</zip> <phone>1768768768</phone> </person> INFO - SimpleTransformerBean - receivee person John Doe