系统配置

Biz-SIP业务中台通过配置来构建系统的介绍。

一、概述

Biz-SIP中间件在开发应用时,主要涉及配置文件和Java代码开发,系统架构如下所示:

image.png

上图中蓝色虚框所呈现的部分,就是Biz-SIP中间件的配置文件。
Biz-SIP中间件的配置文件,一般都统一存放在配置目录下(由application.yml文件中的bizsip.config-path配置项所约定),配置目录中的文件如下例所示:

config
|____sink.yml
|____source.yml
|____app.yml
|____converter
| |____server3
| | |____woman.vm
| | |____error.vm
| | |____man.vm
|____service
| |____client1
| | |____error.script
| |____openapi
| | |____sample1.script
| | |____sample5.script
| | |____sample2.script
| | |____sample4.script
|____check-rule
| |____client1
| | |____sample1.yaml

sink.yml:领域层sink模块的配置文件
source.yml:渠道层source模块的配置文件
app.yml:应用层app聚合服务的的配置文件(非脚本的服务)
service目录:存放所有的应用层app聚合服务编排脚本
converter目录:存放消息转换器converter相关的消息格式转换配置文件
check-rule目录:存放聚合服务校验规则配置文件

二、app应用层配置

1. app.yml

定义了所有非脚本类聚合服务的配置参数:

配置项 配置说明
[].app-service-id 应用服务ID,要全局唯一
[].type 应用服务执行调用方式,目前支持“app-bean-service”、“bean-service”、“sink-service”三种方式:

其余参数如下:

  • app-bean-service:该类型执行继承BizServiceInterface接口的SpringBean,并调用约定的process()方法,相关参数如下:

    配置项 配置说明
    [].class-name 要执行的SpringBean类名(要求必须继承AppBeanInterface接口)
  • bean-service:该类型执行约定的SpringBean,调用的方法和参数通过消息传递过来,方法名为消息体JSON数据中的“methodName”域,参数为消息体JSON数据中的“params”域(应为JSON数组),相关参数如下:

    配置项 配置说明
    [].class-name 要执行的SpringBean类名,由用户自行定义
  • sink-service:直接把后端的sink服务,通过此接口通过聚合服务暴露出来,相关参数如下:

    配置项 配置说明
    [].sinkId 该聚合服务所对应的sink id,此聚合服务的数据会直接透传给sink id所对应的Sink后端。

1.1 app-bean-service

该类型执行继承BizServiceInterface接口的SpringBean,并调用约定的doBizService()方法,配置参数如下:

配置项 配置说明
[].class-name 要执行的SpringBean类名(从AppBeanInterface接口继承)

service.yml配置例子如下:

- app-service-id: /sample/service4
  type: app-bean-service
  class-name: com.bizmda.bizsip.sample.app.IntegratorService4

class-name是服务绑定的类,这个类需要从AppBeanInterface接口继承,接口如下:

public interface AppBeanInterface {
    /**
     * 执行聚合服务
     * @param message 传入的消息
     * @return 返回的消息
     */
    public abstract JSONObject process(JSONObject message) throws BizException;
}

1.2 bean-service

该类型执行约定的SpringBean,调用的方法和参数通过消息传递过来,方法名为消息体JSON数据中的“methodName”域,参数为消息体JSON数据中的“params”域(应为JSON数组),配置参数如下:

配置项 配置说明
[].class-name 要执行的SpringBean类名,方法由开发者自由定义。

service.yml配置例子如下:

- app-service-id: /springbean
  type: bean-service
  class-name: com.bizmda.bizsip.sample.app.SinkClientInterface1Impl

class-name是服务绑定的类,这个类的接口需要由开发者约定Interface并实现。

1.3 sink-service

sink-server是直接把后端的sink服务,通过此接口通过聚合服务暴露出来。

配置项 配置说明
[].sink-id 该聚合服务所对应的sink id,此聚合服务的数据会直接透传给sink id所对应的Sink后端。

service.yml配置例子如下:

- app-service-id: /sinkService
  type: sink-service
  sink-id: sink1

2. service目录

service目录位置配置文件根目录下的/service目录,目录下存放了聚合服务脚本,聚合服务ID为“目录+文件前缀”的方案,例如“service/openapi/sample1.script”文件,对应的聚合服务ID为“openapi/sample1”,文件的后续名表示是支持不同的服务聚合器类型,目前支持script服务聚合器(*.script)。

config
|____sink.yml
|____source.yml
|____converter
|____service
| |____client1
| | |____error.script
| |____openapi
| | |____sample1.script
| | |____sample5.script
| | |____sample2.script
| | |____sample4.script

3. Script服务聚合器脚本(*.script)

