Filtros de mensagem
Para implementar o roteamento baseado em conteúdo, o Serviço de Roteamento usa implementações MessageFilter que inspecionam seções específicas de uma mensagem, como o endereço, o nome do ponto de extremidade ou uma instrução XPath específica. Se nenhum dos filtros de mensagem fornecidos com o .NET Framework 4.6.1 atender às suas necessidades, é possível criar um filtro personalizado criando uma nova implementação da classe base MessageFilter.
Ao configurar o Serviço de Roteamento, defina os elementos de filtro (objetos FilterElement) que descrevem o tipo de MessageFilter e todos os dados de suporte necessários para criar o filtro, como valores de cadeia de caracteres específicos a serem pesquisados na mensagem. Observe que a criação dos elementos de filtro define apenas os filtros de mensagem individuais; para usar os filtros para avaliar e rotear mensagens, também será necessário definir uma tabela de filtro (FilterTableEntryCollection).
Cada entrada na tabela de filtro faz referência a um elemento de filtro e especifica o ponto de extremidade do cliente para o qual uma mensagem será roteada se corresponder ao filtro. As entradas da tabela de filtro também permitem que você especifique uma coleção de pontos de extremidade de backup (BackupEndpointCollection), que define uma lista de pontos de extremidade para os quais a mensagem será transmitida em caso de falha de transmissão no envio para o ponto de extremidade primário. Esses pontos de extremidade serão testados na ordem especificada até que um seja bem-sucedido.
Filtros de mensagem
Os filtros de mensagem usados pelo Serviço de Roteamento possuem a funcionalidade de seleção de mensagem comum, como avaliar o nome do ponto de extremidade ao qual uma mensagem foi enviada, a ação SOAP ou o endereço ou prefixo de endereço para o qual a mensagem foi enviada. Os filtros também podem ser associados a uma condição AND
, de modo que as mensagens só serão roteadas para um ponto de extremidade se corresponderem aos dois filtros. Também é possível criar filtros personalizados criando sua própria implementação de MessageFilter.
A tabela a seguir lista o FilterType usado pelo Serviço de Roteamento, a classe que implementa o filtro de mensagem específico e os parâmetros FilterData necessários.
Tipo de Filtro | Descrição | Filtrar o significado de dados | Filtro de exemplo |
---|---|---|---|
Ação | Usa a classe ActionMessageFilter para corresponder às mensagens que contêm uma ação específica. | A ação a ser filtrada. | <filter name="action1" filterType="Action" filterData="http://namespace/contract/operation" /> |
EndpointAddress | Usa a classe EndpointAddressMessageFilter com IncludeHostNameInComparison == true para corresponder às mensagens que contêm um endereço específico. |
O endereço a ser filtrado (no cabeçalho Para). | <filter name="address1" filterType="EndpointAddress" filterData="http://host/vdir/s.svc/b" /> |
EndpointAddressPrefix | Usa a classe PrefixEndpointAddressMessageFilter com IncludeHostNameInComparison == true para corresponder às mensagens que contêm um prefixo de endereço específico. |
O endereço a ser filtrado usando a correspondência de prefixo mais longa. | <filter name="prefix1" filterType="EndpointAddressPrefix" filterData="http://host/" /> |
And | Usa a classe StrictAndMessageFilter que sempre avalia as duas condições antes de retornar. | filterData não é usado; Em vez disso, filter1 e filter2 têm os nomes dos filtros de mensagem correspondentes (também na tabela), que devem ser ANDed juntos. | <filter name="and1" filterType="And" filter1="address1" filter2="action1" /> |
Personalizado | Um tipo definido pelo usuário que estende a classe MessageFilter e tem um construtor tomando uma cadeia de caracteres. | O atributo customType é o nome de tipo totalmente qualificado da classe a ser criada; filterData é a cadeia de caracteres a ser passada para o construtor na criação do filtro. | <filter name="custom1" filterType="Custom" customType="CustomAssembly.CustomMsgFilter, CustomAssembly" filterData="Custom Data" /> |
EndpointName | Usa a classe EndpointNameMessageFilter para corresponder às mensagens com base no nome do ponto de extremidade de serviço no qual elas chegaram. | O nome do ponto de extremidade de serviço, por exemplo: "serviceEndpoint1". Deve ser um dos pontos de extremidade expostos no Serviço de Roteamento. | <filter name="stock1" filterType="Endpoint" filterData="SvcEndpoint" /> |
MatchAll | Usa a classe MatchAllMessageFilter. Esse filtro corresponde a todas as mensagens recebidas. | filterData não é usado. Esse filtro sempre corresponderá a todas as mensagens. | <filter name="matchAll1" filterType="MatchAll" /> |
XPath | Usa a classe XPathMessageFilter para corresponder a consultas XPath específicas na mensagem. | A consulta XPath a ser usada ao corresponder mensagens. | <filter name="XPath1" filterType="XPath" filterData="//ns:element" /> |
O exemplo a seguir define as entradas de filtro que usam os filtros de mensagem XPath, EndpointName e PrefixEndpointAddress. Este exemplo também demonstra o uso de um filtro personalizado para as entradas RoundRobinFilter1 e RoundRobinFilter2.
<filters>
<filter name="XPathFilter" filterType="XPath"
filterData="/s12:Envelope/s12:Header/custom:RoundingCalculator = 1"/>
<filter name="EndpointNameFilter" filterType="EndpointName"
filterData="calculatorEndpoint"/>
<filter name="PrefixAddressFilter" filterType="PrefixEndpointAddress"
filterData="http://localhost/routingservice/router/rounding/"/>
<filter name="RoundRobinFilter1" filterType="Custom"
customType="RoutingServiceFilters.RoundRobinMessageFilter,
RoutingService" filterData="group1"/>
<filter name="RoundRobinFilter2" filterType="Custom"
customType="RoutingServiceFilters.RoundRobinMessageFilter,
RoutingService" filterData="group1"/>
</filters>
Observação
A simples definição de um filtro não faz com que as mensagens sejam avaliadas com base no filtro. O filtro deve ser adicionado a uma tabela de filtro, que é associada ao ponto de extremidade de serviço exposto pelo Serviço de Roteamento.
Tabela de Namespace
Ao usar um filtro XPath, os dados de filtro que contêm a consulta XPath podem se tornar extremamente grandes devido ao uso de namespaces. Para atenuar esse problema, o Serviço de Roteamento fornece a capacidade de definir seus próprios prefixos de namespace usando a tabela de namespace.
A tabela de namespace é uma coleção de objetos NamespaceElement que define os prefixos de namespace para namespaces comuns que podem ser usados em um XPath. Os namespaces padrão e os prefixos de namespace contidos na tabela de namespace podem ser encontrados abaixo.
Prefixo | Namespace |
---|---|
s11 | http://schemas.xmlsoap.org/soap/envelope |
s12 | http://www.w3.org/2003/05/soap-envelope |
wsaAugust2004 | http://schemas.xmlsoap.org/ws/2004/08/addressing |
wsa10 | http://www.w3.org/2005/08/addressing |
sm | http://schemas.microsoft.com/serviceModel/2004/05/xpathfunctions |
tempuri | http://tempuri.org |
ser | http://schemas.microsoft.com/2003/10/Serialization |
Quando você souber que usará um namespace específico em suas consultas XPath, poderá adicioná-lo à tabela de namespace junto com um prefixo de namespace exclusivo e usar o prefixo em qualquer consulta XPath em vez do namespace completo. O exemplo a seguir define um prefixo "personalizado" para o namespace "http://my.custom.namespace"
, que é usado na consulta XPath contida em filterData.
<namespaceTable>
<add prefix="custom" namespace="http://my.custom.namespace/"/>
</namespaceTable>
<filters>
<filter name="XPathFilter" filterType="XPath" filterData="/s12:Envelope/s12:Header/custom:RoundingCalculator = 1"/>
</filters>
Filtrar tabelas
Embora cada elemento de filtro defina uma comparação lógica que pode ser aplicada a uma mensagem, a tabela de filtro fornece a associação entre o elemento de filtro e o ponto de extremidade do cliente de destino. Uma tabela de filtro é uma coleção nomeada de objetos FilterTableEntryElement que definem a associação entre um filtro, um ponto de extremidade de destino primário e uma lista de pontos de extremidade de backup alternativos. As entradas da tabela de filtro também permitem que você especifique uma prioridade opcional para cada condição de filtro. O exemplo a seguir define dois filtros e uma tabela de filtro que associa cada filtro a um ponto de extremidade de destino.
<routing>
<filters>
<filter name="AddAction" filterType="Action" filterData="Add" />
<filter name="SubtractAction" filterType="Action" filterData="Subtract" />
</filters>
<filterTables>
<table name="routingTable1">
<filters>
<add filterName="AddAction" endpointName="Addition" />
<add filterName="SubtractAction" endpointName="Subtraction" />
</filters>
</table>
</filterTables>
</routing>
Prioridade de avaliação de filtro
Por padrão, todas as entradas na tabela de filtro são avaliadas simultaneamente e a mensagem que está sendo avaliada é roteada para os pontos de extremidade associados a cada entrada de filtro correspondente. Se vários filtros forem avaliados como true
e a mensagem for unidirecional ou duplex, a mensagem será multicast para os pontos de extremidade em todos os filtros correspondentes. As mensagens de solicitação-resposta não podem ser multicast, pois apenas uma resposta pode ser retornada ao cliente.
A lógica de roteamento mais complexa pode ser implementada especificando níveis de prioridade para cada filtro; O Serviço de Roteamento avalia todos os filtros, começando pelo nível de prioridade mais alto. Se uma mensagem corresponder a um filtro desse nível, nenhum filtro de prioridade inferior será processado. Por exemplo, uma mensagem de entrada unidirecional é avaliada primeiro em relação a todos os filtros com prioridade 2. A mensagem não corresponde a nenhum filtro nesse nível de prioridade, portanto, a mensagem é comparada com filtros com prioridade 1. Dois filtros com prioridade 1 correspondem à mensagem e, como a mensagem é unidirecional, ela é roteada para ambos os pontos de extremidade de destino. Como uma correspondência foi encontrada entre os filtros de prioridade 1, nenhum filtro da prioridade 0 é avaliado.
Observação
Se nenhuma prioridade for especificada, a prioridade padrão 0 será usada.
O exemplo a seguir define uma tabela de filtro que especifica prioridades 2, 1 e 0 para os filtros referenciados na tabela.
<filterTables>
<filterTable name="filterTable1">
<add filterName="XPathFilter" endpointName="roundingCalcEndpoint"
priority="2"/>
<add filterName="EndpointNameFilter" endpointName="regularCalcEndpoint"
priority="1"/>
<add filterName="PrefixAddressFilter" endpointName="roundingCalcEndpoint"
priority="1"/>
<add filterName="MatchAllMessageFilter" endpointName="defaultCalcEndpoint"
priority="0"/>
</filterTable>
</filterTables>
No exemplo anterior, se uma mensagem corresponder ao XPathFilter, ela será roteada para o roundingCalcEndpoint e nenhum filtro adicional na tabela será avaliado, pois todos os outros filtros terão prioridade mais baixa. No entanto, se a mensagem não corresponder ao XPathFilter, ela será avaliada com base em todos os filtros da próxima prioridade mais baixa, EndpointNameFilter e PrefixAddressFilter.
Observação
Quando possível, use filtros exclusivos em vez de especificar uma prioridade porque a avaliação de prioridade pode resultar na degradação de desempenho.
Listas de backup
Cada filtro na tabela de filtros pode, opcionalmente, especificar uma lista de backup, que é uma coleção nomeada de pontos de extremidade (BackupEndpointCollection). Essa coleção contém uma lista ordenada de pontos de extremidade para os quais a mensagem será transmitida em caso de CommunicationException durante o envio para o ponto de extremidade primário especificado em EndpointName. O exemplo a seguir define uma lista de backup chamada "backupServiceEndpoints" que contém dois pontos de extremidade.
<filterTables>
<filterTable name="filterTable1">
<add filterName="MatchAllFilter1" endpointName="Destination" backupList="backupEndpointList"/>
</filterTable>
</filterTables>
<backupLists>
<backupList name="backupEndpointList">
<add endpointName="backupServiceQueue" />
<add endpointName="alternateServiceQueue" />
</backupList>
</backupLists>
No exemplo anterior, se um envio para o ponto de extremidade primário "Destino" falhar, o Serviço de Roteamento tentará enviar para cada ponto de extremidade na sequência que estão listados, primeiro enviando para backupServiceQueue e, posteriormente, para alternateServiceQueue se o envio para backupServiceQueue falhar. Se todos os pontos de extremidade de backup falharem, uma falha será retornada.