规则引擎 Apache camel (学习三)

重述下:Exchange要素帮助开发人员在控制端点到处理器、处理器到处理器的路由过程中完成消息的统一描述

1.Exchange中的基本属性

   ExchangeID:

        一个Exchange贯穿着整个编排的路由规则,ExchangeID就是它的唯一编号信息,

       同一个路由规则的不同实例(对路由规则分别独立的两次执行),ExchangeID不相同。

   fromEndpoint:

         表示exchange实例初始来源的Endpoint控制端点(类的实例),一般来说就是开发人员设置路由时由“from”关键字所表达的Endpoint。

         比如:from关键字填写的URI信息是“ jetty: http://0.0.0.0:8282/doHelloWorld ”,

                   而实现Jetty协议头支持的org.apache.camel.Endpoint接口实现类是org.apache.camel.component.jetty.JettyHttpEndpoint。

                   Exchange对象中的fromEndpoint属性就是JettyHttpEndpoint类的一个实例化对象。

   properties:

          Exchange对象贯穿整个路由执行过程中的控制端点、处理器甚至还有表达式、路由条件判断。

          为了让这些元素能够共享一些开发人员自定义的参数配置信息,Exchange以K-V结构提供了这样的参数配置信息存储方式。

          在org.apache.camel.impl.DefaultExchange类中,对应properties的实现代码如下所示

              ......
             public Map<String, Object> getProperties() {
                       if (properties == null) {
                          properties = new ConcurrentHashMap<String, Object>();
                       }
                       return properties;
              }
            ......

      Pattern:

            介绍:Exchange中的pattern属性非常重要,它的全称是:ExchangePattern(交换器工作模式)。

                       其实现是一个枚举类型:org.apache.camel.ExchangePattern。

                       可以使用的值包括:InOnly, RobustInOnly, InOut, InOptionalOut, OutOnly, RobustOutOnly, OutIn, OutOptionalIn。

                       从Camel官方已公布的文档来看,这个属性描述了Exchange中消息的传播方式

          例子:例如 Event Message类型的消息,其ExchangePattern默认设置为InOnly。

                     Request/Reply Message类型的消息,其ExchangePattern设置为InOut。

                     但是笔者通过代码排查,发现并不是ExchangePattern都被Camel-Core核心实现部分所使用

                  (并不能说明没有被诸如 Camel-CXF这些pluin所使用),而且Camel的官方文档对于它们的介绍

                    也只有寥寥数笔(http://camel.apache.org/exchange-pattern.html)。

                    例如RobustOutOnly、OutOptionalIn、OutOnly这些枚举值就没有在Camel-Core实现部分发现引用。

     Exception:

                  如果在处理器Processor的处理过程中,开发人员需要抛出异常并终止整个消息路由的执行过程,

                 可以通过设置Exchange中的exception属性来实现。

        

2.Exchange中的Message(这里我理解为Exchange是共有的,方便控制点,处理器之间的信息共享)

    定义:Exchange中还有两个重要属性inMessage和outMessage。

               这两个属性分别代表Exchange在某个处理元素(处理器、表达式等)上的输入消息和输出消息。

    描述:

          当控制端点和处理器、处理器和处理器间的Message在Exchange中传递时

      (虽然ExchangePattern枚举中存在isInCapable()、isInCapable()这样的判断方法,但是通过代码排查,

          笔者并没有发现在camel-core中有关于这些方法的任何使用),

          Exchange会自动将上一个元素的输出值作为作为这个元素的输入值进行使用。

          但是如果在上一个处理器中,开发人员没有在Exchange中设置任何out message内容(即Excahnge中out属性为null)

          那么上一个处理器中的in message内容将作为这个处理器的in message内容

    例子:这里需要注意一个问题,在DefaultExchange类中关于getOut()方法的实现,有这样的代码片段:

            ......
            public Message getOut() {
                     // lazy create
                    if (out == null) {
                        out = (in != null && in instanceof MessageSupport)? ((MessageSupport)in).newInstance() : new DefaultMessage();
                        configureMessage(out);
                     }
                     return out;
            }
         ......

    所以,在处理器中对out message属性的赋值,并不需要开发人员明确的“new”一个Message对象。

    只需要调用getOut()方法,就可以完成out message属性赋值。以下路由代码片段在fromEndpoint后,

    连续进入两个Processor处理器,且Exchange的ExchangePattern为InOut。我们来观察从第一个处理处理完后,

    到第二个处理收到消息时Exchange对象中的各个属性产生的变化:

        ......
        from("jetty:http://0.0.0.0:8282/doHelloWorld")
        .process(new HttpProcessor())
        .process(new OtherProcessor())
        ......

      规则引擎 Apache camel (学习三)

 

    上图显示了当前内存区域中,Exchange对象的id为452,fromEndpoint属性是一个JettyHttpEndpoint的实例,对象id为479。

   注意两个重要的inMessage和outMessage,它们分别是HttpMessage的实例(对象id467)和DefaultMessage的实例(对象id476),

   这里说明一下无论是HttpMessage还是DefaultMessage,它们都是org.apache.camel.Message接口的实现。

   outMessage中的body部分存储了一个字符串信息,我们随后验证一下信息在下一个OtherProcessor处理器中的记录方式。

   规则引擎 Apache camel (学习三)

 

      可以看到HttpProcessor处理器中outMessage的Message对象作为了这个OtherProcessor处理器的inMessage属性,对象的id编号都是476,

     说明他们使用的内存区域都是相同的,是同一个对象。Excahnge对象的其它信息也从HttpProcessor处理器原封不动的传递到了OtherProcessor处理器。

     

2.每一个Message(无论是inMessage还是outMessage)对象主要包括四个属性:MessageID、Header、Body和Attachment。

   MessageID:在系统开发阶段,提供给开发人员使用的标示消息对象唯一性的属性,这个属性可以没有值。

   Header:

      介绍:消息结构中的“头部”信息,在这个属性中的信息采用K-V的方式进行存储,

                并可以随着Message对象的传递将信息带到下一个参与路由的元素中。

            

      例子:主要注意的是在org.apache.camel.impl.DefaultMessage中对headers属性的实现是一个名叫org.apache.camel.util.CaseInsensitiveMap的类。

                看这个类的名字就知道:headers属性的特点是忽略大小写。也就是说:

                 ......
                outMessage.setHeader("testHeader", "headerValue");
                outMessage.setHeader("TESTHEADER", "headerValue");
                outMessage.setHeader("testheader", "HEADERVALUE");
                ......

        总结:以上代码片段设置后,Message中的Headers属性中只有一个K-V键值对信息,且以最后一次设置的testheader为准。

     Body:

           Message的业务消息内容存放在这里

     Attachment:

          Message中使用attachment属性存储各种文件内容信息以便这些文件内容在Camel路由的各个元素间进行流转

          attachment同样使用K-V键值对形式进行文件内容的存储。但不同的是,这里的V是一个javax.activation.DataHandler类型的对象。

        

      

规则引擎 Apache camel (学习三)

上一篇:vue项目中引入jquery


下一篇:Ajax 原理初探