Introdução

Normalmente associamos as transformações de documentos aos mapas de BizTalk, mas a realidade é que existem dois tipos de transformações: as de estrutura (semântica) e as de representação (sintaxe). Estas últimas tipicamente ocorrem à entrada ou saída do BizTalk Server. Este artigo tem como objectivo ajudá-lo a compreender o processo de transformação de arquivos de texto (também chamados de Flat Files) num documento XML, bem como na validação da informação neles contida.

Este artigo pretende ser uma nota introdutória, destinado a quem está a dar os primeiros passos nesta tecnologia e tem como objectivo ajudá-lo a compreender o processo de transformação de um arquivos de texto (também chamados de Flat Files) num documento XML e no processo dessa transformação efectuar a validação da informação.

Um dos padrões mais antigos e comuns para a troca de mensagens é a utilização de arquivos texto (Flat Files) como: CSV (Comma Separated Values) ou TXT. Porém com a adopção do XML como formato de eleição na troca de mensagens, muitas vezes é necessário transformar arquivos texto em XML e vice-versa.

Embora ferramentas como Excel nos ajudem a interpretar um ficheiro destes, o processo é sempre interactivo e requer algumas dicas do utilizador para que o software consiga determinar onde separar os campos/colunas, bem como o tipo de dados de cada campo. Ora para um sistema de integração (Enterprise Application Integration) como o BizTalk Server, é preciso reduzir todas as ambiguidades, por forma a estas operações poderem ser efectuadas milhares de vezes com confiança e sem que seja necessário recorrer a um operador manual.

Mapa ou Schema Annotation?

Conforme referido na introdução, podemos caracterizar dois tipos de transformações existentes em BizTalk:
  • Transformações de Semântica: este tipo de transformações ocorre por norma nos mapas de BizTalk. Aqui o documento mantém a mesma sintaxe com que é representado (XML), mas muda a sua estrutura/forma/semântica. Tipicamente são operações One-way, uma vez que quando extraímos e agregamos partes de informação de um documento e compomos um outro documento diferente, podendo perder detalhes importantes para se conseguir fazer a transformação inversa de volta ao documento original.

  • Transformações de Sintaxe: é a transformação de um documento noutra representação, por exemplo de CSV para XML. Aqui o documento mantém os mesmos dados (semântica), mas muda a sintaxe com que é representado. Ou seja, traduzimos o documento mas não o modificamos em termos de estrutura. Por norma este tipo de transformação é bidireccional. Podemos aplicar a mesma lógica de transformação e voltar a obter um documento no seu formato original. Exemplos comuns destas transformações são também as conversões entre HL7 e XML, ou EDI e XML

Nota: Neste artigo vamos falar apenas nas transformações de sintaxe. Se procura saber mais sobre a transformação de semântica, pode consultar o artigos “BizTalk Server - Princípios Básicos dos Mapas”.

Como é que os arquivos de texto (Flat Files) são processados pelo BizTalk?

Internamente, o tipo de mensagem preferido do BizTalk é o XML. Se as mensagens estiverem no formato XML o BizTalk “oferece” inúmeros automatismos muito úteis nestes ambientes, como por exemplo: o encaminhamento da mensagem com base num determinado campo (propriedade promovida); tracking e análise multidimensional de valores e dimensões no BAM (Business Activity Monitoring); ou a tomada decisões lógicas dentro das orquestrações (processos de negócio) usando elementos da mensagem.

Felizmente, o BizTalk suporta a conversão de arquivos de texto para XML de uma forma bastante simples e intuitiva usando para isso “Flat File Schemas” que são simples esquemas (schemas) XSD com anotações específicas. À primeira vista, isso pode parecer estranho, porque os esquemas XSD’s são para descrever XML, no entanto o BizTalk usa-os como metadados para descrever não só os documentos XML mas também a representação em texto (Flat file). O truque é que todas as informações necessárias, como os símbolos delimitadores ou o tamanho do elemento num arquivo posicional, ou seja, as definição das regras de transformação (“parsing”), são embebidas em forma de anotações no schema XSD, simplificando logo toda a reutilização destes esquemas nos diferentes pontos do processo. Em qualquer ponto o documento poderá ser novamente traduzido para Flat File pois a definição é declarativa e simétrica.

Onde podem ocorrer as transformações de sintaxe?

