技术开发 频道

关于ESB的开发实践小结

    判断使用何种类型服务

    服务总线支持各种类型的服务,包括Web Services(使用XML或WSDL中的SOAP绑定),以及各种非XML或其他通用的服务。

    如果一个服务具备一个定义良好的WSDL接口,使用WSDL来定义服务。它具有以下可选的优势:

    系统提供了对WSDL中每个操作的衡量
    可以在管道中使用操作分支(operational branching )
    当服务是被代理服务调用,SOAP动作的报文头会自动发布
    在XQuery 和 XPath 编辑器和条件构建器中,可以十分方便的操作$body变量,因为编辑器会自动将请求消息的$body消息映射到WSDL上。但是,实际运行状态中$body信息内容可能对特定动作中会与缺省的内容有所不同。这是因为服务总线是一种非传统的编程语言,它不会生命有类型的变量并使用。相反其中的变量都是无类型的,并在运行状态时动态的创建和使用。另外变量的类型会在创建时来表明变量所包含的内容。设计时编辑器允许在一个指定动作中映射变量,依此简化XQuery的编写。服务总线本身并不知道变量内容的类型。
    如果服务使用 WS-Security,  WSDL 是必须的 (WS-Policies同时需要附在该WSDL上).
    系统支持 <url>?这种WSDL语法,这可以动态的获得一个HTTP代理的WSDL,这对一些SOAP客户端代码生成工具是非常有用(如:BEA Workshop)。

    服务总线并不自动根据接口定义(WSDL或消息接口定义)来校验服务发送或接收的消息。但是通过将服务接口定义放置到某一位置,在将来是可以通过打开开关方式来让系统对消息进行校验,虽然上述校验的代价比较大。目前对于消息流的设计者使用校验动作和XQuery条件表达式来在消息流中进行明确的校验。

    服务总线不自动做必须理解的SOAP消息头的合法性校验,而是可以在消息流中通过Xquery明确的进行处理。另外将来服务总线是可以增加选项来进行该项工作

    当使用WSDL,在下述场景中,建议选择WSDL  Port方式来绑定服务而非直接绑定:

    通过?WSDL语法产生的WSDL中,port名称被保留,这对于一些客户端工具非常重要,但是服务的URL会被服务定义中transport部分的URL定义所覆盖。绑定服务的WSDL中的URL不会被使用,除非它是在业务服务定义中缺省的URL定义
    任何 WS-Security 策略在port层面被使用的状况下

    如果用户希望暴露一个port给客户端,以涵盖后端各种企业应用,可以使用Any SOAP或Any XML服务类型。

    如果消息(请求/响应)中至少一个类型不是XML,则使用 messaging service 类型定义服务。

    对于各种类型的消息,如何理解上下文

    对于整个流程,存在一个消息,该消息存在于$header, $body和$attachments变量中。即使服务类型不是SOAP方式,消息的规范模式遵循SOAP格式,在上下文中,消息的体现方式为SOAP格式。

    $header 变量包含SOAP Header 元素, $body 元素包含SOAP Body 元素,而$attachments变量则封装了附件,每个附件为一个子附件元素。附件元素包含body元素来表示真实的附件数据。

    如果消息格式是二进制格式,$body变量中的Body元素包含一个XML的指针元素,它表示二进制数据内容的指针。而在二进制附件数据,附件元素中的body元素同样包含数据的指针信息。

    对于MFL格式的消息,$body 变量中的Body 元素则按照MFL文件所定义的XML格式体现。

    对于文本数据,$body 变量中的Body 元素为文本。而对于文本格式的附件,$attachments变量中body元素为文本。

    对于XML格式的附件,$attachments变量中body元素为XML。

    下面给出了这些元素的格式定义,这些元素的命名空间为预先定义的”ctx” :

    <element name="attachments" type="mc:AttachmentsType"/>

    <!-- Each attachment in the 'attachments' variable is represented by an instance of this element -->
    <element name="attachment" type="mc:AttachmentType"/>

    <!-- Element used to represent binary payloads and pass-by reference content -->
    <element name="binary-content" type="mc:BinaryContentType"/>

    <complexType name="AttachmentsType">
        <sequence>
            <!-- the 'attachments' variable is just a series of attachment elements -->
            <element ref="mc:attachment" minOccurs="0" maxOccurs="unbounded"/>
        </sequence>
    </complexType>
   
    <complexType name="AttachmentType">
        <sequence>
            <!-- Set of MIME headers associated with attachment -->
            <element name="Content-ID" type="string" minOccurs="0"/>
            <element name="Content-Type" type="string" minOccurs="0"/>
            <element name="Content-Transfer-Encoding" type="string" minOccurs="0"/>
            <element name="Content-Description" type="string" minOccurs="0"/>
            <element name="Content-Location" type="string" minOccurs="0"/>
            <element name="Content-Disposition" type="string" minOccurs="0"/>

            <!-- Contains the attachment content itself, either in-lined or as <binary-content/> -->
            <element name="body" type="anyType"/>
        </sequence>
    </complexType>

    <complexType name="BinaryContentType">
        <!-- URI reference to the binary or pass-by-reference payload -->
        <attribute name="ref" type="anyURI" use="required"/>
    </complexType>

    上下文实际处理过程中的一些关键点

    当在一个Xquery中指向一个变量时,该变量的根元素通常没有表达出。例如:一个Xquery的表达式需要获取第一个附件的Content-Description信息,可以表达为:$attachments/ctx:attachment[1]/ctx:Content-Description.

    另一个Xquery示例是获取第二个附件中的订单信息,这样订单的获取为: $attachments/ctx:attachment[2]/ctx:body/*

    当变量为空或只有一个元素,而Xquery返回的是一个序列信息,则当该Xquery被赋给该变量时,只有序列中的第一个元素被存入该变量。例如:如果需要将WS-Addressing MessagerID SOAP头赋予一个变量,而SOAP头只有一个的情况下,赋值动作为:

    assign data($header/wsa:MessageID) to variable idvar.

    注意:如果有两个WS-Addressing MessageID头存在,变量中只包含第一个头的信息。

    通常情况下,当使用转换资源(XSLT 或 XQuery),转换资源需要定义转换SOAP报文体的文档,为了简化,转换的输入参数仍然可以是一个XQuery,例如输入参数可以从$body变量中选择是$body/*[1] 来提供业务文档,转换的结果通过替换内容动作可以直接放置到$body中(替换$body变量的内容意味着替换Body元素的内容)。采用这种方式会使转换更有效率。

    当XQuery表达返回序列,可以通过插入和替换操作可以实现对一个序列的插入和替换。例如:将$inbound变量中的transport header信息复制到$outbound变量中。

0
相关文章