Biz-SIP金融级业务中台(http://bizsip.bizmda.com)是一套基于领域驱动设计(DDD)架构,能快速构建金融级云原生架构的服务整合中间件,整合了在金融场景里锤炼出来的最佳实践。
Biz-SIP业务中台支持多种报文类型的格式转换器(Converter),包括XML、JSON、定长、有分隔符、ISO-8583等报文类型的解包和打包。
Biz-SIP业务中台支持多种连接方式的通讯适配器(Connector),包括TCP、RabbitMQ、HTTP、调用Spring服务等通讯适配方式。
在Sink服务中,可以通过Java API接口调用Converter,在Sink服务类代码中实现报文解包和打包;通过Java API接口调用Connector,在Sink服务类代码中实现通讯的连接适配。
本节案例中是在Sink服务类中,通过Java API调用模板XML格式转换器(velocity-xml),实现XML报文的打包和解包,并通过Java API调用Spring服务通讯适配器,实现对EchoConnectorService服务类的调用:
其中,App层是通过Sink透传App服务,直接让调用方通过OpenAPI接口调用Sink服务(sample17-sink),Sink服务调用格式转换器(Converter),把平台内部标准格式(JSONObject对象,内部即JSON报文)进行打包成XML报文,传给通讯适配器(Connector),原包返回后再解包成平台内部标准格式,响应给调用方。
具体代码和配置可以查看Biz-SIP源代码中的Sample相关测试案例(https://gitee.com/szhengye/biz-sip)
一、Sink层Sink服务的开发和配置
首先,在Biz-SIP配置目录的sink.yml中,配置对应的Sink服务:
- id: sample17-sink
type: rest
url: http://bizsip-sample-sink/sample17-sink
processor: sink-bean
class-name: com.bizmda.bizsip.sample.sink.service.Sample17SinkBeanService
converter:
type: velocity-xml
pack-rules:
- predicate: '#{#data[sex]=="0"}'
rule: velocity-xml-sink/woman.vm
- predicate: '#{#data[sex]=="1"}'
rule: velocity-xml-sink/man.vm
- predicate:
rule: velocity-xml-sink/error.vm
unpack-rules:
connector:
type: service
class-name: com.bizmda.bizsip.sample.sink.service.EchoConnectorService
可以看到sample17-sink这个Sink服务,connector关联了能把请求报文直接原包响应返回的EchoConnectorService类。而格式转换器converter,设置为“type: velocity-xml”,表示采用基于velocity模板的XML格式转换器,作为当前Sink服务的格式转换器。
这个Sink服务processor属性为“sink-bean”,表示Sink服务,会调用标准Sink处理接口的Sink Bean类来进行处理,class-name(关联的服务类)为“com.bizmda.bizsip.sample.sink.service.Sample17SinkBeanService”,相关代码如下:
@Slf4j
@Service
public class Sample17SinkBeanService extends AbstractSinkService implements SinkBeanInterface {
@Override
public JSONObject process(JSONObject inJsonObject) throws BizException {
log.debug("收到报文:\n{}", BizUtils.buildJsonLog(inJsonObject));
byte[] inBytes = this.converter.pack(inJsonObject);
log.debug("打包后报文:\n{}",BizUtils.buildHexLog(inBytes));
byte[] outBytes = this.connector.process(inBytes);
log.debug("Connector返回报文:\n{}",BizUtils.buildHexLog(outBytes));
JSONObject outJsonObject = this.converter.unpack(outBytes);
log.debug("解包后报文:\n{}",BizUtils.buildJsonLog(outJsonObject));
return outJsonObject;
}
}
可以看到Sample17SinkBeanService类实现了标准Sink处理接口(SinkBeanInterface),实现了process()方法(出入参数为平台标准的JSONObject对象),并且继承了AbstractSinkService类(继承AbstractSinkService类,能自动将sink.yml中对应Sink所配置的Converter和Connector注入到converter、connector实例变量中)。
在process()方法中,主要有以下处理步骤:
- 调用this.converter.pack()进行打包;
- 把打包后的XML报文通过this.connector.process()方法调用配置好的Spring服务类;
- 调用this.converter.unpack(),对返回的XML报文解包成平台标准JSONObject对象,并返回。
最后,还需要在SampleSinkApplication的应用配置文件application-local.yml中,在bizsip.sink-id配置项中,增加sample17-sink以便启动Sink服务:
bizsip:
config-path: /var/bizsip/config
sink-id: hello-sink,echo-sink,simple-xml-sink,velocity-json-sink,velocity-xml-sink,fixed-length-sink,velocity-split-sink,iso-8583-sink,sample17-sink
二、App层App服务的开发和配置
对于Sink透传App服务,只需要在app.yml中配置即可:
- app-service-id: /sink/sample17-sink
type: sink-service
sink-id: sample17-sink
可以看到在app.yml中,配置了App服务“/sink/sample17-sink”,类型为Sink透传App服务(sink-service),透传调用的Sink服务为“sample17-sink”。
三、启动应用进行测试
启动SampleSinkApplication、SampleAppApplication应用,通过OpenAPI接口进行测试:
$ curl -H "Content-Type:application/json" -H "Biz-Service-Id:/sink/sample17-sink" -X POST --data '{"accountName": "王五","sex": "0","accountNo":"005","balance":100}' http://localhost:8888/api|jq
{
"code": 0,
"message": "success",
"extMessage": null,
"appServiceId": "/sink/sample17-sink",
"traceId": "65b72dc4907b40da8c74a16624c3d645",
"parentTraceId": null,
"timestamp": 1647613188390,
"data": {
"account": {
"no": "005",
"sex": "女人",
"balance": 100,
"name": "王五"
}
}
}
SampleSinkApplication应用打印日志:
[bizsip-sample-sink:192.169.1.105:8001] 22:19:48 DEBUG 5022 [65b72dc4907b40da8c74a16624c3d645] [http-nio-8001-exec-1] c.b.b.s.processor.SinkBeanSinkProcessor 调用Sink服务[sample17-sink](处理器类型sink-bean:com.bizmda.bizsip.sample.sink.service.Sample17SinkBeanService)
[bizsip-sample-sink:192.169.1.105:8001] 22:19:48 DEBUG 5022 [65b72dc4907b40da8c74a16624c3d645] [http-nio-8001-exec-1] c.b.b.s.s.s.Sample17SinkBeanService 收到报文:
{
"accountName": "王五",
"sex": "0",
"balance": 100,
"accountNo": "005"
}
[bizsip-sample-sink:192.169.1.105:8001] 22:19:48 DEBUG 5022 [65b72dc4907b40da8c74a16624c3d645] [http-nio-8001-exec-1] c.b.b.s.s.s.Sample17SinkBeanService 打包后报文:
==== 01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20 ====== ASCII ======
0000: 3C 61 63 63 6F 75 6E 74 3E 0A 20 20 20 20 3C 6E 61 6D 65 3E | <account>. <name> |
0020: E7 8E 8B E4 BA 94 3C 2F 6E 61 6D 65 3E 0A 20 20 20 20 3C 62 | 王.五.</name>. <b |
0040: 61 6C 61 6E 63 65 3E 31 30 30 3C 2F 62 61 6C 61 6E 63 65 3E | alance>100</balance> |
0060: 0A 20 20 20 20 3C 6E 6F 3E 30 30 35 3C 2F 6E 6F 3E 0A 20 20 | . <no>005</no>. |
0080: 20 20 3C 73 65 78 3E E5 A5 B3 E4 BA BA 3C 2F 73 65 78 3E 0A | <sex>女.人.</sex>. |
0100: 3C 2F 61 63 63 6F 75 6E 74 3E | </account>.......... |
[bizsip-sample-sink:192.169.1.105:8001] 22:19:48 DEBUG 5022 [65b72dc4907b40da8c74a16624c3d645] [http-nio-8001-exec-1] c.b.b.s.connector.ServiceSinkConnector 调用ServiceSinkConnector: class-name=com.bizmda.bizsip.sample.sink.service.EchoConnectorService
[bizsip-sample-sink:192.169.1.105:8001] 22:19:48 DEBUG 5022 [65b72dc4907b40da8c74a16624c3d645] [http-nio-8001-exec-1] c.b.b.s.s.service.EchoConnectorService 收到报文:
==== 01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20 ====== ASCII ======
0000: 3C 61 63 63 6F 75 6E 74 3E 0A 20 20 20 20 3C 6E 61 6D 65 3E | <account>. <name> |
0020: E7 8E 8B E4 BA 94 3C 2F 6E 61 6D 65 3E 0A 20 20 20 20 3C 62 | 王.五.</name>. <b |
0040: 61 6C 61 6E 63 65 3E 31 30 30 3C 2F 62 61 6C 61 6E 63 65 3E | alance>100</balance> |
0060: 0A 20 20 20 20 3C 6E 6F 3E 30 30 35 3C 2F 6E 6F 3E 0A 20 20 | . <no>005</no>. |
0080: 20 20 3C 73 65 78 3E E5 A5 B3 E4 BA BA 3C 2F 73 65 78 3E 0A | <sex>女.人.</sex>. |
0100: 3C 2F 61 63 63 6F 75 6E 74 3E | </account>.......... |
[bizsip-sample-sink:192.169.1.105:8001] 22:19:48 DEBUG 5022 [65b72dc4907b40da8c74a16624c3d645] [http-nio-8001-exec-1] c.b.b.s.s.s.Sample17SinkBeanService Connector返回报文:
==== 01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20 ====== ASCII ======
0000: 3C 61 63 63 6F 75 6E 74 3E 0A 20 20 20 20 3C 6E 61 6D 65 3E | <account>. <name> |
0020: E7 8E 8B E4 BA 94 3C 2F 6E 61 6D 65 3E 0A 20 20 20 20 3C 62 | 王.五.</name>. <b |
0040: 61 6C 61 6E 63 65 3E 31 30 30 3C 2F 62 61 6C 61 6E 63 65 3E | alance>100</balance> |
0060: 0A 20 20 20 20 3C 6E 6F 3E 30 30 35 3C 2F 6E 6F 3E 0A 20 20 | . <no>005</no>. |
0080: 20 20 3C 73 65 78 3E E5 A5 B3 E4 BA BA 3C 2F 73 65 78 3E 0A | <sex>女.人.</sex>. |
0100: 3C 2F 61 63 63 6F 75 6E 74 3E | </account>.......... |
[bizsip-sample-sink:192.169.1.105:8001] 22:19:48 DEBUG 5022 [65b72dc4907b40da8c74a16624c3d645] [http-nio-8001-exec-1] c.b.b.s.s.s.Sample17SinkBeanService 解包后报文:
{
"account": {
"no": "005",
"sex": "女人",
"balance": 100,
"name": "王五"
}
}
,Biz-SIP网站:http://bizsip.bizmda.comGitee代码库:https://gitee.com/szhengye/biz-sip