2012-05-21 25 views
0

我正在尝试开发一个用于配置动态端口的通用BizTalk应用程序。我有一个编排,将每个端口的所有配置设置都拉回来,我想循环这些设置并配置端口。这些设置保存在MSSQL中,例如,其中两个属性是PortName和Address。所以从编排中我想通过字符串变量PortName来引用端口。那么有什么方法可以获得编排中所有端口的集合或通过字符串变量引用端口,即Port['MyPortName'](Microsoft.XLANGs.BaseTypes.Address) = "file://c:\test\out\%MessageId%.xml"谢谢通过字符串变量在业务流程中引用端口

+0

我意识到我没有严格回答你的问题,而是显示动态应用端口设置的传出消息的上下文。这是等式的第二部分。我会试着弄清楚如何将端口引用为字符串,并在下面改进我的答案。 –

回答

1

首先,您不应该尝试使用Orchestration来完成像这样的配置更改。从技术上讲,做你想做的事是可行的,但作为一种实践,你不应该将业务流程与管理混淆。

执行此类操作的最佳方法是编写一些普通脚本或PowerShell。

要回答你的问题,你可以从BtsOrchestration类,你想要的数据ExplorerOM http://msdn.microsoft.com/en-us/library/microsoft.biztalk.explorerom.btsorchestration_members(v=bts.20)

+0

感谢您的信息,不幸的是您发送的链接无效。不过,我已将ExplorerOM视为可能的解决方案。你能解释为什么我不应该通过编排来设置动态端口吗?我们通常在运行时从SSO撤回这些设置,但是如果它们需要更改,那么我们必须重新启动主机实例,而将它们从SQL撤回意味着它们可以随时重新配置。我现在要做的是让这个过程更通用,可以从任何BT应用程序中调用。 – RedEyedMonster

2

为了动态地从业务流程中配置动态逻辑发送端口,一个具有将设置保存到永久数据存储(例如数据库或配置文件)并实现一种在运行时动态分配这些属性的方法。

但首先,我们需要了解配置动态发送端口时发生了什么。

如何从业务流程中配置动态逻辑发送端口

Configuring the properties of a dynamic logical send port包括两个步骤:

  • 首先,TransportType和目标Address属性必须在发送端口指定。这通常是在表达式形状与代码类似于此完成:

    DynamicSendPort(Microsoft.XLANGs.BaseTypes.TransportType)= “FILE”; DynamicSendPort(Microsoft.XLANGs.BaseTypes.Address)=“C:\ Temp \ Folder \%SourceFileName%”;

  • 其次,必须在传出消息本身的上下文中指定任何附加传输属性。几乎所有的BizTalk适配器都有additional properties用于消息传递引擎和XLANG/s编排引擎之间的通信。例如,使用ReceivedFileName上下文属性为FILE适配器将传出消息保存在其目标位置时动态设置特定名称。这最好的赋值形状内部执行,作为构建输出消息的一部分:

    OutgoingMessage(FILE.ReceiveFileName)=“HardCodedFileName.xml”

你会发现,大多数配置属性必须在传出消息的上下文中指定,指定一个名称空间前缀(例如FILE),一个属性名称(例如ReceiveFileName),以及指定给相应属性的值。

实际上,所有的上下文属性都是生活在内知名的Microsoft.BizTalk.GlobalPropertySchemas.dll程序集中的类。这可以通过在Visual Studio的对象浏览器中查找此程序集来确认。

FILE.ReceivedFileName in Microsoft.BizTalk.GlobalPropertySchemas.dll

即使是需要配置动态逻辑发送端口最上下文属性住这里面具体的装配,不是所有的人做的。例如,MSMQ BizTalk适配器使用单独的程序集来存储其上下文属性。显然,第三方或定制适配器也有附加组件。

因此,为了设置上的动态上下文属性使用类似于一个灵活的方法下面描述发送端口,四种信息是必要的:

  • 含有该组件的全限定名上下文属性类。
  • 命名空间前缀。
  • 属性名称。
  • 属性值。

在持久性介质

以下.XSD模式存储部件,端口设置示出了用于串行端口设置一个可能的结构。

ContextProperties XML Schema Definition

一旦串行化时,指定的上下文属性可以然后被存储在SQL数据库或配置文件变得非常容易。举例来说,这里被用作此职位为例设置:

Example of ContextProperties Settings

了一种灵活的配置动态逻辑发送端口