Este tipo de transformações podem ocorrer nas pipelines de recepção e/ou de envio, geralmente os arquivos de texto (Flat Files) são processados em tempo de execução da seguinte forma:
  • Os Flat Files são recebidos por um adaptador (Pasta no File System por exemplo)
  • Uma pipeline aí configurada faz a transformação do Flat File no seu equivalente em XML;
  • Um ou mais interessados no documento, como por exemplo uma orquestração, irá subscrever este documento XML e esta mensagem irá percorrer o processo de negócio. Nota, num cenário de pure messaging poderemos nem ter orquestrações;
  • Se, e quando necessário, o BizTalk enviar as mensagens XML novamente como um documento de texto, é na porta de saída que o respectivo pipeline transformará desta vez no sentido inverso
Conforme a imagem a baixo demonstra:

 
As pipelines de recepção são compostas por 4 etapas, sendo que a transformação de sintaxe podem ocorrer em duas delas:
  • Decode Stage: Esta etapa é usada para descodificar (decode) ou decifrar (decrypt) a mensagem. Descodificação é o processo de transformar informação de um formato para outro. As transformações de sintaxe podem ocorrer nesta etapa através de um componente “custom.
  • Disassemble Stage: Esta etapa é usada para analisar (parse) e desmontar (disassemble) a mensagem. As transformações de sintaxe devem ocorrer nesta etapa. No exemplo que será demonstrado neste artigo, iremos utilizar o componente “Flat file disassembler” para transformar um documento de texto em XML.

  • Validate Stage: Esta etapa é usada para validar o formato da mensagem – efectua a validação de um documento XML com um respectivo XML schema (XSD).
  • Resolve Party Stage: Esta etapa é reservada para situações em que é preciso descobrir qual o originador/parceiro que nos enviou a mensagem. Por exemplo nos cenários de EDI, aqui estão os componentes que tratam das relações/acordos estabelecidos entre empresas (B2B).
No que diz respeito às pipelines de envio, elas são compostas por apenas 3 etapas, sendo que a transformação de sintaxe pode ocorrer em duas delas:
  • Pre-assemble Stage: Esta etapa é usada para realizar acções sobre a mensagem antes de a mensagem ser serializada.

  • Assemble Stage: É a operação inversa à etapa de Disassemble Stage na pipeline de recepção. É aqui que as transformações de sintaxe devem ocorrer.
  • Encode Stage: É a operação inversa à etapa de Decode Stage na pipeline de recepção. As transformações de sintaxe podem ocorrer nesta etapa através de um componente custom.

Ferramentas necessárias

Conforme mencionado anteriormente, para resolvermos este problema teremos de criar obrigatoriamente dois componentes:
  • Flat File Schema: que irá conter as definições das regras de transformação. Este tipo de artefacto pode ser criado manualmente ou a partir da ferramenta “BizTalk Flat File Schema Wizard”.
  • Pipeline Recepção/Envio: que será responsável por transformar o Flat File e representá-lo no seu equivalente em XML ou vice-versa. Este artefacto pode ser criado utilizando o Pipeline Designer.

Flat File Schema Wizard

BizTalk Flat File Schema Wizard” é uma ferramenta integrada no Visual Studio que permite ao programador facilmente e de forma visual efectuar transformação de arquivos de texto para documentos XML. Esta ferramenta suporta dois tipos de arquivos de texto:

  • Flat Files Posicionais:
    CABEÇALHOXXXXXXXXXXXXXXXXXXXX
    CORPOXXXXXXXXXXXXXXXXXXXXXXXX
    CORPOXXXXXXXXXXXXXXXXXXXXXXXX
    RODAPÉXXXXXXXXXXXXXXXXXXXXXXX

  • Ou delimitado por símbolos:
    1999990;1;P0110;1;1;20110307;
    1999990;2;P0529;2;2;20110307;
    1999990;3;P0530;3;3;20110307;


BizTalk Pipeline Designer

O editor de pipelines, BizTalk Pipeline Designer, possibilita criar e visualizar pipelines, mover os seus componente (Pipeline components) entre as diferentes etapas e configurar pipelines, as suas etapas e os seus componentes.