Script服务整合器是构建在magic-script脚本解析器基础上的服务编排引擎,通过解释执行service目录下的*.script文件,实现内外部服务整合和编排运行。
service目录下所有的“*.script”文件,都是Script服务整合器脚本。脚本语言采用magic-script(https://gitee.com/ssssssss-team/magic-script),这是一款基于JVM的脚本语言。
脚本中涉及的相关对象,请参见附录1。

4. 服务校验规则

Biz-SIP中间件支持服务消息域校验规则和服务阻断校验规则,服务消息域校验规则能对上送域的域值进行合法性检验,对于不符合检验规则的消息,会直接在入口处拒绝。服务阻断检验规则能对服务上送数据进行检查,对不符合规则的服务,也会在入口处拒绝,类似于服务的风控系统。
服务检验规则,是配置在config/check-rule目录下,配置文件的目录和文件名和对应的服务脚本位置应一致,配置文件后缀为“.yml”,配置相关参数:

配置项 配置说明
field-check-rules 定义域校验规则
field-check-rules.[].field 域的JSON取值Path,例如email、account[1].balance
field-check-rules.[].rule 域校验规则,具体参见域校验规则一节
field-check-rules.[].args[] 域检验规则的参数,具体参见域检验规则一节
field-check-rules.[].message 检验出错后,显示给调用方的错误消息。message可以嵌入域值,例如“不是邮箱地址:{}”。
field-check-mode 域检验模式,主要有“one”和“all”这二种模式,“one”表示有一个域不满足,即返回错误,返回的错误只包括第一个不满足的原因信息;“all”表示返回错误会包括所有不满足的原因信息。
service-check-rules 定义服务校验规则
service-check-rules.[].script 服务检验脚本
service-check-rules.[].message 检验出错后,显示给调用方的错误消息。
service-check-mode 服务校验模式,主要有“one”和“all”这二种模式,“one”表示有一个域不满足,即返回错误,返回的错误只包括第一个不满足的原因信息;“all”表示返回错误会包括所有不满足的原因信息。

具体案例如下:
config/check-rule/openapi/sample1.yml

field-check-rules:
  - field: email
    rule: isEmail
    message: '不是邮箱地址:{}'
  - field: sex
    rule: notEmpty
    message: '不能为空'
  - field: mobile
    rule: isMatchRegex
    args:
      - '^[1][3,4,5,6,7,8,9][0-9]{9}$'
    message: '不是手机号{}'
field-check-mode: one
service-check-rules:
  - script: if(data.sex == '1')
            {return '性别不符合!';}
    message: '额度超限'
service-check-mode: one

域检验规则:

域校验规则 说明 参数
isCitizenId 验证是否为身份证号码(支持18位、15位和港澳台的10位) (无)
isEmail 验证是否为可用邮箱地址 (无)
notEmpty 验证是否为空 (无)
isMatchRegex 通过正则表达式验证 参数1:正则表达式
isMoney 验证是否为金额,单位元2位小数
isCent 验证是否为金额,单位分支持
isUrl 验证是否为URL
isNumber 验证该字符串是否是数字
isMobile 验证是否为手机号码(中国)
isBetween 验证给定的数字是否在指定范围内 参数1:下限,参数2:上限
checkTimeFormatter 验证时间格式
isLengthBetween 验证给定的字符传长度是否在指定范围内 参数1:最小长度,参数2:最大长度

三、source适配层配置

source.yml定义了客户端适配器的配置参数,并不是所有适配层的接入模块都需要在source.yml中定义,只有用到可配置的消息转换器converter时,才需要定义:

配置项 配置说明
[].id 客户端的ID,要全局唯一
[].converter 参见:消息处理器配置
[].service 聚合服务相关配置
[].service-rules[] 聚合服务定位断言规则
[].service-rules[].predicate 断言规则,返回true选择当前规则rule作为聚合服务ID,空条件为true,支持EL表达式
[].service-rules[].rule 当前断言规则对应的聚合服务ID,支持EL表达式

例子:

- id: source1
  converter:
    type: simple-json
  service:
    service-rules:
      - predicate: '#{#data[serviceId] != null}'
        rule: '#{#data[serviceId]}'
      - predicate:
        rule: source1/error

四、sink领域层配置

sink.yml定义了所有接入的服务端适配器的配置参数:

配置项 配置说明
[].id 服务端的ID,要全局唯一
[].type 服务端适配器调用方式,目前支持rest、rabbitmq:
- rest为RESTful同步调用方式
- rabbitmq:为基于RabbitMQ消息中间件的异步调用方式
[].processor 支持3种sink服务处理方式:
- default:为缺省的Sink服务处理方式,会根据配置的converter和connector进行处理;
- sink-bean:为调用sink-bean类处理方式,sink-bean是基于SinkBeanInterface统一接口的类;
- bean:为调用基于开发者自定义接口实现的类。
[].url [条件:type为rest]:服务端适配器调用方式为RESTful方式时,该属性约定RESTful调用的url地址
[].exchange [条件:type为rabbitmq]:服务端适配器调用方式为rabbitmq方式时,该属性约定异步调用时,投递到RabbitMQ中间件的exchange。
缺省值为“exchange.dircect.bizsip.sink”
[].routing-key [条件:type为rabbitmq]:服务端适配器调用方式为rabbitmq方式时,该属性约定异步调用时,投递到RabbitMQ中间件的routing key的值。
缺省值为对应sink id的值。
[].queue [条件:type为rabbitmq]:
服务端适配器调用方式为rabbitmq方式时,该属性约定异步调用时,投递到RabbitMQ中间件的queue的值。
缺省值为“queue.bizsip.sink.{sink id}”值。
[].converter 参见:消息处理器配置
[].connector 服务端协议处理器相关配置
[].connector.type 约定服务端协议处理器的类型(具体参见服务端协议处理器配置)
[].connector.* 约定服务端协议处理器的其它参数(具体参见服务端协议处理器配置)

sink.yml例子:

- id: customer-sink
  type: rest
  processor: bean
  url: http://customer-sink/sink
  class-name: com.xbank.sink.customer.service.CustomerSinkService

- id: account-sink
  type: rest
  processor: bean
  url: http://account-sink/sink
  class-name: com.xbank.sink.account.service.AccountSinkService

- id: payment1-sink
  type: rest
  processor: sink-bean
  url: http://payment1-sink/sink
  class-name: com.xbank.sink.payment.service.Payment1SinkService
  converter:
    type: simple-xml

- id: payment2-sink
  type: rest
  processor: sink-bean
  url: http://payment2-sink/sink
  class-name: com.xbank.sink.payment.service.Payment2SinkService

1. 接口调用方式

1.1 rest接口调用

在sink.yml中sink的type设置为rest时,app层是采用RESTful同步调用sink服务的,sink.yml中需要设置url来约定调用的url。
app服务代码中的调用,如下例:

@Service
public class SampleBeanService implements SampleBeanServiceInterface {
    private HelloInterface sampleBeanSinkInterface = AppClientFactory
            .getSinkClient(HelloInterface.class,"sample-bean-sink");
    @Override
    public String callSampleBeanSink(String message) {
        return this.sampleBeanSinkInterface.hello(message);
    }

在app服务脚本中的调用,如下例:

var result = sip.callSink("sink1",bizmessage.data)

1.2 rabbitmq接口调用

在sink.yml中sink的type设置为rabbitmq时,app层是采用RabbitMQ异步调用sink服务的,sink.yml中可以设置exchange、routing-key来约定Rabbitmq消息传递的exchange和routing key,如果没有设置则采用缺省的设置(exchange缺省为exchange.dircect.bizsip.sink,routing key缺省为对应的sink id)。
在app服务代码和app服务脚本中的调用,和rest接口调用方式完全一样。

2. 接口服务处理方式

sink.yml中可以约定每个sink的服务处理方式,这是通过sink的processor属性来设置的,processor包括以下属性值:

  • default:采用缺省的、无需代码开的的处理方式;
  • sink-bean:通过编写继承平台约定sink-bean接口(SinkBeanInterface)的Java类来进行处理;
  • bean:通过编写自定义接口的Java类来进行处理。

2.1 缺省Sink服务

在sink.yml中sink的processor设置为default时,sink服务是采用默认的缺省Sink服务流程来处理的,无需任何代码开发,处理流程如下:

2.2 sink-bean服务

在sink.yml中sink的processor设置sink-bean时,sink服务是会调用实现sink-bean接口(SinkBeanInterface接口)的sink-bean服务类(要求为Spring容器类),具体类名是由sink.yml中当前sink的class-name来指定的。

2.3 bean服务

在sink.yml中sink的processor设置为bean时,sink服务是会调用实现基于开发者自己约定接口实现的bean服务类(要求为Spring容器类),具体类名是由sink.yml中当前sink的class-name来指定的。

五、适配层source/领域层sink converter配置(消息适配)

1 source.yml/sink.yml

source.yml和sink.yml文件中定义了消息转换器相关配置:

配置项 配置说明
[].converter Source模块/Sink模块的消息格式相关配置
[].converter.type Source模块/Sink模块的消息转换类型,目前支持:simple-json、simple-xml、velocity-json、velocity-xml、fixed-length、velocity-split等
[].converter.pack-rules[](可选) 消息打包规则,选择打包格式文件
[].converter.pack-rules[].predicate 断言规则,返回true选择当前规则rule作为打包格式文件,空条件为true,支持EL表达式
[].converter.pack-rules[].rule 消息格式文件,支持EL表达式
[].converter.unpack-rules[](可选) 消息解包规则
[].converter.unpack-rules[].predicate 断言规则(同上)
[].converter.unpack-rules[].rule 消息格式文件(同上)


消息转换类型,目前支持simple-json、simple-xml、velocity-json、velocity-xml、fixed-length、velocity-split、iso-8583等7种方式,这7种消息转换类型的说明和针对打包、解包规则说明如下:

消息转换类型 消息转换说明 消息转换描述 消息打包规则 消息解包规则
simple-json 支持快速简单的JSON报文适配 打包:直接输出内部标准JSON报文
解包:直接对传入JSON进行解包
simple-xml 支持快速简单的XML报文适配 打包:直接把内部标准JSON报文转换成XML格式输出
解包:对传入XML直接解包成内部标准JSON报文
velocity-json 支持基于Velocity模板的JSON报文适配 打包:根据断言规则定位的Velocity模板文件进行打包
解包:直接对传入JSON进行解包
velocity-xml 支持基于Velocity模板的XML报文适配 打包:根据断言规则定位的Velocity模板文件,进行打包
解包:对传入XML直接解包成内部标准JSON报文
fixed-length 支持基于配置的定长报文适配 打包:根据断言规则定位的打包文件,文件是基于域级打包配置参数定制的
解包:基于预解包域级配置,并根据断言规则 定位的解包文件,文件是基于域级配置参数配置的
velocity-split 支持基于配置和Velocity模板的有分隔符报文适配 打包:根据断言规则定位的Velocity模板文件进行打包
解包:基于多级分隔符配置的解包
iso-8583 支持基于配置的ISO8583报文适配 打包:根据sink.yml中的fields、destination-id、source-id配置进行打包;
解包:根据sink.yml中的fields配置进行解包

2 converter目录

“config/converter”目录,存放了各种消息的格式转换配置文件,目前支持的文件类型有“.vm”和“.yml”。
对于消息格式转换类型有打包和解包规则 的,会根据断言规则定位,到message目录下用对应的文件来加载对应的格式转换配置,如下例所示:

config/converter
├── server3
│   ├── error.vm
│   ├── man.vm
│   └── woman.vm
├── server4
│   ├── man.yml
│   └── woman.yml
└── server5
    ├── error.vm
    ├── man.vm
    └── woman.vm

文件类型和消息转换类型的关系如下:

  • *.vm:Velocity模板文件
    • velocity-json消息转换类型中的打包模板
    • velocity-xml消息转换类型中的打包模板
    • velocity-split消息转换类型中的打包模板
  • *.yml:YML配置文件
    • fix-length消息转换类型中的打包和解包参数配置文件

2.1 velocity-json/velocity-xml(*.vm)

对于消息转换类型为velocity-json、velocity-xml的,会根据断言规则定位,到converter目录下用对应的vm文件进行消息打包,如下例所示:

config
|____converter
| |____sink4
| | |____woman.vm
| | |____error.vm
| | |____man.vm

vm文件支持velocity模板语言进行处理,模板中注入变量有:

变量名 变量说明
data BizMessage.data:内部标准消息的数据体,为JSONObject对象格式

2.2 fixed-length(*.yml)

对于消息转换类型为fixed-length,会根据断言规则 定位,到converter目录下用对应的yml文件进行打包和解包,如下例所示:

config
|____converter
| |____sink6
| | |____woman.yml
| | |____error.yml
| | |____man.yml

yml配置文件如下例所示:

- name: sex
  length: 1
- name: accountNo
  length: 8
  unpack-functions:
    - name: trim
- name: accountName
  length: 10
  unpack-functions:
    - name: trim
- name: balance
  length: 10
  pack-functions:
    - name: decimalFormat
      args:
        - "###,###.00"

相关配置域属性如下:

配置域 域说明
name 对应内部标准消息格式中的JSON域名。
length 域值所占长度
unpack-functions 解包函数,支持多个函数,多个函数会按序执行。
pack-functions 打包函数,同样支持多个函数

3 Converter类型

3.1 simple-json(简单JSON格式适配)

支持快速、简单的JSON消息适配,直接把Biz-SIP内部标准消息,直接打包成外部的JSON格式;同时也直接把外部的JSON格式消息,快速直接解包成Biz-SIP内部标准消息。
可以在客户端适配器和服务端适配器中启用,配置如下例所示:

- id: sink1
  type: rest
  url: http://bizsip-sample-sink/sink1
  converter:
    type: simple-json
  connector:
    type: sink-bean
    class-name: com.bizmda.bizsip.sample.sink.controller.CrmServer

3.2 simple-xml(简单XML格式适配)

支持快速、简单的XML消息适配,直接把Biz-SIP内部标准消息,直接打包成外部的XML格式;同时也直接把外部的XML格式消息,快速直接解包成Biz-SIP内部标准消息。
可以在客户端适配器和服务端适配器中启用,配置如下例所示:

- id: server3
  type: rest
  url: http://sip-sample-server/server3
  converter:
    type: simple-xml
  connector:
    type: sink-bean
    class-name: com.bizmda.bizsip.sample.sink.controller.EchoServer

3.3 velocity-json(基于模板的JSON格式适配)

支持基于Velocity模板的JSON报文适配,在对外部的JSON报文打包,是采用Velocity模板文件,这个文件是通过打包断言规则来进行匹配的;外部JSON报文的解包,是直接解包成Biz-SIP内部标准消息的。
配置如下例所示,含有pack-rules:

- id: server4
  type: rest
  url: http://sip-sample-server/server4
  converter:
    type: velocity-json
    pack-rules:
      - predicate: '#{#data[sex]=="0"}'
        rule: server3/woman.vm
      - predicate: '#{#data[sex]=="1"}'
        rule: server3/man.vm
      - predicate:
        rule: server3/error.vm
  connector:
    type: sink-bean
    class-name: com.bizmda.bizsip.sample.sink.controller.EchoServer

Velocity模板中注入变量有:

变量名 变量说明
data BizMessage.data:内部标准消息的数据体,为JSONObject对象格式

3.4 velocity-xml(基于模板的XML适配)

支持基于Velocity模板的XML报文适配,在对外部的XML报文打包,是采用Velocity模板文件,这个文件是通过打包断言规则来进行匹配的;外部XML报文的解包,是直接解包成Biz-SIP内部标准消息的。
配置如下例所示,含有pack-rules:

- id: server5
  type: rest
  url: http://sip-sample-server/server5
  converter:
    type: velocity-xml
    pack-rules:
      - predicate: '#{#data[sex]=="0"}'
        rule: server3/woman.vm
      - predicate: '#{#data[sex]=="1"}'
        rule: server3/man.vm
      - predicate:
        rule: server3/error.vm
    unpack-rules:
  connector:
    type: sink-bean
    class-name: com.bizmda.bizsip.sample.sink.controller.EchoServer

Velocity模板中注入变量有:

变量名 变量说明
data BizMessage.data:内部标准消息的数据体,为JSONObject对象格式

3.5 fixed-length(定长消息适配)

支持基于配置的定长报文适配:

  • 打包:根据断言规则定位的打包文件,文件是基于域级打包配置参数定制的
  • 解包:先基于域级配置进行消息报文的预解包,并根据断言规则 定位的解包文件,文件是基于域级配置参数配置的。

配置如下例所示,含有pre-unpack、pack-rules和unpack-rules:

- id: server6
  type: rest
  url: http://sip-sample-server/server6
  converter:
    type: fixed-length
    pre-unpack:
      - name: sex
        length: 1
        functions:
          - name: trim
    pack-rules:
      - predicate: '#{#data[sex]=="0"}'
        rule: server4/woman.yml
      - predicate: '#{#data[sex]=="1"}'
        rule: server4/man.yml
      - predicate:
        rule: server4/error.yml
    unpack-rules:
      - predicate: '#{#data[sex]=="0"}'
        rule: server4/woman.yml
      - predicate: '#{#data[sex]=="1"}'
        rule: server4/man.yml
      - predicate:
        rule: server4/error.yml
  connector:
    type: sink-bean
    class-name: com.bizmda.bizsip.sample.sink.controller.EchoServer

根据解包和打包断言规则,定位报文对应的解包或打包定义yml定义文件,解包和打包定义文件如下例所示:

- name: sex
  length: 1
- name: accountNo
  length: 8
  unpack-functions:
    - name: trim
- name: accountName
  length: 10
  unpack-functions:
    - name: trim
- name: balance
  length: 10
  pack-functions:
    - name: decimalFormat
      args:
        - "###,###.00"

主要的配置定义如下:

配置项 配置说明
[].name 域名,对应Biz-SIP内部标准消息中的域名。
解包:表示当前数据从些域名中取得数据;
打包:表示数据对置入该域名对应的数据域。
[].length 当前域的长度
[].unpack-functions[](可选) 解包时,对当前域域值进行处理的域处理函数。
[].pack-functions[](可选) 打包时,对当前域域值进行处理的域处理函数。

其中,unpack-functions、pack-functions,以及pre-unpack项下的functions,都是域处理函数,具体请参见“6.4 域处理函数”一节,相关配置定义如下:

配置项 配置说明
name 域处理函数,具体请参见域处理函数一节
args[] 域处理函数的参数,具体参数约定请参见域处理函数一节。


fixed-length格式转换的解包流程为:

  1. 根据“pre-unpack”中的设置,首先对传入的定长消息进行预解包,先解出关键域的域值;
  2. 根据“unpack-rule”,用上一步解出的关键域域值,根据解包断言规则,选择指定的解包yml定义文件;
  3. 根据上一步选择的解包yml定义文件,对传入的定长消息进行解包,解包成Biz-SIP内部标准消息。

打包流程为:

  1. 根据“pack-rule”,根据打包断言规则,选择指定的打包yml定义文件;
  2. 根据上一步选择的打包yml定义文件,对Biz-SIP内部标准消息进行打包,打包成定长消息报文。

3.6 velocity-split(基于模板的有分隔符消息适配)

velocity-split消息适配,是针对有分隔符消息的转换和适配,打包是基于Velocity模板方式来进行转换的,解包是基于客户端适配器和服务端适配器的消息配置来转换的。
velocity-split消息适配的打包,是支持基于Velocity模板的适配,模板文件是通过打包断言规则来进行匹配的。
source.yml/sink.yml文件的配置如下例所示,含有separators和pack-rules的定义:

- id: server7
  type: rest
  url: http://sip-sample-server/server7
  converter:
    type: velocity-split
    separators:
      - "*"
      - ","
    pack-rules:
      - predicate: '#{#data[sex]=="0"}'
        rule: server5/woman.vm
      - predicate: '#{#data[sex]=="1"}'
        rule: server5/man.vm
      - predicate:
        rule: server5/error.vm
  connector:
    type: sink-bean
    class-name: com.bizmda.bizsip.sample.sink.controller.EchoServer

主要的配置定义如下:

配置项 配置说明
[].converter.separators
约定分隔符,可以设置多个分隔符。

velocity-split格式转换的打包流程为:

  1. 根据“pack-rule”,执行打包断言规则,选择指定的打包vm定义文件;
  2. 根据上一步选择的解包yml定义文件,对Biz-SIP内部标准消息进行打包,打包成有分隔符消息报文。

解包流程为:

  1. 根据“unpack-rule”,根据打包断言规则,选择指定的打包yml定义文件;
  2. 根据source.yml/sink.yml文件中的separators设置,将有分隔符消息报文,直接解包到Biz-SIP内部标准消息报文。

3.7 iso-8583(ISO8583消息适配)

支持基于配置的ISO8583消息适配,打包和解包,都是根据sink.yml文件中对应sink的iso-8583报文和域配置信息,进行ISO8583报文的打包和解包。
sink.yml对应ISO8583报文配置,如下例所示:

- id: sink13
  type: rest
  url: http://bizsip-sample-sink/sink13
  converter:
    type: iso-8583
    destination-id: '00010344'
    source-id: '42430440'
    fields:
      - index: 2
        length: 19
        unfixed: 2
        name: accNo2
      - index: 3
        length: 6
        name: processingCode3
      - index: 4
        length: 12
        name: amt_trans4
      - index: 5
        length: 12
        name: amt_settlmt5
      - index: 6
        length: 12
        name: transactionAmount6
      - index: 7
        length: 10
        name: transmsn_date_time7
      - index: 9
        length: 8
        name: transmsn_date_time9
      - index: 10
        length: 8
        name: transmsn_date_time10
      - index: 11
        length: 6
        name: systemTraceAuditNumber11
      - index: 12
        length: 6
        name: time_local_trans12
      - index: 13
        length: 4
        name: date_local_trans13
      - index: 14
        length: 4
        name: date_expr14
      - index: 15
        length: 4
        name: date_settlmt15
      - index: 16
        length: 4
        name: date_conv16
      - index: 18
        length: 4
        name: mchnt_type18
      - index: 19
        length: 3
        name: mchnt_cntry_code19
      - index: 22
        length: 3
        name: pos_entry_mode_code22
      - index: 23
        length: 3
        name: card_seq_num23
      - index: 25
        length: 2
        name: pos_cond_code25
      - index: 26
        length: 2
        name: pos_pin_cap_code26
      - index: 28
        length: 9
        name: amt_fee28
      - index: 32
        length: 11
        unfixed: 2
        name: acq_inst_id_code32
      - index: 33
        length: 11
        unfixed: 2
        name: fwd_inst_id_code33
      - index: 35
        length: 37
        unfixed: 2
        name: track2_data35
      - index: 36
        length: 104
        unfixed: 3
        name: track3_data36
      - index: 37
        length: 12
        name: retrivl_ref_num37
      - index: 38
        length: 6
        name: authr_id_resp38
      - index: 39
        length: 2
        name: resp_code39
      - index: 41
        length: 8
        name: card_accptr_termnl_id41
      - index: 42
        length: 15
        name: card_accptr_id42
      - index: 43
        length: 40
        name: card_accptr_name_loc43
      - index: 44
        length: 25
        unfixed: 2
        name: addtnl_resp_code44
      - index: 45
        length: 76
        unfixed: 2
        name: track1_data45
      - index: 48
        length: 512
        unfixed: 3
        name: addtnl_data_private48
      - index: 49
        length: 3
        name: currcy_code_trans49
      - index: 50
        length: 3
        name: currcy_code_settlmt50
      - index: 51
        length: 3
        name: currcy_code_cdhldr_bil51
      - index: 52
        length: 8
        name: pin_data52
      - index: 53
        length: 16
        name: security_control_info53
      - index: 54
        length: 40
        unfixed: 3
        name: addtnl_amt54
      - index: 55
        length: 255
        unfixed: 3
        name: ICC_data55
      - index: 56
        length: 255
        unfixed: 3
        name: token_par56
      - index: 57
        length: 100
        unfixed: 3
        name: issr_addtnl_data57
      - index: 59
        length: 600
        unfixed: 3
        name: detai_inquiring59
      - index: 60
        length: 100
        unfixed: 3
        name: reserved60
      - index: 61
        length: 200
        unfixed: 3
        name: ch_auth_info61
      - index: 62
        length: 200
        unfixed: 3
        name: switching_data62
      - index: 63
        length: 512
        unfixed: 3
        name: fin_net_data63
      - index: 70
        length: 3
        name: net_mgr_info_code70
      - index: 90
        length: 42
        name: ori_data_element90
      - index: 96
        length: 8
        name: msg_security_code96
      - index: 100
        length: 11
        unfixed: 2
        name: rcvg_inst_id_code100
      - index: 102
        length: 28
        unfixed: 2
        name: acct_id_1_102
      - index: 103
        length: 28
        unfixed: 2
        name: acct_id_2_103
      - index: 104
        length: 512
        unfixed: 3
        name: trans_industry_app_inf104
      - index: 113
        length: 512
        unfixed: 3
        name: add_data113
      - index: 117
        length: 256
        unfixed: 3
        name: addtnl_data117
      - index: 121
        length: 100
        unfixed: 3
        name: national_sw_resved121
      - index: 122
        length: 100
        unfixed: 3
        name: acq_inst_resvd122
      - index: 123
        length: 100
        unfixed: 3
        name: issr_inst_resvd123
      - index: 125
        length: 256
        unfixed: 3
        name: addtnl_data125
      - index: 128
        length: 8
        name: msg_authn_code128
  connector:
    type: sink-bean
    class-name: com.bizmda.bizsip.sample.sink.controller.EchoServer

主要的配置定义如下:

配置项 配置说明
[].type 约定为“iso-8583”
[].destination-id 配置ISO8583报文中的目的ID
[].source-id 配置ISO8583报文中的源ID
[].fields ISO8583中各域的配置
[].fields[].index 对应ISO8583报文中的域索引号。
0:报文头,缺省域名为“msgHead”
1:报文类型标识,缺省域名为“msgType”
2…128:ISO8583域
[].fields[].name 域名,主要在生成的JSON报文中用,报文头、报文类型标识缺省为msgHead、msgType,2…128域缺省为f2…f128
[].fields[].length 域长度,可变长度域为最大域长度
[].fields[].unfixed 可变长度域类型,可以取值为2和3,代表长度位分别是2位和3位;如果不配置则为定长域。

4 域处理函数

域处理函数可以用在以下几个地方:

  1. 预解包:一般定义在source.yml/sink.yml文件中的pre-unpack设置下的functions;
  2. 解包:一般定义在解包yml文件中的unpack-functions;
  3. 打包:一般定义在打包yml文件中的pack-functions。

支持的域处理函数如下(可以自行扩展):

域处理函数名 说明 参数
fill 填充 参数1(必选):填充方式,left/right分别代表左填充和右填充
参数2(必选):填充字符
参数3(可选):填充长度,缺省为当前域长度
trim 去除空格 参数1(可选):left/right分别代表去左边空格和去右边空格,缺省为左右空格都去掉。
decimalFormat 对数字进行格式化 参数1(必选):根据Java中的DecimalFormat类格式,对数字进行格式化

六、领域层sink connector配置(通讯适配)

1 Netty Connector

通过Netty实现TCP短连接调用。
相关配置参数:

配置项 配置说明
[].connector.type 约定为“netty”
[].connector.host 约定调用的TCP主机地址
[].connector.port 约定调用的TCP端口地址

例子:

- id: netty-server
  type: rest
  url: http://sip-sample-server/netty
  converter:
    type: simple-json
  connector:
    type: netty
    host: 127.0.0.1
    port: 10002

2 RabbitMQ Connector

通过RabbitMQ进行RPC同步调用。
相关配置参数:

配置项 配置说明
[].connector.type 约定为“rabbitmq”
[].connector.exchange 投递消息的exchange目标
[].connector.routing-key 投递消息时的Routing Key

例子:

- id: sink9
  type: rest
  url: http://bizsip-sample-sink/sink9
  converter:
    type: simple-json
  connector:
    type: rabbitmq
    exchange: exchange.dircect.bizsip.sink
    routing-key: key.bizsip.sink9

3 Sink-Bean Connector(不推荐)

注:建议直接采用sink的processor属性值为“sink-bean”的方式

相关配置参数:

配置项 配置说明
[].connector.type 约定为“sink-bean”
[].connector.class-name 约定调用的java类
[].connector.spring-bean 约定是否调用的是Spring容器Bean(缺省是非Spring容器Bean)

例子:

- id: server1
  type: rest
  url: http://sip-sample-server/server1
  converter:
    type: simple-json
  connector:
    type: sink-bean
    class-name: com.bizmda.bizsip.sample.sink.controller.CrmServer

Sink-Bean Connector相关类,可以开发并实现SinkBeanInterface接口的类,并挂接到Sink-Bean Connector上,SinkBeanInterface接口约定如下:

public interface SinkBeanInterface {
    /**
     * JSONObject SinkBean服务调用接口
     * @param jsonObject 传入的消息
     * @return 返回值
     * @throws BizException
     */
    public JSONObject process(JSONObject jsonObject) throws BizException;
}

4 Bean Connector(不推荐)

注:建议直接采用sink的processor属性值为“bean”的方式

Bean Connector能根据sink.yaml和传入数据中包含的约定参数,调用约定的Java类的方法。
在Sink服务内部机制中,是通过传入JSON数据中的className、methodName、params,来分别约定调用的Java类名、方法名、参数列表的,可以在App服务中通过以下代码来调用:

@Service
public class SampleBeanService implements SampleBeanServiceInterface {
    private HelloInterface sampleBeanSinkInterface = AppClientFactory
            .getSinkClient(HelloInterface.class,"sample-bean-sink");

    @Override
    public String callSampleBeanSink(String message) {
        return this.sampleBeanSinkInterface.hello(message);
    }
		.....
}

这里有二点需要注意:

  • 所对应的Sink,要求配置的converter一定是“simple-json”类型,其它类型的converter不支持。
  • 调用Sink后返回的结果,是用“result”作为根节点的JSON报文。

七、典型Source端适配器介绍与配置

对于一些常用的服务接入模式,提供了开箱即用的Source端适配器,可以直接拿来用,也可以在原有的基础上再做个性化改造。

1 RESTful服务接入适配器

RESTful服务接入适配器,是建立RESTful服务器来处理发来的RESTful消息,服务请求URL为“http://{地址}:{端口}/rest”,请求需要以“POST”方式来提交,适配器收到发来的消息后,会发给聚合服务整合器进行处理,并把处理结果同步返回给接入端。
客户端适配器代码放在“source/rest-source”模块中,启动运行程序为“RestSourceApplication.java”。
模块application.yml相关参数:

配置项 配置说明
bizsip.config-path Biz-SIP中间件配置文件根目录位置
bizsip.integrator-url 服务聚合器的开放接口url地址
bizsip.source-id 客户端适配器ID,是在source.yml文件中定义的

2 Netty TCP服务接入适配器

Netty TCP服务接入适配器,是建立一个Netty服务器来侦听指定的端口,收到发来的TCP报文后,会发给聚合服务整合器进行处理,并把处理结果同步返回给接入端,可以支持Biz-SIP所有已支持的消息报文类型。
客户端适配器代码放在“source/netty-source”模块中,启动运行程序为“NettySourceApplication.java”。
模块application.yml相关参数:

配置项 配置说明
bizsip.config-path Biz-SIP中间件配置文件根目录位置
bizsip.integrator-url 服务聚合器的开放接口url地址
bizsip.source-id 客户端适配器ID,是在source.yml文件中定义的
netty.port 定义Netty TCP服务的侦听端口

附录:

1. 服务Script脚本相关对象

在Script服务整合器脚本中,主要使用的特殊对象包括:sip对象、log对象等。

3.1 sip对象

sip.callSink(sinkId,inData)

执行适配器服务调用
参数:

  • sinkId:Sink ID,在sink.yml配置文件中约定。
  • inData:传送给服务端的数据

返回:

  • 服务端返回的数据,是BizMessage内部消息类型。


sip.doDelayService(serviceId,inData,delayMilliseconds1,delayMilliseconds2…)

执行SAF服务调用
参数:

  • serviceId:SAF服务ID,为配置在config/script中的服务脚本。
  • inData:传送给服务的数据,在脚本中以“bizmessage”进行存取。
  • delayMilliseconds…:延迟毫秒数,可以有多个,分别代表第1次、第2次…..的服务延迟毫秒数

返回:

  • SAF子交易的BizMessage内部消息类型。
sip.getServiceRetryCount()

获取SAF服务的当前重试次数
参数:

  • (无)

返回:

  • SAF服务的当前重试次数


sip.saveAsyncContext(transactionKey,context,timeout)

保存异步服务上下文
参数:

  • transactionKey:异步回调的全局唯一交易索引键
  • context:注入回调聚合服务的上下文变量
  • timeout:异步服务超时时间,单位(秒)

返回:

  • (无)


sip.loadAsyncContext(transactionKey)

保存异步服务上下文
参数:

  • transactionKey:异步回调的全局唯一交易索引键

返回:

  • 异步服务上下文


3.2 log对象

// 使用方法与SLF4J完全一致
log.info('Hello');
log.info('Hello {}','MagicAPI');
log.debug('test');

3.3 db对象

select
  • 入参:sql:String
  • 返回值:List<Map<String,Object>>
  • 函数说明:查询List结果
return db.select('select * from sys_user');
selectInt
  • 入参:sql:String
  • 返回值:Integer
  • 函数说明:查询int结果
//需要保证结果返回一行一列
return db.selectInt('select count(*) from sys_user');
selectOne
  • 入参:sql:String
  • 返回值:Map<String,Object>
  • 函数说明:查询单个对象
return db.selectOne('select * from sys_user limit 1');
selectValue
  • 入参:sql:String
  • 返回值:Object
  • 函数说明:查询单个值
//需要保证结果返回一行一列 
return db.selectValue('select user_name from sys_user limit 1');
page
  • 入参:sql:String
  • 入参:limit : long 可省略
  • 入参:offset : long 可省略
  • 返回值:Object 默认返回为Object,如果自定义了分页结果,则返回自定义结果
  • 函数说明:分页查询
//需要保证结果返回一行一列 
return db.page('select * from sys_user');
update
  • 入参:sql:String
  • 返回值:Integer
  • 函数说明:执行增删改操作
return db.update('delete from sys_user');
cache
  • 入参:cacheName:String
  • 入参:ttl:long 缓存有效期,单位毫秒,可省略,默认为配置的值
  • 返回值:db //返回当前实例,即可以链式调用
  • 函数说明:使用缓存
//使用缓存名为user的查询
return db.cache('user').select('select * from sys_user');
transaction
  • 入参:callback:Function,回调函数,可省略
  • 返回值:Object
  • 函数说明:开启事务
  • 自动事务
var val = db.transaction(()=>{
    var v1 = db.update('...');
    var v2 = db.update('....');
    return v2;
});
return val;
  • 手动开启事务
var tx = db.transaction();  //开启事务
try{
    var value = db.update('...');
    db.commit();    // 提交事务
    return value;
}catch(e){
    db.rollback();  // 回滚事务
}

3.4 redis对象

var data = bizmessage.data;
var value = data.accountNo;
//通过redis.命令名(命令参数,命令参数,.....,命令参数) 进行调用,其中命令名不区分大小写
redis.set('key',value); //调用set命令
//redis.setex('key',10,value);    //调用setex命令
data.accountName = redis.get('key');    //调用get命令
return data;
上一页
下一页