规则引擎Apache Camel[kæml]

1.了解下ESB,SOA

   百度百科:

      企业服务总线,即ESB全称为Enterprise Service Bus,指的是传统中间件技术与XML、Web服务等技术结合的产物。ESB提供了网络中最基本的连接中枢,是构筑企业神经系统的必要元素。

      面向服务的体系结构已经逐渐成为IT集成的主流技术。面向服务的体系结构(service-oriented architecture,SOA)是一种软件系统设计方法,通过已经发布的和可发现的接口为终端用户应用程序或其它服务提供服务。
 
2.Apache Camel介绍
   官网地址:http://camel.apache.org/
    概述:
          Apache Camel的官网并没有把Camel定义成一个ESB中间件服务,因为Camel并不是服务:

         Camel empowers you to define routing and mediation rules in a variety of domain-specific languages, including a Java-based Fluent API, Spring or Blueprint XML Configuration files, and a Scala DSL.

         This means you get smart completion of routing rules in your IDE, whether in a Java, Scala or XML editor.

         Apache Camel uses URIs to work directly with any kind of Transport or messaging model such as HTTP, ActiveMQ, JMS, JBI, SCA, MINA or CXF, as well as pluggable Components and Data Format options.

         Apache Camel is a small library with minimal dependencies for easy embedding in any Java application. Apache Camel lets you work with the same API regardless which kind of Transport is used - so learn

         the API once and you can interact with all the Components provided out-of-box.

         Apache Camel provides support for Bean Binding and seamless integration with popular frameworks such as CDI, Spring, Blueprint and Guice. Camel also has extensive support for unit testing your routes.

        以上引用是Apache Camel官方对它的定义。domain-specific languages指代的是DSL(领域特定语言),首先Apache Camel支持DSL,这个问题已经在上一篇文章中说明过了。

        Apache Camel支持使用JAVA语言和Scala语言进行DSL规则描述,也支持使用XML文件进行的规则描述。这里提一下,JBOSS提供了一套工具“Tools for Apache Camel”可以图形化Apache Camel的规则编排过程。

        Apache Camel在编排模式中依托URI描述规则,实现了传输协议和消息格式的转换:HTTP, ActiveMQ, JMS, JBI, SCA, MINA or CXF等等。Camel还可以嵌入到任何java应用程序中:看到了吧,Apache Camel不是ESB中间件服务,

       它需要依赖于相应的二次开发才能被当成ESB服务的核心部分进行使用。

   总结:Apache Camel想要实现中间件或者java的实现,需要进行二次开发

    

   示例:

        package com.yinwenjie.test.cameltest.helloworld;
            import java.io.ByteArrayOutputStream;
            import java.io.IOException;
            import java.io.InputStream;
            import org.apache.camel.Exchange;
            import org.apache.camel.ExchangePattern;
            import org.apache.camel.Message;
            import org.apache.camel.Processor;
            import org.apache.camel.builder.RouteBuilder;
            import org.apache.camel.component.http.HttpMessage;
            import org.apache.camel.impl.DefaultCamelContext;
            import org.apache.camel.model.ModelCamelContext;
             /**
               * 郑重其事的写下 helloworld for Apache Camel
               * @author yinwenjie
             */
            public class HelloWorld extends RouteBuilder {
                    public static void main(String[] args) throws Exception {
                     // 这是camel上下文对象,整个路由的驱动全靠它了。
                    ModelCamelContext camelContext = new DefaultCamelContext();
                    // 启动route
                   camelContext.start();
                   // 将我们编排的一个完整消息路由过程,加入到上下文中
                    camelContext.addRoutes(new HelloWorld());
                    /*
                     * ==========================
                     * 为什么我们先启动一个Camel服务
                     * 再使用addRoutes添加编排好的路由呢?
                     * 这是为了告诉各位读者,Apache Camel支持动态加载/卸载编排的路由
                     * 这很重要,因为后续设计的Broker需要依赖这种能力
                     * ==========================
                     * */
                     // 通用没有具体业务意义的代码,只是为了保证主线程不退出
                     synchronized (HelloWorld.class) {
                                 HelloWorld.class.wait();
                     }
                 }
                @Override
                public void configure() throws Exception {
                        // 在本代码段之下随后的说明中,会详细说明这个构造的含义
                       from("jetty:http://0.0.0.0:8282/doHelloWorld").process(new HttpProcessor()).to("log:helloworld?showExchangeId=true");
                }
               /**
                 * 这个处理器用来完成输入的json格式的转换
                 * @author yinwenjie
                 */
              public class HttpProcessor implements Processor {
              /* (non-Javadoc)
               * @see org.apache.camel.Processor#process(org.apache.camel.Exchange)
               */
             @Override
             public void process(Exchange exchange) throws Exception {
                   // 因为很明确消息格式是http的,所以才使用这个类
                   // 否则还是建议使用org.apache.camel.Message这个抽象接口
                   HttpMessage message = (HttpMessage)exchange.getIn();
                   InputStream bodyStream = (InputStream)message.getBody();
                   String inputContext = this.analysisMessage(bodyStream);
                   bodyStream.close();
                   // 存入到exchange的out区域
                   if(exchange.getPattern() == ExchangePattern.InOut) {
                          Message outMessage = exchange.getOut();
                          outMessage.setBody(inputContext + " || out");
                   }
           }
         /**
           * 从stream中分析字符串内容
           * @param bodyStream
           * @return
           */
         private String analysisMessage(InputStream bodyStream) throws IOException {
                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                byte[] contextBytes = new byte[4096];
                int realLen;
                while((realLen = bodyStream.read(contextBytes , 0 ,4096)) != -1) {
                                  outStream.write(contextBytes, 0, realLen);
                }
                // 返回从Stream中读取的字串
               try {
                     return new String(outStream.toByteArray() , "UTF-8");
                } finally {
                     outStream.close();
                }
            }
         }
      }

    过程说明:

          以上代码可以直接拿来使用,它展示了一个简单的可以实际运行的消息路由规则:首先from语句中填写的“ jetty:http://0.0.0.0:8282/doHelloWorld ”表示这个编排好的路由的消息入口:使用http传输协议,访问本物理节点上任何IP(例如127.0.0.1或者192.168.1.1),

          在端口8282上的请求,都可以将HTTP携带的消息传入这个路由。

          接下来消息会在HttpProcessor这个自定义的处理器中被进行转换。为了让各位读者看清楚原理,HttpProcessor 中的消息转换很简单:在HTTP传入的json字符串的末尾,加上一个” || out”并进行字符串输出。

          Apache Camel中自带了很多处理器,并且可以自行实现Processor接口来实现自己的处理逻辑。

          最后,消息被传输到最后一个endPoint控制端点,这个endPoint控制端点的URI描述(log:helloworld?showExchangeId=true)表明它是一个Log4j的实现,所以消息最终会以Log日志的方式输出到控制台上。到此,整个编排的路由就执行完成了。

   

 

参考:https://www.kutu66.com//diannao/article_69003

           http://www.uml.org.cn/zjjs/201801223.asp

           https://baike.baidu.com/item/企业服务总线/8790284?fromtitle=ESB&fromid=8742700&fr=aladdin

           https://www.oschina.net/p/apache+camel?hmsr=aladdin1e1

posted @ 2020-08-25 15:23  小窝蜗  阅读(844)  评论(1编辑  收藏  举报