有了一个简单的辅助库,建立动态端口配置非常容易。首先,您必须从持久介质中检索序列化设置。这可以使用WCF-SQL适配器和一个简单的存储过程轻松实现。一旦检索

,这些属性然后可以反序列化为一个强类型C#对象图。为此,首先创建上面所示的ContextProperties架构的C#表示,其中使用下面的命令行实用程序:

xsd.exe /classes /language:cs /namespace:Helper.Schemas .\ContextProperties.xsd 

这产生可与以下的方法来改善一个局部类:

namespace Helper.Schemas 
{ 
    public partial class ContextProperties 
    { 
     public static ContextProperties Deserialize(string text) 
     { 
      using (MemoryStream stream = new MemoryStream()) 
      { 
       byte[] buffer = Encoding.UTF8.GetBytes(text); 
       stream.Write(buffer, 0, buffer.Length); 
       stream.Seek(0, SeekOrigin.Begin); 
       return (ContextProperties) 
        Deserialize(
          stream 
         , typeof(ContextProperties)); 
      } 
     } 

     public static Object Deserialize(Stream stream, Type type) 
     { 
      XmlSerializer xmlSerializer = new XmlSerializer(type); 
      return xmlSerializer.Deserialize(stream); 
     } 
    } 
} 

其次,应用此配置涉及从代码创建XLANG/s消息,并基于反序列化的ContextProperties对象图中指定的上下文属性类的描述,使用反射动态地设置上下文属性。

对于这一点,我使用Paolo Salvatori的系列文章regarding dynamic transformations,其中包括在创建自定义BTXMessage派生类,通过在BizTalk XLANG/s的引擎在内部使用借来的技术。

namespace Helper.Schemas 
{ 
    using Microsoft.BizTalk.XLANGs.BTXEngine; // Found in Microsoft.XLANGs.BizTalk.Engine 
    using Microsoft.XLANGs.Core; // Found in Microsoft.XLANGs.Engine 

    [Serializable] 
    public sealed class CustomBTXMessage : BTXMessage 
    { 
     public CustomBTXMessage(string messageName, Context context) 
      : base(messageName, context) 
     { 
      context.RefMessage(this); 
     } 

     public void SetContextProperty(string assembly, string ns, string name, object value) 
     { 
      if (String.IsNullOrEmpty(ns)) 
       ns = "Microsoft.XLANGs.BaseTypes"; 
      if (String.IsNullOrEmpty(assembly)) 
       assembly = "Microsoft.BizTalk.GlobalPropertySchemas"; 

      StringBuilder assemblyQualifiedName = new StringBuilder(); 
      assemblyQualifiedName.AppendFormat("{0}.{1}, {2}", ns, name, assembly); 

      Type type = Type.GetType(assemblyQualifiedName.ToString(), true, true); 
      SetContextProperty(type, value); 
     } 

     internal void SetContextProperty(string property, object value) 
     { 
      int index = property.IndexOf('.'); 
      if (index != -1) 
       SetContextProperty(String.Empty, property.Substring(0, index), property.Substring(index + 1), value); 
      else 
       SetContextProperty(String.Empty, String.Empty, property, value); 
     } 

    } 
} 

现在,最后一块难题是如何在Orchestration中使用此自定义类。

namespace Helper.Schemas 
{ 
    using Microsoft.XLANGs.BaseTypes; 
    using Microsoft.XLANGs.Core; // Found in Microsoft.XLANGs.Engine 

    public static class Message 
    { 
     public static XLANGMessage SetContext(XLANGMessage message, ContextProperties properties) 
     { 
      try 
      { 
       // create a new XLANGMessage 

       CustomBTXMessage customBTXMessage = new CustomBTXMessage(message.Name, Service.RootService.XlangStore.OwningContext); 

       // add parts of the original message to it 

       for (int index = 0; index < message.Count; index++) 
        customBTXMessage.AddPart(message[index]); 

       // set the specified context properties 

       foreach (ContextPropertiesContextProperty property in properties.ContextProperty) 
        customBTXMessage.SetContextProperty(property.assembly, [email protected], property.name, property.Value); 

       return customBTXMessage.GetMessageWrapperForUserCode(); 
      } 

      finally 
      { 
       message.Dispose(); 
      } 
     } 
    } 
} 

您可以使用此静态方法您赋值形状里面像以下所示的代码,其中OutboundMessage表示要消息:这是很容易在赋值形状使用下面的助手代码完成设置上下文:

OutboundMessage = Helper.Schemas.Message.SetContext(OutboundMessage, contextProperties); 
相关问题