Este editor encontra-se integrado no Visual Studio e é composto essencialmente por 3 módulos:
  • Janela de Propriedades (properties window): nesta janela podemos ver e modificar as propriedades dos diferentes objectos da pipeline.
  • Janela de Ferramentas (toolbox window): Providencia acesso a todas as componentes (Pipeline components) que podemos utilizar nas pipelines.
  • Janela de desenho (design surface): que permite que o programador desenhe uma representação gráfica de uma pipeline, inserindo os componentes da janela de ferramentas nas diferentes etapas da pipeline.

Flat Files – Exemplo prático

Para este projecto iremos utilizar o BizTalk Server 2010 e o Visual Studio 2010, e explicar passo a passo o que é necessário desenvolver. Resumidamente estes serão os passos que teremos de efectuar:
  • Criação do exemplo (instância) de texto que servirá de teste ao projecto;
  • Criação do Schema para reconhecer o ficheiro de texto;
  • Criação da Pipeline para recepção e processamento do ficheiro de texto;
  • Publicar a solução no servidor BizTalk;
  • Configurar a aplicação BizTalk;
  • Executar a solução;
A solução deste exemplo, assim como todo o código pertencente, encontra-se disponível no MSDN Code Gallery: http://code.msdn.microsoft.com/BizTalk-Server-Transformar-0abe5767

Começaremos então por iniciar o Visual Studio 2010 e criar um novo projecto BizTalk:
  • File -> New  -> Project, em BizTalk Projects, seleccione a opção “Empty BizTalk Server Project”;
  • Coloque o nome do projecto, a localização física no disco e o nome da solução.


Criação de um ficheiro de texto para teste e validação

Antes de começarmos o nosso desenvolvimento teremos de criar uma instância, ou amostra, do ficheiro de texto que irá servir de modelo para a criação do Flat File Schema. Desta forma iremos configurar os seguintes requisitos, ao nível do file system, que irão ser necessários para a solução:

  • Criar uma pasta “<solução>\TESTFILES” onde vamos criar/colocar os artefactos que pretendemos transformar. Neste artigo vamos utilizar um ficheiro de texto delimitado por símbolos e que será composto por várias linhas com o seguinte conteúdo:
Sandro;Pereira;1978-04-04;Crestuma;4415 Crestuma
Lígia;Tavares;1982-01-21;Seixo-Alvo;451 Seixo-Alvo
José;Silva;1970-09-19;Crestuma;4415 Crestuma
Rui;Barbosa;1975-09-19;Lever;4415 Lever
Cada linha é composta pela seguinte estrutura: Nome, Apelido, Data Nascimento, Morada e Código Postal
Nota: O ficheiro “PESSOAS.txt” que vamos utilizar para testes encontra-se disponível na directoria “<solução>\TESTFILES”.
  • Vamos também criar duas pastas que iremos utilizar para o processo de conversão de dados.
    • Crie a pasta “<solução>\PORTS\IN” que irá servir como canal de entrada dos ficheiros Flat File para conversão ;
    • Crie a pasta “<solução>\PORTS\OUT” que irá servir como canal de saída dos ficheiros após terem sido convertidos.

Criação do Schema para reconhecer o ficheiro de texto

