Pergunta

Estou tentando desenvolver um aplicativo BizTalk genérico para configurar portas dinâmicas.Eu tenho uma orquestração que recupera todas as definições de configuração de cada porta e quero percorrer essas configurações e configurar as portas.As configurações são mantidas em MSSQL e, por exemplo, duas das propriedades são PortName e Address.Então, dentro da orquestração, gostaria de fazer referência à porta pela variável de string PortName.Então, existe alguma maneira de obter uma coleção de todas as portas em uma orquestração ou referenciar uma porta por meio de uma variável de string, ou seja, Port['MyPortName'](Microsoft.XLANGs.BaseTypes.Address) = "file://c:\test\out\%MessageId%.xml" Obrigado

Foi útil?

Solução

Em primeiro lugar você não deve tentar fazer alterações de configuração como esta usando uma orquestração.Tecnicamente, é viável fazer o que você está tentando fazer, mas como uma prática você não deve misturar seu processo de negócios com a administração.

A melhor maneira de fazer essas coisas será escrevendo alguns scripts normais ou PowerShell.

Para responder a você, você pode obter os dados que deseja da classe Btsorchestration no explorerom http://msdn.microsoft.com / pt-us / biblioteca / microsoft.biztalk.explorerom.btsorchestration_members (v= bts.20)

Outras dicas

Para configurar dinamicamente Portas de Envio Lógicas Dinâmicas de dentro de uma orquestração, é necessário armazenar as configurações em um armazenamento de dados persistente (por exemplo,um banco de dados ou arquivo de configuração) e implementar uma maneira de atribuir essas propriedades dinamicamente em tempo de execução.

Mas primeiro precisamos entender o que está acontecendo ao configurar uma Porta de Envio Dinâmico.

Como configurar uma porta de envio lógica dinâmica

Configurando as propriedades de uma porta de envio lógica dinâmica de dentro de uma orquestração envolve duas etapas:

  • Primeiro, o Tipo de transporte e alvo Endereço as propriedades devem ser especificadas na porta de envio.Isso geralmente é feito em um Forma de Expressão com código semelhante a este:

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

  • Segundo, quaisquer propriedades de transporte adicionais devem ser especificadas no contexto da própria mensagem de saída.Praticamente todos os adaptadores BizTalk possuem propriedades adicionais que são usados ​​para a comunicação entre o Messaging Engine e o XLANG/s Orchestration Engine.Por exemplo, o Nome do arquivo recebido A propriedade context é usada para definir dinamicamente um nome específico para quando o adaptador FILE salvará a mensagem de saída em seu local de destino.Isto é melhor realizado dentro de um Forma de Atribuição, como parte da construção da mensagem de saída:

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

Você notará que a maioria das propriedades de configuração devem ser especificadas no contexto das mensagens de saída, especificando um prefixo de namespace (por exemplo,FILE), um nome de propriedade (por exemplo,ReceiveFileName) e, obviamente, o valor atribuído à propriedade correspondente.

Na verdade, todas as propriedades de contexto são classes que vivem dentro do bem conhecido Microsoft.BizTalk.GlobalPropertySchemas.dll conjunto.Isso é confirmado pesquisando esse assembly no explorador de objetos do Visual Studio.

FILE.ReceivedFileName in Microsoft.BizTalk.GlobalPropertySchemas.dll

Embora a maioria das propriedades de contexto necessárias para configurar portas de envio lógicas dinâmicas residam dentro deste assembly específico, nem todas elas o fazem.Por exemplo, o adaptador MSMQ BizTalk usa um assembly separado para armazenar suas propriedades de contexto.Obviamente, adaptadores de terceiros ou personalizados também vêm com montagens adicionais.

Portanto, para configurar uma propriedade de contexto em uma Porta de Envio Dinâmico usando uma abordagem flexível como a descrita abaixo, são necessárias quatro informações:

  • O nome completo do assembly que contém as classes de propriedades de contexto.
  • O prefixo do namespace.
  • O nome da propriedade.
  • O valor da propriedade.

Armazenando configurações de porta em um meio persistente

O esquema .XSD a seguir ilustra uma estrutura possível para serializar configurações de porta.

ContextProperties XML Schema Definition

Depois de serializadas, as propriedades de contexto especificadas podem ser armazenadas em um banco de dados SQL ou em um arquivo de configuração com muita facilidade.Por exemplo, aqui estão as configurações usadas como exemplo nesta postagem:

Example of ContextProperties Settings

Uma abordagem flexível para configurar portas de envio lógicas dinâmicas

Com uma biblioteca auxiliar simples, definir a configuração dinâmica da porta é muito fácil.Primeiro, você precisa recuperar as configurações serializadas da mídia persistente.Isso pode ser facilmente alcançado usando o adaptador WCF-SQL e um procedimento armazenado simples.

Depois de recuperadas, essas propriedades podem ser desserializadas em um gráfico de objeto C# fortemente tipado.Para isso, primeiro crie uma representação C# do esquema ContextProperties mostrado acima, usando o seguinte utilitário de linha de comando:

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

Isso gera uma classe parcial que pode ser melhorada com o seguinte 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);
        }
    }
}

Em segundo lugar, a aplicação dessa configuração envolve a criação de uma mensagem XLANG/s a partir do código e a configuração das propriedades de contexto dinamicamente usando reflexão, com base na descrição das classes de propriedades de contexto especificadas no gráfico do objeto ContextProperties desserializado.

Para isso, utilizo uma técnica emprestada de Paulo Salvatorisérie de artigos sobre transformações dinâmicas, que consiste em criar um custom Mensagem BTXclasse derivada, usada internamente pelo mecanismo 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);
        }

    }
}

Agora, a última peça do quebra-cabeça é como usar essa classe personalizada dentro de uma orquestração.Isto é feito facilmente em um Forma de Atribuição usando o seguinte 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();
            }
        }
    }
}

Você pode usar este método estático dentro do seu Forma de Atribuição como o código mostrado a seguir, onde OutboundMessage representa a mensagem cujo contexto você deseja definir:

OutboundMessage = Helper.Schemas.Message.SetContext(OutboundMessage, contextProperties);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top