Pregunta

Estoy intentando desarrollar una aplicación BizTalk genérica para configurar puertos dinámicos.Tengo una orquestación que retira todos los ajustes de configuración para cada puerto y quiero recorrer estos ajustes y configurar los puertos.La configuración se mantiene en MSSQL y, por ejemplo, dos de las propiedades son PortName y Address.Entonces, desde dentro de la orquestación, me gustaría hacer referencia al puerto mediante la variable de cadena PortName.Entonces, ¿hay alguna forma de obtener una colección de todos los puertos en una orquestación o hacer referencia a un puerto a través de una variable de cadena, es decir? Port['MyPortName'](Microsoft.XLANGs.BaseTypes.Address) = "file://c:\test\out\%MessageId%.xml" Gracias

¿Fue útil?

Solución

En primer lugar, no debería intentar realizar cambios de configuración como este mediante una orquestación.Técnicamente es factible hacer lo que está intentando hacer, pero como práctica no debe mezclar su proceso comercial con la administración.

La mejor manera de hacer estas cosas será escribiendo algunos scripts normales o PowerShell.

Para responder a su pregunta, puede obtener los datos que desea de la clase BtsOrchestration en ExplorerOMhttp://msdn.microsoft.com/en-us/library/microsoft.biztalk.explorerom.btsorchestration_members(v=bts.20)

Otros consejos

Para configurar dinámicamente los puertos de envío lógicos dinámicos desde una orquestación, es necesario almacenar la configuración en un almacén de datos persistente (p. ej.una base de datos o un archivo de configuración) e implementar una forma de asignar esas propiedades dinámicamente en tiempo de ejecución.

Pero primero, debemos comprender qué sucede al configurar un puerto de envío dinámico.

Cómo configurar un puerto de envío lógico dinámico

Configurar las propiedades de un puerto de envío lógico dinámico desde dentro de una orquestación implica dos pasos:

  • Primero el Tipo de transporte y objetivo DIRECCIÓN Las propiedades deben especificarse en el puerto de envío.Esto generalmente se hace en un Forma de expresión con un código similar a este:

    DynamicSendPort(Microsoft.XLANGs.BaseTypes.TransportType) = "ARCHIVO";DynamicSendPort(Microsoft.XLANGs.BaseTypes.Address) = "C: emp\Folder\%SourceFileName%";

  • En segundo lugar, cualquier propiedad de transporte adicional debe especificarse en el contexto del propio mensaje saliente.Prácticamente todos los adaptadores de BizTalk tienen propiedades adicionales que se utilizan para la comunicación entre el motor de mensajería y el motor de orquestación XLANG/s.Por ejemplo, el Nombre de archivo recibido La propiedad de contexto se utiliza para establecer dinámicamente un nombre específico para cuando el adaptador FILE guarde el mensaje saliente en su ubicación de destino.Esto se realiza mejor dentro de un Forma de asignación, como parte de la construcción del mensaje saliente:

    OutgoingMessage(FILE.ReceiveFileName) = "HardCodedFileName.xml"

Notarás que la mayoría de las propiedades de configuración deben especificarse en el contexto de los mensajes salientes, especificando un prefijo de espacio de nombres (p. ej.ARCHIVO), un nombre de propiedad (p. ej.RecibirFileName) y, obviamente, el valor que se asigna a la propiedad correspondiente.

De hecho, todas las propiedades de contexto son clases que viven dentro del bien conocido Microsoft.BizTalk.GlobalPropertySchemas.dll asamblea.Esto se confirma buscando este ensamblaje en el explorador de objetos de Visual Studio.

FILE.ReceivedFileName in Microsoft.BizTalk.GlobalPropertySchemas.dll

Aunque la mayoría de las propiedades de contexto necesarias para configurar los puertos de envío lógicos dinámicos se encuentran dentro de este ensamblaje específico, no todas lo hacen.Por ejemplo, el adaptador MSMQ BizTalk utiliza un ensamblado independiente para almacenar sus propiedades de contexto.Obviamente, los adaptadores personalizados o de terceros también vienen con conjuntos adicionales.

Por lo tanto, para configurar una propiedad de contexto en un puerto de envío dinámico utilizando un enfoque flexible como el que se describe a continuación, se necesitan cuatro datos:

  • El nombre completo del ensamblado que contiene las clases de propiedad de contexto.
  • El prefijo del espacio de nombres.
  • El nombre de la propiedad.
  • El valor de la propiedad.

Almacenamiento de la configuración del puerto en un medio persistente

El siguiente esquema .XSD ilustra una posible estructura para serializar la configuración del puerto.

ContextProperties XML Schema Definition

Una vez serializadas, las propiedades de contexto especificadas se pueden almacenar en una base de datos SQL o en un archivo de configuración muy fácilmente.Por ejemplo, aquí están las configuraciones utilizadas como ejemplo en esta publicación:

Example of ContextProperties Settings

Un enfoque flexible para configurar puertos de envío lógicos dinámicos

Con una biblioteca auxiliar simple, configurar la configuración del puerto dinámico es muy fácil.Primero, debes recuperar la configuración serializada del medio persistente.Esto se puede lograr fácilmente utilizando el adaptador WCF-SQL y un procedimiento almacenado simple.

Una vez recuperadas, esas propiedades se pueden deserializar en un gráfico de objetos C# fuertemente tipado.Para ello, primero cree una representación en C# del esquema ContextProperties que se muestra arriba, utilizando la siguiente utilidad de línea de comandos:

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

Esto genera una clase parcial que se puede mejorar con el siguiente método:

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);
        }
    }
}

En segundo lugar, aplicar esta configuración implica crear un mensaje XLANG/s a partir del código y configurar las propiedades de contexto dinámicamente mediante la reflexión, según la descripción de las clases de propiedades de contexto especificadas en el gráfico de objetos ContextProperties deserializado.

Para ello, utilizo una técnica tomada de paolo salvatoriserie de artículos sobre transformaciones dinámicas, que consiste en crear un personalizado Mensaje BTX-clase derivada, utilizada internamente por el motor 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);
        }

    }
}

Ahora, la última pieza del rompecabezas es cómo utilizar esta clase personalizada desde una orquestación.Esto se hace fácilmente en un Forma de asignación usando el siguiente código auxiliar:

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, property.@namespace, property.name, property.Value);

                return customBTXMessage.GetMessageWrapperForUserCode();
            }

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

Puedes usar este método estático dentro de tu Forma de asignación como el código que se muestra a continuación, donde OutboundMessage representa el mensaje cuyo contexto desea establecer:

OutboundMessage = Helper.Schemas.Message.SetContext(OutboundMessage, contextProperties);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top