Para criarmos o Schema devemos aceder à solução criada no Visual Studio e efectuar os seguintes passos:

  • Pressione o botão direito em cima do projecto no Solution Explorer, seleccione a opção “Add -> New Item...”.
  • Na janela “Add New Item”, seleccionar o menu “Schema Files” nos templates, escolha a opção “Flat File Schema Wizard” e, em seguida, fornecer o nome que quer dar ao esquema, neste exemplo: “TXT_to_XML.xsd”

  • Ao seleccionar esta opção, automaticamente seremos guiados pela ferramenta “BizTalk Flat File Schema Wizard” que nos irá ajudar a criar um Flat File Schema e definir a sua estrutura de dados (records, elementos, atributos,…) com base no ficheiro de texto especificado. Seleccione a opção “Next” para continuar.

  • Na janela “Flat File Schema Information” iremos necessitar de:
    • Seleccionar uma instância do ficheiro de texto que queremos transformar
    • Apesar de não ser necessário, é boa prática renomear o Record name Root”. Neste caso vamos renomeá-lo para “Pessoas”.
    • E por último, atribuir um “Target namespace” ao esquema e definir o encoding do ficheiro de entrada

  • O wizard irá carregar o ficheiro de texto de exemplo para começa-lo a dividir e mapeá-lo na estrutura pretendida. É nesta etapa que necessitamos de definir como os registos ou as linhas são diferenciados. A estrutura do exemplo é:
                            Nome;Apelido; Data Nascimento;Morada;Codigo Postal{CR}{LF}
    Uma vez que cada registo (record) que quero criar “Pessoa” se encontra definido e contido numa linha, na janela “Select Document Data” iremos seleccionar toda a porção de dados no documento que irá definir o registo (record) o que nesta fase é toda a primeira linha.

  • Na janela “Select Record Format” iremos definir se estamos a lidar com um Flat File delimitado por símbolos ou se é posicional, no nosso caso iremos seleccionar a opção “By delimiter symbol” que é delimitado por um retorno Carriage Return/Line Feed.

  • Na janela “Delimited Record” iremos providenciar o delimitador do record, neste caso como queremos definir a estrutura de Pessoa, ou seja cada linha é uma Pessoa, o nosso limitador é {CR}{LF} (Carriage Return/Line Feed)

  • Na janela “Child Elements” iremos definir que tipo de elemento pretendemos atribuir ao registo. Como estamos a definir a estrutura Pessoa e o ficheiro contém várias pessoas, teremos de seleccionar o “Element Type" como “Repeating record”. Se não efectuarmos este passo, não teremos a capacidade de dividir o record em vários elementos/atributos individuais.

  • Nesta fase criamos com sucesso o record Pessoa, ou seja, acabamos de mapear que cada linha do ficheiro de texto corresponde a um elemento Pessoa. Na janela “Schema View” seleccione a opção “Next” para continuar a transformação da mensagem

  • Nesta fase o wizard irá reiniciar todo o processo descrito anteriormente, mas se repararem, já não selecciona toda a informação contida no ficheiro de texto, mas apenas o que foi seleccionado para definir o record Pessoa. O que iremos fazer agora é dividir a informação do record “Pessoa” em diferentes elementos, para isso seleccionamos apenas a informação pretendida deixando de fora o Carriage Return/Line Feed.

  • Mais uma vez a nossa estrutura é delimitada por símbolos (;), logo iremos seleccionar a opção “By delimiter symbol

  • Como podemos analisar, todos os elementos encontram-se separados pelo carácter ponto e vírgula (;) que é o nosso delimitador, logo na janela “Delimited Record” na opção “Child delimiter” temos de alterar o valor para “;”.

  • Nesta janela, iremos definir os diferentes elementos/atributos da estrutura do record “Pessoa”. Esta operação é muito parecida com qualquer XSD, onde podemos definir os nomes e os diferentes tipos de dados. Ajuste os valores de acordo com a imagem:

  • Por fim o wizard vai mostra-lhe a estrutura que o seu ficheiro de texto irá ter no seu equivalente documento XML. Assim que seleccionar a opção “Finish”, o esquema estará disponível para você utilizar na sua solução BizTalk.


Após finalizarmos a criação do Flat File Schema que irá conter as regras de transformação do ficheiro de texto, podemos facilmente testar a nossa transformação, sem ter de sair da nossa ferramenta de desenvolvimento (Visual Studio) e sem ter de publicar a nossa solução.

Se seleccionarem o Flat File Schema que acabamos de criar e acedermos às suas propriedades, verificamos que por omissão temos todas as propriedades pré-configuradas para efectuarmos testes à nossa transformação: a instância de entrada do esquema encontra-se configurada com o ficheiro que serviu de base à criação do esquema; assim como os formatos de entrada e saída.

 
Para testarmos basta seleccionar o esquema e com o botão direito do rato seleccionar a opção “Validate Instance”:

 
Esta opção vai usar o ficheiro configurado e validar todas as regras de transformação definidas, apresentando posteriormente o resultado final ou os erros ocorridos:


Criação da Pipeline para recepção do ficheiro de texto

