一、 绑定方式 – dynamic(动态)
动态绑定这种绑定方式只有orchestration发送端口有,orchestration接收端口不具有这种绑定方式。(注意:sql adapter不支持动态绑定)
所谓动态,就是跟orchestration发送端口绑定的物理发送端口是动态发送端口(物理发送端口有静态发送端口和动态发送端口),这种动态发送端口只有管道的设置,没有端口使用的适配器和URI的设置,运行时根据消息中上下文属性来决定使用的适配器类型和URI的相关属性。这样一个发送端口可以动态的路由消息到不同的适配器的不同的地址。
1、 测试场景
设想这种需求,在一个文件夹中有个消息,类似这样:
<ns0:Person xmlns:ns0="http://BindingDynamic.InputSch">
<Method>mail</Method>
<Body>
<id>id_0</id>
<name>name_0</name>
</Body>
</ns0:Person>
读取此消息,并需要根据Method元素指定的方式把此消息发送到不同的地方,Method有三种可能:
file – 把消息用file适配器发送到指定文件夹
mail – 把消息用smtp适配器发送到指定的邮箱
ftp – 把消息用ftp适配器发送到指定的ftp服务器
2、 设计项目
设计一个跟消息相匹配的消息架构,并把架构中Method元素设为可分辨字段,因为需要在orchestration中使用这个字段作为分支判断条件。
设计流程如下:
Figure 12. dynamic绑定测试流程
输入消息通过Port_Person_In端口绑定单向接收端口从指定的文件夹中读取。
通过Decide形状根据Method元素的三种可能的值分别处理file、mail和ftp时的情况。
在orchestration中分别建立三个跟入站消息同类型的消息分别对应三种情况需要构造的消息。
OutFileMsg消息对应要输出到文件夹的消息。
OutMailMsg消息对应要发送到email的消息。
OutFtpMsg消息对应要上传到ftp服务器的消息。
Port_Person_Out端口配置为动态发送端口,orchestrastion的动态端口在部署后会自动在biztalk控制台生成相应的物理动态发送端口并绑定。物理动态发送端口根据orchestration的动态端口发出消息的上下文属性BTS.OutboundTransportType(决定使用何种适配器)和BTS.OutboundTransportLocation(决定消息发送到的URI)把消息发送到不同的适配器。流程根据输入的消息构造不同的消息(这里是消息类型一样,上下文属性不同),都是通过orchestrastion的动态端口发送出去。
2.1. 构造file适配器发送消息
ConstructMsg_File构造要输出到文件夹的OutFileMsg消息:
OutFileMsg = InPersonMsg; //将入站消息赋给OutFileMsg
Port_Person_Out(Microsoft.XLANGs.BaseTypes.Address) = @"file://C:/Samples/BindingDynamic/Out/File_%MessageID%.xml";
2.2. 构造smtp适配器消息
ConstructMsg_Mail构造要输出到文件夹的OutMailMsg消息:
OutMailMsg = InPersonMsg;
Port_Person_Out(Microsoft.XLANGs.BaseTypes.Address) = "mailto:testname@yeah.net"; //目的地email地址
OutMailMsg(SMTP.EmailBodyTextCharset)="UTF-8"; //正文编码
OutMailMsg(SMTP.Subject) = "test"; //邮件主题
OutMailMsg(SMTP.MessagePartsAttachments) = 2; //表示消息的所有部分都作为附件发送
OutMailMsg(SMTP.SMTPAuthenticate) = 1; //基本验证,使用明码发送用户名和密码
OutMailMsg(SMTP.From) = "username@yeah.net"; //from的email地址
OutMailMsg(SMTP.SMTPHost) = "smtp.yeah.net"; //smtp服务器
OutMailMsg(SMTP.Username) = "username"; //smtp验证用户名
OutMailMsg(SMTP.Password) = "password"; //密码
2.3. 构造ftp适配器消息
ConstructMsg_Ftp构造要输出到文件夹的OutFtplMsg消息:
OutFtpMsg = InPersonMsg;
Port_Person_Out(Microsoft.XLANGs.BaseTypes.Address) = "ftp://ftpserver.com";
OutFtpMsg(FTP.UserName) = " username ";
OutFtpMsg(FTP.Password) = " password ";
3、 发往动态端口消息的属性
发往动态端口的消息依靠消息上下文属性BTS.OutboundTransportType、BTS.OutboundTransportLocation决定端口最终使用哪种适配器和发往的地址。消息在发送Messagebox路由到动态发送端口前必须把这两个属性升级到消息上下文。
Biztalk是通过在orchestration的表达式中给orchestration动态绑定端口的Microsoft.XLANGs.BaseTypes.Address赋值来给消息的BTS.OutboundTransportType、BTS.OutboundTransportLocation属性升级的。
赋值形式是这样:
DynamicPortName(Microsoft.XLANGs.BaseTypes.Address) = "前缀别名+URI";
比如,发送到smtp适配器,email地址为testuname@yeah.net,赋值语句是这样:
Port_Person_Out(Microsoft.XLANGs.BaseTypes.Address) = "mailto:testname@yeah.net";
下表是biztalk中所有可用于动态发送端口的适配器、前缀别名和适配器名:
适配器 | 前缀别名 | 适配器名 |
HTTP adapter | HTTP:// | HTTP |
SOAP adapter | SOAP:// | SOAP |
FILE adapter | FILE:// | FILE |
Windows SharePoint Services adapter | WSS:// | Windows SharePoint Services |
SMTP adapter | MAILTO: | SMTP |
SQL adapter | SQL:// | SQL |
FTP adapter | FTP:// | FTP |
MSMQ adapter | MSMQ:// | MSMQ |
MQSeries adapter | MQS:// | MQSeries |
EDI adapter | EDI:// | EDI |
当消息到了orchestration的动态绑定发送端口后, rchestration引擎根据端口的Microsoft.XLANGs.BaseTypes.Address属性的值,把适配器前缀别名转换成相应的适配器名,然后作为消息的BTS.OutboundTransportTyp属性升级到消息的上下文。Microsoft.XLANGs.BaseTypes.Address把属性的URI部分作为消息的BTS.OutboundTransportLocation属性升级到消息的上下文。
有一点需要注意:
必须要给orchestration的动态绑定发送端口的Microsoft.XLANGs.BaseTypes.Address属性赋值,否则编译会通不过,编译器提示你动态发送端口没有被初始化。不要试图在消息进入到orchestration的动态绑定发送端口前使用表达式给消息的BTS.OutboundTransportType、BTS.OutboundTransportLocation属性进行赋值,因为这两个消息属性在orchestration的动态绑定发送端口会被orchestration的动态绑定发送端口的Microsoft.XLANGs.BaseTypes.Address属性的值覆盖掉。
4、 查看消息订阅
编译项目,部署。
配置项目,接收端口是specify later绑定类型端口,配置中使用file适配器指向指定的文件夹。
物理动态发送端口在部署好后已经自动建立并跟orchestration的动态绑定端口绑定。
启动部署好的应用程序,看产生的订阅:
Figure 13. dynamic绑定订阅
第一个订阅是orchestration接收端口跟file适配器接收端口的specify later绑定产生的订阅,接收来自文件的消息,这种订阅前面已经讨论过。
后面后十个订阅,形式看上去类似,先来看第一个订阅的详情,“General”标签:
Figure 14. Dynamic动态发送端口订阅
Service class是订阅消息的服务类型,这里是Messaging类型,就是只一般的端口类型服务。
Service name是订阅消息的具体服务,这里是BindingDynamic_ 1.0.0 .0_BindingDynamic.OrcheBindingDynamic_Port_Person_Out_380d269ec 565a 18c ,就是物理动态发送端口。
“Expression”标签:
Figure 14. Dynamic动态发送端口订阅条件
订阅条件是:
Subscription:
{
ORGroup0
{
BTS.OutboundTransportType == FILE
And
BTS.SPID == {BA5CD1EE-19D8-4904 -88A 3-EE 999F 52870E}
And
BTS.OutboundTransportLocation Exists
}
}
这个订阅表示接收BTS.OutboundTransportType属性类型指定file适配器的,并且消息中BTS.OutboundTransportLocation属性存在的,消息中BTS.SPID属性指向这个动态物理发送端口。消息的BTS.SPID属性在orchestration端口跟动态物理发送端口绑定后,在消息到了orchestration端口后在端口中把BTS.SPID属性升级到消息上下文的。
类似订阅一共有十个,分别订阅所有十个可用于动态发送端口的适配器,每个订阅对应一种适配器,适应消息中可能出现的各种适配器名。订阅的服务都是这个物理动态发送端口。
这十个订阅的订阅主体都是这个物理动态发送端口,只是订阅的条件有些不同,根据订阅的原理,应该可以把这十个订阅合并为一个订阅,把订阅条件用或组合并在一起就行了,类似这样:
Subscription:
{
ORGroup0
{
BTS.OutboundTransportType == FILE
And
BTS.SPID == {BA5CD1EE-19D8-4904 -88A 3-EE 999F 52870E}
And
BTS.OutboundTransportLocation Exists
}
OR
ORGroup1
{
BTS.OutboundTransportType == SOAP
And
BTS.SPID == {BA5CD1EE-19D8-4904 -88A 3-EE 999F 52870E}
And
BTS.OutboundTransportLocation Exists
}
OR
ORGroup2
{
BTS.OutboundTransportType == SMTP
And
BTS.SPID == {BA5CD1EE-19D8-4904 -88A 3-EE 999F 52870E}
And
BTS.OutboundTransportLocation Exists
}
……
}
项目的测试代码下载:BindingDynamic.rar