Filtragem

O sistema de filtragem do WCF (Windows Communication Foundation) pode usar filtros declarativos para fazer a correspondência de mensagens e tomar decisões operacionais. Você pode usar filtros para determinar o que fazer com uma mensagem examinando uma parte dela. Um processo de enfileiramento, por exemplo, pode usar uma consulta XPath 1.0 para verificar o elemento de prioridade de um cabeçalho conhecido a fim de determinar se uma mensagem deve ser movida para a frente da fila.

O sistema de filtragem é composto por um conjunto de classes que pode determinar com eficiência quais de um conjunto de filtros são true para uma mensagem WCF específica.

O sistema de filtragem é um componente principal do sistema de mensagens do WCF. Ele foi projetado para ser extremamente rápido. Cada implementação de filtro foi otimizada para um tipo específico de correspondência com mensagens WCF.

O sistema de filtragem não é thread-safe. O aplicativo precisa processar a semântica de bloqueio. No entanto, ele dá suporte a um gravador único de vários leitores.

Em que ponto a filtragem entra

A filtragem é executada depois que uma mensagem é recebida e faz parte do processo de expedição da mensagem para o componente de aplicativo adequado. O design do sistema de filtragem atende aos requisitos de vários subsistemas do WCF, incluindo mensagens, roteamento, segurança, tratamento de eventos e gerenciamento do sistema.

Filtros

O mecanismo de filtro tem dois componentes principais: filtros e tabelas de filtro. Um filtro toma decisões boolianas sobre uma mensagem com base nas condições lógicas especificadas pelo usuário. Os filtros implementam a classe MessageFilter.

Os métodos Match são usados para determinar se uma mensagem satisfaz um filtro. Um dos métodos testa o cabeçalho da mensagem, mas não pode inspecionar o corpo da mensagem. O outro método usa um buffer de mensagens como um parâmetro de entrada e pode inspecionar o corpo da mensagem.

Em geral, os filtros não são testados individualmente, mas como parte de uma tabela de filtro, que é uma classe genérica criada pelo método CreateFilterTable.

Os vários tipos de filtros são especializados na correspondência de um tipo específico de condição booliana. Depois de construir um filtro, você não poderá alterar os critérios usados por um filtro. Para modificar os critérios de um filtro, construa um novo e exclua o filtro existente.

Filtros de ação

O ActionMessageFilter contém uma lista de cadeias de caracteres de ação. Se uma das ações na lista do filtro corresponder ao cabeçalho Action na mensagem ou no buffer de mensagens, o método Match retornará true. Se a lista estiver vazia, o filtro será considerado um filtro de correspondência de tudo e qualquer mensagem ou buffer de mensagens será correspondente e Match retornará true. Se nenhuma das ações na lista do filtro corresponder ao cabeçalho Action na mensagem ou no buffer de mensagens, Match retornará false. Se não houver nenhuma ação na mensagem e a lista do filtro não estiver vazia, Match retornará false.

Filtros de endereço do ponto de extremidade

O EndpointAddressMessageFilter filtra as mensagens e os buffers de mensagens com base em um endereço de ponto de extremidade, conforme representado na coleção de cabeçalhos. Para que uma mensagem passe por esse filtro, as seguintes condições precisam ser atendidas:

  • O URI (Uniform Resource Identifier) do endereço do filtro precisa ser o mesmo que aquele no cabeçalho da mensagem Para.

  • Cada parâmetro de ponto de extremidade no endereço do filtro (coleção address.Headers) precisa encontrar um cabeçalho na mensagem para mapeamento. Os cabeçalhos extras na mensagem ou no buffer de mensagens são aceitáveis para que a correspondência permaneça true.

Filtros de endereço do ponto de extremidade de prefixo

  1. As funções PrefixEndpointAddressMessageFilter são semelhantes ao filtro EndpointAddressMessageFilter, com a exceção de que a correspondência pode estar em um prefixo do URI da mensagem. Por exemplo, um filtro que especifica o endereço http://www.adatum.com corresponde às mensagens endereçadas a http://www.adatum.com/userA.

Filtros de mensagem XPath

Um XPathMessageFilter usa uma expressão XPath para determinar se um documento XML contém elementos específicos, atributos, texto ou outras construções sintáticas XML. O filtro é otimizado para ser extremamente eficiente para um subconjunto estrito de XPath. A XML Path Language é descrita na especificação W3C do XML Path Language 1.0.

Normalmente, um aplicativo usa um XPathMessageFilter em um ponto de extremidade para consultar o conteúdo de uma mensagem SOAP e executa a ação apropriada com base nos resultados dessa consulta. Um processo de enfileiramento, por exemplo, pode usar uma consulta XPath para inspecionar o elemento de prioridade de um cabeçalho conhecido para decidir se uma mensagem deve ser movida para a frente da fila.

Tabelas de filtro

As tabelas de filtro são usadas para armazenar pares chave-valor, em que um filtro é a chave e alguns dados associados são o valor. Os dados de filtro podem ser usados para indicar as ações a serem tomadas se uma mensagem corresponder ao filtro e o tipo de dados de filtro for o parâmetro genérico para a classe de tabela de filtro. Os dados de filtro podem consistir em regras de roteamento, estado de segurança de sessão, ouvintes em um canal etc. Os dados podem ser usados quando o controle de fluxo de dados é necessário.

As tabelas de filtro implementam a interface IMessageFilterTable<TFilterData>genérica.

As tabelas de filtro têm vários métodos que correspondem a uma mensagem com todos os filtros na tabela e retornam uma coleção não ordenada de filtros ou dados correspondentes. Alguns dos métodos de correspondência são de correspondência múltipla e retornam todos os itens correspondentes. Outros são de correspondência única, retornando apenas um item e geram uma MultipleFilterMatchesException se mais de um filtro é correspondente.

Tabela de filtro de mensagem

A MessageFilterTable<TFilterData> é a implementação mais geral de IMessageFilterTable<TFilterData>. Você pode armazenar filtros de todos os tipos na tabela.

É possível atribuir prioridades numéricas a filtros, em que a prioridade mais alta é indicada pelo número mais alto. Vários tipos de filtros podem ter a mesma prioridade. Um tipo específico de filtro pode aparecer em mais de um nível de prioridade.

A correspondência é feita a partir da prioridade mais alta e, depois que os filtros correspondentes são encontrados com determinada prioridade, nenhum filtro com prioridades mais baixas é examinado. Portanto, se você estiver usando um método de correspondência de filtro único e mais de um filtro corresponder a uma mensagem, mas cada filtro correspondente tiver uma prioridade diferente, nenhuma exceção será gerada e o filtro com a prioridade mais alta será retornado. Da mesma forma, um método de correspondência de vários filtros só retorna os filtros correspondentes com a prioridade mais alta.

Tabela de filtro de mensagem XPath

O XPathMessageFilterTable<TFilterData> é otimizado para filtros XPath declarativos, ou seja, a chave da tabela é um XPathMessageFilter.

A classe XPathMessageFilterTable<TFilterData> otimiza a correspondência para um subconjunto de XPath que abrange a maioria dos cenários de mensagens e dá suporte à gramática completa do XPath 1.0. Ela tem algoritmos otimizados para a correspondência paralela eficiente.

Esta tabela contém vários métodos Match especializados que operam em um XPathNavigator e em um SeekableXPathNavigator. Um SeekableXPathNavigator estende a classe XPathNavigator adicionando uma propriedade CurrentPosition. Essa propriedade permite que as posições no documento XML sejam salvas e carregadas rapidamente sem a necessidade de clonar o navegador, uma alocação de memória cara que o XPathNavigator precisa para essa operação. O mecanismo XPath do WCF precisa registrar com frequência a posição do cursor durante a execução de consultas em documentos XML, ou seja, o SeekableXPathNavigator fornece uma otimização importante para o processamento de mensagens.

Cenários de clientes

Você poderá usar a filtragem sempre que quiser enviar uma mensagem para diferentes módulos de processamento, dependendo dos dados contidos na mensagem. Dois cenários típicos são encaminhar uma mensagem com base no código de ação e desfazer a multiplexação de um fluxo de mensagens com base no endereço do ponto de extremidade das mensagens.

Roteamento

O ouvinte de um ponto de extremidade escuta mensagens que têm um ou mais códigos de ação no cabeçalho SOAP da mensagem. Implemente isso criando um ActionMessageFilter pela transmissão de uma matriz que contenha os códigos de ação para o construtor. Ele usa esse filtro para se registrar no ListenerFactory, ou seja, somente as mensagens cuja ação corresponde a uma daquelas no filtro chega a esse ponto de extremidade específico.

Desfazer a multiplexação

Quando é feito o fan-out de vários pontos de extremidade do mesmo ServiceListener, a única maneira de desfazer a multiplexação de mensagens e saber se elas pertencem a determinado endereço de ponto de extremidade é usar EndpointAddressMessageFilters, que selecionam mensagens em direção aos pontos de extremidade registrados executando uma pesquisa nas informações armazenadas nos cabeçalhos. Nesses filtros, somente as mensagens aprovadas têm todos os cabeçalhos necessários que correspondem ao:

  • URI no EndpointAddress.

  • Restante dos parâmetros de ponto de extremidade no EndpointAddress, conforme especificado no EndpointAddressMessageFilter.

Confira também