Para criarmos A pipeline de recepção devemos aceder à solução criada no Visual Studio e efectuar os seguintes passos:
  • Pressione o botão direito em cima do projecto no Solution Explorer, seleccione a opção “Add -> New Item...”.
  • Na janela “Add New Item”, seleccionar o menu “Pipeline Files” nos templates, escolha a opção “Receive Pipeline” e, em seguida, forneça o nome que quer dar à pipeline, neste exemplo: “ReceivePipelineCustomPessoas.btp”

  • Ao seleccionar a opção “Add” irá aparecer o editor de pipelines, BizTalk Pipeline Designer, que irá permitir visualizar todas as etapas associadas à pipeline de recepção: Decode, Disassemble, Validate e ResolveParty. Neste caso, a Pipeline de que iremos criar, será responsável por receber um ficheiro de texto através de uma porta e convertê-lo para XML. Para isso, iremos utilizar o componente “Flat File Disassembler” que está disponível na Toobox à esquerda do Visual Studio. Arraste-o para dentro da Pipeline na etapa “Disassemble”.

  • Para terminar, seleccione o componente "Flat file disassembler", aceda às suas propriedades e na opção “Document Schema” seleccione o schema criado anteriormente, no caso o “TXT_to_XML”.


Nota: Caso pretenda criar uma pipeline de envio por forma a transformando um documento XML em Flat File, teríamos de seguir os mesmo passos, a diferença é que teríamos de arrastar o componente “Flat File Assembler” na etapa “Assemble

Publicar a solução para o servidor BizTalk

Todos os artefactos criados até o momento devem ser instalados no BizTalk Server 2010. No entanto antes de efectuarmos a publicação da solução existem algumas configurações que necessitamos de fazer/garantir:

  • Antes de publicarmos a solução do Visual Studio para uma aplicação BizTalk é necessário que todas as assemblies do projecto estejam assinadas com uma strong name key, uma vez que as mesmas terão de ser instaladas na global assembly cache (GAC). Para isso necessitamos:
    • No Visual Studio Solution Explorer, right-click sobre o nome do projecto e seleccione a opção “Properties
    • Seleccione a tab Signing e escolha a opção “New” na drop down box Choose a strong name key file

  • Atribua um nome, por exemplo “TXTtoXML.snk”

  • Da mesma forma, antes de publicarmos a solução do Visual Studio para uma aplicação BizTalk, necessitamos primeiro definir as propriedades associadas com a publicação para o BizTalk, especialmente as propriedades do “BizTalk Group”. Se a solução no Visual Studio contiver vários projectos, teremos de configurar as propriedades separadamente para cada projecto.
    • No Visual Studio Solution Explorer, right-click sobre o nome do projecto e seleccione a opção “Properties
    • Seleccione a tab Deployment e configure o nome que queremos atribuir à aplicação BizTalk na propriedade “Application Name”: “TransfFlatFilesEmXML Demo”. As restantes propriedades poderão ficar com os valores default.

Por fim podemos efectuar o Build e o Deploy do projecto por forma a este ser publicado numa aplicação BizTalk:


No entanto para podermos publicar uma solução no BizTalk, o utilizador terá de ser membro do grupo “BizTalk Server Administrators”. Se, nas propriedades de “Deployment”, a opção “Install to Global Assembly Cache“ estiver activa, então também necessitará de permissões de leitura/escrita na GAC.

Configurar a aplicação BizTalk

Este é a última etapa deste processo. Por forma a podermos testar a solução que tivemos a desenvolver no servidor BizTalk, necessitamos de configurar a aplicação que foi criada na publicação.

Para isso teremos aceder à consola “BizTalk Server Administration” para criar e configurar:
  • Uma porta de entrada para os ficheiros Flat File;
  • Uma porta de saída para guardar os ficheiros transformados no formato XML.
Abra o “BizTalk Server Administration” através do menu Iniciar, Programas, Microsoft BizTalk Server 2010 e procure no menu “Applications” a aplicação chamada “TransfFlatFilesEmXML Demo”.

  • Pressione com botão direito em cima de “Receive Port” e seleccione a opção “New” e “One-Way Receive Port...”;
  • Aparecerá uma nova janela para definição das propriedades da porta:
    • Na tab “General” defina o nome da porta de recepção: “ReceiveTXT”.

  • Na tab “Receive Locations”, seleccione “New” e defina o nome como “ReceiveTXT_to_XML”, seleccione a opção “Type” como FILE e seleccione na drop down box da opção “Receive pipeline” a pipeline que criamos anteriormente: “ReceivePipelineCustomPessoas”;

  • Na mesma tab seleccione o botão “Configure”. Na janela “FILE Transport Properties” configure a opção “Receive Folder”, associando a pasta criada anteriormente “<solução>\PORTS\IN”. No campo “File Mask” coloque “*.txt” para definirmos que só será lido pelo BizTalk arquivos com a extensão “.txt”. Por fim seleccione o botão “Ok”.

  • Para terminar o processo de criação da porta de recepção pressione em “Ok”.
Os passos em cima referidos, foram necessários para criarmos uma Receive Port e uma Receive Location. Agora iremos criar uma Send Port para enviar os dados uma vez transformados pelo BizTalk:
  • Pressione com o botão direito em “Send Ports”, seleccione “New”, e em “Static One-way Send Port...
  • De seguida será apresentada uma nova janela:
    • Na tab “General” defina o nome da “Send Port” como “SaveXMLFile”.
    • Na opção “Type” seleccione a opção FILE;
    • Na opção “Send Pipeline” defina a pipeline XMLTransmit. Esta é uma pipeline nativa que é usada para o processamento de uma mensagens XML.

  • Na mesma tab seleccione o botão “Configure”. Na janela “FILE Transport Properties” configure a opção “Destination Folder”, associando a pasta criada anteriormente “<solução>\PORTS\OUT”. No campo “File name” coloque a seguinte informação: “%MessageID%.xml”, esta tag especial irá definir que o nome de cada arquivo escrito será um identificador único da mensagem dado pelo BizTalk. Por fim seleccione o botão “Ok” para voltar à janela anterior

  • Para o destino (Send Port) subscrever todos os ficheiros, vamos colocar um filtro na tab “Filters” com a seguinte expressão: “BTS.ReceivePortName == ReceiveTXT”.
  • Nota: Esta configuração irá forçar que cada mensagem que aparecer na MessageBox que tenha entrado pela Receive Port com o nome ReceiveTXT será encaminhada para a Send Port que estamos a acabar de criar.

  • Pressione em “Ok” para terminar a configuração da Send Port.
Por fim, apenas nos falta iniciar a nossa aplicação. Para isso pressione com o botão direito no nome da aplicação “TransfFlatFilesEmXML Demo” e seleccione a opção “Start…”.


Testar a solução

Para testarmos a aplicação do BizTalk apenas temos de copiar um ficheiro Flat File para a directoria que se encontra configurado na porta de recepção: “<solução>\PORTS\IN”. O resultado deverá aparecer na forma de um documento XML na pasta configurada na porta de saída: “<solução>\PORTS\OUT”.

Nota: O ficheiro desaparece automaticamente, pelo que deve evitar fazer drag&drop (move) com os ficheiros de teste sob o risco de não o voltar a poder usar.

Conclusão

Conforme apresentado neste artigo, o BizTalk Server ajuda-nos a resolver muitos destes problemas de transformação de mensagens, de Semântica ou de Sintaxe, apenas com funcionalidades “out of the box” com o produto, em poucos passos e sem nenhum tipo de programação ou desenvolvimento de código.

O facto das definições das regras de “parsing” ficarem embebidas nos schemas XSD, simplifica logo toda a reutilização destes esquemas nos diferentes pontos do processo. Em qualquer ponto o documento poderá ser novamente traduzido para Flat File pois a definição é declarativa e simétrica, ao contrário do que poderia acontecer com por exemplo na programação “normal” C# onde teríamos de criar dois componentes para traduzir de texto para XML e vice-versa. Este modelo usado para os schemas do BizTalk acaba por centralizar todas as definições da mensagem num único artefacto, simplificando a manutenção e evolução da especificação, simplificando futuras reutilizações e gestão de dependências. Quando configuramos um projecto deste tipo, é exactamente este tipo de garantias que nos mantêm os sistemas a funcionar correctamente por muitos anos, ao mesmo tempo que facilitamos a vida a quem um dia tiver de corrigir e/ou evoluir algum destes processos.

Código Fonte

O código fonte de suporte para a elaboração deste artigo encontra-se disponível para download no MSDN Code Gallery: BizTalk Server - Transformar arquivos de texto (Flat Files) em XML

Autor

Sandro Pereira
DevScope | MVP & MCTS BizTalk Server 2010
http://sandroaspbiztalkblog.wordpress.com/ | @sandro_asp

Outros Idiomas

Este artigo também está disponível nos seguintes idiomas:

Ver Também

Tópicos relacionados sugeridos: