Mova seu aplicativo Java para uma nuvem híbrida usando o Bluemix – Parte 01

julho 5, 2016 5:00 pm Publicado por Deixe um comentário

Você está interessado em executar aplicativos Java “na nuvem?” Mas, considerando as realidades de um aplicativo corporativo, você nem sabe por onde começar? Nesta série, discutiremos diferentes opções para definir um aplicativo híbrido em camadas, percorrendo vários exemplos passo a passo. Explicaremos como migrar partes de um aplicativo Java e ainda conectar os melhores componentes existentes na empresa. Além disso, discutiremos as diferentes opções para o Java Runtime, os serviços e o conjunto de ferramentas.

Esta série é focada no aplicativo Java, nos serviços que ele usa e em como é possível mover o aplicativo Java e a camada do banco de dados relacional para uma plataforma baseada no Cloud Foundry. Também cobriremos os cenários nos quais os serviços são deixados no local, além das mudanças que podem ser necessárias no aplicativo para gerenciamento de sessões, dimensionamento e criação de log, ao passar para a nuvem.

Aplicativo Java

Ao avaliar um aplicativo para migrar para a nuvem, o ponto de início natural é o próprio aplicativo. Durante esse processo, será necessário entender o seguinte:

  • Quais recursos Java o aplicativo usa?
  • Quais serviços e dependências externas ele requer?
  • O aplicativo está pronto para a nuvem?
  • Qual o investimento que você pretende fazer para atualizar o aplicativo para nuvem?
  • Qual o investimento que você pretende fazer para atualizar os procedimentos administrativos?

Os aplicativos de servlet e JSP simples, no estilo Tomcat, geralmente são fáceis de migrar para a nuvem, e é possível escolher entre diferentes opções de tempo de execução e serviço. No entanto, até mesmo para os aplicativos simples, é necessário considerar como manipular esses tipos de serviços como bancos de dados e, caso haja necessidade de dimensionamento, como manipular a afinidade de sessão. Nosso primeiro exemplo é uma migração passo a passo de um aplicativo Tomcat, incluindo o banco de dados. Em seguida, examinaremos o problema de executar os processos do trabalhador Java na nuvem. Nos próximos tutoriais, examinaremos os problemas de dimensionamento e afinidade de sessão na nuvem.

Caso o aplicativo use recursos como Remote EJB, processamento Two-phase commit e outros recursos mais avançados, as opções de migração serão mais restritas (ou mais caras). Discutiremos as diferentes opções disponíveis para aplicativos com esse cenário.

Caso você não tenha certeza sobre o que exatamente seu aplicativo usa e precisa, as orientações passo a passo passarão por uma ferramenta de migração para analisar isso (essa ferramenta é recomendada mesmo que você pense que saiba!).

Esse primeiro tutorial na série explica como migrar um aplicativo Java de exemplo para a nuvem e conectar a um banco de dados SQL baseado em nuvem.

Java Runtime

Existem várias opções para executar um aplicativo Java na nuvem. Uma opção é usar um Java Runtime fornecido pela plataforma como serviço (PaaS), como o Liberty for Java Runtime no IBM Bluemix™. Esse é um caminho fácil, pois você lida somente com o próprio aplicativo. Com essa opção, você somente implementa o aplicativo, sem precisar instalar ou manter o Java Runtime. O IBM Bluemix suporta o buildpack Liberty for Java, que inclui o Java EE 7 e o perfil Liberty. O buildpack Java do Cloud Foundry, que inclui o Tomcat 8.0.21, também está disponível no Bluemix. Este artigo inclui orientações passo a passo usando ambos os buildpacks.

Caso deseje mais controle sobre o Java Runtime, ou caso o aplicativo precise de recursos que não sejam suportados atualmente pelo tempo de execução Liberty for Java Bluemix, será possível selecionar entre diferentes opções de infraestrutura como serviço, para controlar e gerenciar a versão da linguagem Java instalada. No IBM Bluemix, é possível escolher um contêiner do Docker ou uma máquina virtual para o Java Runtime. Essas abordagens fornecem mais controle sobre o tempo de execução e as versões. No entanto, esse controle dá um pouco mais de trabalho na instalação e no gerenciamento.

Para obter mais informações sobre os três tempos de execução e seus recursos exclusivos, consulte “Bluemix Instant Runtimes, Containers, or Virtual Machines.”

Serviços

Além do tempo de execução, outras decisões importantes a serem consideradas incluem a manipulação de dependências externas como banco de dados, sistemas de mensagens e gerenciadores de identidade LDAP. É possível escolher o uso de recursos em nuvem para essas dependências (por exemplo, usar um banco de dados como serviço na nuvem, como o SQL Database no IBM Bluemix), ou escolher manter os recursos externos no local e conectar a partir do aplicativo às mesmas dependências usadas hoje com o Serviço de gateway seguro. Esta série inclui orientações passo a passo para ambas as alternativas.

Consideração sobre o aplicativo em nuvem

Conforme um aplicativo é passado para a nuvem, também é necessário entender se seu design está, pelo menos, “pronto para nuvem”, caso não seja centrado em nuvem. A ferramenta de migração que discutimos verifica potenciais áreas problemáticas ao migrar para a nuvem, incluindo gerenciamento e criação de log de estado, além de outros itens comuns que devem ser considerados. No nosso exemplo, percorreremos o cenário de migração do nosso aplicativo, que usa uma sessão HTTP. No entanto, não nos aprofundaremos muito na questão do design para a nuvem e recomendamos que você também consulte artigos de melhores práticas dedicados a esse assunto, como o “Top 9 rules for Cloud Applications” e o 12-factor apps in plain English.

Conjunto de ferramentas

O IBM Bluemix suporta a implementação de aplicativos usando o Cloud Foundry, o Docker e máquinas virtuais, portanto, independentemente de como estiver implementando o aplicativo Java ou do caminho do tempo de execução de implementação selecionado, será possível enviar o aplicativo para a nuvem programaticamente. Nosso primeiro exemplo usa a linha de comandos do Cloud Foundry.

No caso do Eclipse, há inúmeros plug-ins para ajudar a migrar e implementar aplicativos no Bluemix. O plug-in do kit de ferramentas de migração analisa a origem do aplicativo e fornece um relatório e sugestões de migração para o Bluemix. Também existe um plug-in para implementar no Bluemix. Depois do primeiro exemplo, que somente usa a linha de comandos, todo o trabalho é realizado no Eclipse, desde a importação e a análise do aplicativo até as mudanças e a implementação. Embora o Eclipse não seja necessário, é recomendado usá-lo para trabalhar com o aplicativo Java.

Migrando um aplicativo Tomcat para os Bluemix Java Runtimes

Vamos começar!

Estamos usando um aplicativo de amostra, o RedbookLibrary, que é executado no Tomcat. Esse aplicativo provém do WebSphere Application Server v8.5 Migration Guide, no qual as considerações envolvidas na migração do WebSphere Full Profile, Tomcat, JBOSS ou WebLogic para o perfil Liberty são cobertas em detalhes. Fizemos algumas modificações nas práticas de acesso ao banco de dados da versão do Redbook e definimos o uso de um banco de dados Apache Derby local, portanto, assegure-se de usar a versão do aplicativo que pertence a este artigo.

Após uma configuração inicial, começamos a executar o conjunto de ferramentas de análise de migração. Em seguida, migramos o aplicativo para o Liberty for Java Runtime no Bluemix, usando o serviço do SQL Database no Bluemix para o banco de dados, conforme é mostrado na figura a seguir:

image001_new

O que será necessário para desenvolver o aplicativo

execute o app

obtenha o código

Etapa 1. Fazer download do aplicativo

Durante esta série, fornecemos aplicativos de amostra para usar, e recomendamos que eles sejam usados para obter um melhor acompanhamento das etapas e do conjunto de ferramentas. Posteriormente, será possível seguir essas mesmas etapas para seu próprio aplicativo.

  1. O código do aplicativo Tomcat de amostra, o código RedbookLibrary (com nossos aprimoramentos), está disponível como um repositório do GitHub.
  2. Na linha de comandos, execute uma clonagem Git desse repositório. Trabalharemos no diretório que é criado: git clone https://github.com/kgb1001001/RedbookLibrary.

Etapa 2. Instalar o conjunto de ferramentas da API do Cloud Foundry

O IBM Bluemix suporta a API do Cloud Foundry. Portanto, a maneira de desenvolver o aplicativo Java é totalmente flexível. Neste artigo, mostramos como usar a linha de comandos.

Para aqueles que já usam o Eclipse ou que estão buscando uma experiência de IDE mais integrada, a Parte 2 descreverá como usar o Eclipse e abordará o plug-in Liberty for Java Bluemix Migration e o plug-in de implementação do Bluemix.

  1. Faça download e instale a Interface da linha de comandos do Cloud Foundry no website do GitHub.

Etapa 3. Instalar e executar o conjunto de ferramentas de análise de migração da linha de comandos

A IBM fornece ferramentas de análise de migração para ajudar a determinar o grau de facilidade da passagem do aplicativo para o Bluemix. A primeira é uma ferramenta de avaliação binária, que executaremos aqui a partir da linha de comandos. A segunda ferramenta fornece uma análise mais detalhada, mas requer o código-fonte e o Eclipse. Ela será abordada na Parte 2.

  • Faça download da ferramenta de avaliação binária;
  • Instale a ferramenta inserindo java -jar binaryAppScannerInstaller.jar;
  • Depois que a ferramenta for instalada, acesse o subdiretório wamt;
  • Execute a análise a partir do subdiretório wamt inserindo:
    java -jar binaryAppScanner.jar directory-containing-war-file. O diretório será <git_clone_location>RedbookLibrary, como c:usersibm_adminRedbookLibrary.

image002

  • O comando anterior fornece os resultados da análise de tecnologia de alto nível (em HTML).

image003

  • Em seguida, é possível executar um relatório de análise detalhado em HTML, que destaca os problemas potenciais ao passar para a nuvem, arquivos e números de linha. Ele também inclui o material de referência para solucionar esses problemas. No subdiretório wamt, insira:
    java -jar binaryAppScanner.jar directory-containing-war-file –analyzeMigrationDetails –targetAppServer=bluemix

image004_new

Etapa 4. Analisar os resultados para escolher a topologia de implementação

A visualização prévia de tecnologia do scanner fornece informações de análise importantes para o aplicativo.

  1. No Relatório de avaliação de aplicativo (mostrado acima), em “Tecnologias do aplicativo da web”, vemos que esse aplicativo usa Servlet e JSP. Obviamente isso não é surpresa para um aplicativo Tomcat. Todas as tecnologias migrarão para o Liberty for Java no Bluemix, como é mostrado na coluna 1.
  2. Em “Especificações relacionadas ao Java EE no Java SE”, vemos que o aplicativo usa o Java Database Connectivity (JDBC). Esse aplicativo também será executado no Liberty for Java no IBM Bluemix. No entanto, essa análise de alto nível mostrando que o aplicativo usa JDBC indica que será necessário decidir como manipular o banco de dados.
  3. A análise detalhada fornece ainda mais informações (veja as próximas figuras). Na verdade, esse relatório pode assustar um pouco à primeira vista. Felizmente, a maioria das áreas sinalizadas são do banco de dados Derby local usado com o Tomcat e não se aplicam à passagem para a nuvem. É fácil ver as regras que estão sinalizadas a partir dos arquivos do Derby, consultando o Detalhe de nome do arquivo.
    image005 (1)
  4. Depois de eliminar os problemas provenientes dos arquivos com o Derby, as regras que precisam de atenção para a migração para nuvem são Capturar informações de log, Persistência de sessão HTTP e Usar serviço do SQL Database.
    image006_new
  5. Para o banco de dados, recomendamos usar o serviço do SQL Database no Bluemix (consulte a figura a seguir). Aqui na Parte 1, isso é exatamente o que faremos. Mostraremos como usar um banco de dados na nuvem, usando o serviço do SQL Database no Bluemix. Posteriormente na série, mostraremos como usar os recursos de Gateway seguro para conectar-se ao banco de dados existente.
    image007_new
  6. O relatório também sinaliza Capturar informações de log como algo a ser verificado para o aplicativo. Ao consultar a ajuda, vemos: “Os aplicativos podem registrar no System.err/System.out, para que o componente Loggregator do Cloud Foundry recupere as entradas de log. Usando o Loggregator, é possível acompanhar os logs do aplicativo e fazer dump de um conjunto recente de logs do aplicativo”.
    No nosso aplicativo, estamos usando o recurso de criação de log Java padrão e também registrando no local padrão, que é o System.out. Portanto, as entradas de log são recuperadas automaticamente pelo Loggregator.
    image008
  7. Finalmente, o relatório sinaliza a persistência de sessão na nuvem. Isso requer atenção, mas não aqui na Parte 1 onde não estamos lidando com armazenamento em cluster. Um tutorial posterior nesta série abordará o armazenamento em cache e o armazenamento em cluster de sessão.

Etapa 5. Criar o serviço de banco de dados

Estamos escolhendo usar um banco de dados na nuvem, portanto, será necessário criar o serviço de banco de dados a ser usado. Isso pode ser feito usando o painel do IBM Bluemix ou a linha de comandos. Continuaremos usando a linha de comandos neste artigo. Depois que o banco de dados for criado, implementaremos o aplicativo e ligaremos ao banco de dados. Mas antes de criar o banco de dados, é necessário discutir como o aplicativo será implementado e como ele usará o banco de dados.

Uma melhor prática no Cloud Foundry é usar o que é chamado de arquivo manifest.yml ao implementar aplicativos. Um arquivo manifest.yml é semelhante à ideia de um arquivo manifest em um arquivo Java JAR ou WAR. São as informações que ajudam o conjunto de ferramentas do Cloud Foundry a entender como o aplicativo é construído.

Os manifests são gravados em YAML. É necessário saber apenas sobre dois aspectos do YAML para ler esse arquivo:

  • As chaves são separadas dos valores por dois pontos e um espaço;
  • Um novo elemento em uma linha é indicado por um hífen e um espaço.

Vamos observar o arquivo manifest.yml que é fornecido com o aplicativo de amostra.

  1. No diretório RedbookLibrary, abra o arquivo manifest.yml:
    applications:
    - name: redbooklibrary
      memory: 512M
      path: RedbookLibrary.war
      host: redbook-library
      buildpack: liberty-for-java 
      services:
      - library_db
  2. O manifest informa que existe um único serviço nos serviços: lista, nomeado como library_db. Há duas etapas no Cloud Foundry para usar um serviço em um aplicativo: (1) criar uma instância do serviço (que ocorre uma única vez por espaço) e (2) ligar essa instância de serviço ao aplicativo (que deve ocorrer para cada aplicativo no espaço). Portanto, para esse aplicativo, é necessário criar um serviço que seja chamado “library_db.” Esse serviço pode ser criado usando a linha de comandos do Cloud Foundry. Na linha de comandos, digite: cf login.
  3. O serviço de banco de dados que usaremos será o sqldb. Criamos uma instância de serviço para usar o plano de avaliação grátis e nomeamos o serviço que o aplicativo precisa como “library_db.”
    cf create-service sqldb sqldb_free library_db
  4. Agora que o serviço está criado (mas ainda não vinculado), caso deseje, é possível consultar a GUI do Bluemix e validar se ele está disponível no seu espaço ou digitar cf services e validar se “library_db” está na lista dos serviços definidos para o seu espaço.

Etapa 6. Implementar o aplicativo na nuvem

O motivo pelo qual os manifests são importantes é que os elementos que acabamos de abordar são coisas que devem ser definidas por meio dos parâmetros da linha de comandos ou de outros comandos na ferramenta de linha de comandos do Cloud Foundry. Ao colocar todas essas informações no manifest, não será necessário gravar um comando longo, de formato integral, com todos os parâmetros para cf push sempre que implementar. Apenas será necessário colocar as informações no manifest.yml uma única vez e reutilizá-las para cada implementação.

Queremos que o aplicativo use o serviço library_db recém-criado no Bluemix, o que significa que ele precisa ser configurado de forma adequada. Um dos recursos interessantes do Liberty for Java Buildpack é que ele inclui recursos para configurar automaticamente os serviços de ligação. Isso facilita muito a passagem do aplicativo para o Liberty for Java Buildpack no Bluemix.

Estamos configurando o aplicativo intencionalmente para usufruir dos recursos de configuração automática. Uma das coisas que faz com que seja um desafio seguir alguns exemplos de Java gravados para o Bluemix é que muitos exemplos desviam das melhores práticas de codificação JEE e não usam a técnica automática. Eles se aproveitam do fato de que os programas no Bluemix podem receber informações de serviços (URLs, usuários e senhas) sobre serviços de ligação por meio de variáveis de ambiente VCAP_SERVICES que o Cloud Foundry passa para cada tempo de execução. Portanto, muitos programas Java contêm instruções IF que procuram essas variáveis de ambiente e, em seguida, a partir dos valores nessas variáveis, configuram os parâmetros apropriados para o código de chamada de serviço necessário (como drivers de banco de dados). No entanto, isso anula o propósito pelo qual o JEE foi projetado.

O JEE externaliza esse tipo de detalhe em um arquivo de configuração do servidor de aplicativos externo (como o arquivo server.xml que é usado no WebSphere Liberty Profile) de modo que o código do programa somente precise de uma referência abstrata ao serviço por meio de JNDI. Por exemplo, vamos considerar um servlet que deseja acessar a origem de dados JDBC. No JEE, isso geralmente é feito usando uma anotação de Recurso no formato: @Resource(name = “jdbc/library_db”)

Nas classes que não são objetos JEE (por exemplo, servlets ou EJBs), é possível usar consultas JNDI padrão para obter referências: (DataSource) ic.lookup(“java:comp/env/jdbc/library_db”);

Agora, quando isso tange o perfil Liberty é que o Liberty Profile Buildpack for Bluemix configura isso automaticamente gravando um arquivo server.xml para o servidor Liberty que é criado. Esse arquivo server.xml contém as sub-rotinas apropriadas para fazer a ligação, criando automaticamente uma ligação JNDI no formato: <type, e.g. “jdbc”>/service_name para cada serviço que é ligado ao aplicativo Liberty. Como ligamos uma instância de serviço do SQL Database chamada “library_db” ao nosso aplicativo com o arquivo manifest, o Liberty Buildpack liga essa instância automaticamente a qualquer instrução @Resource ou consulta JNDI do tipo acima, procurando esse nome JDNI específico.

Existe uma lista inteira de serviços com os quais o Liberty Buildpack faz essa conexão automaticamente. Esses serviços incluem o SQL Database (que usamos neste exemplo), o MYSQL, o PostreSQL, o MQLight, o Cloudant e muitos outros bancos de dados e serviços. Para obter a lista completa, consulte a documentação do Liberty Buildpack.

Então, a boa notícia é que você não precisa se preocupar com a ligação dos serviços para a maioria dos programas gravados em código Java! Isso simplifica radicalmente a quantidade de coisas que precisam ser feitas para que os programas sejam executados.

Para ver como o Bluemix cria o arquivo server.xml para o Liberty, selecione um aplicativo Java Liberty que esteja implementado no Bluemix, selecione Arquivos e logs no painel e navegue para app/wlp/usr/servers/defaultServer/server.xml.

Agora, está tudo pronto para implementar o aplicativo. Como estamos usando manifests, é simples!

  1. Na linha de comandos, digite cf push -n <NEWHOST>, em que <NEWHOST> é o nome definido para a “rota” na qual o aplicativo ficará disponível. Uma rota equivale a um subdomínio. Por exemplo, se você usar redbook-library-abc, em que abc são suas iniciais, o aplicativo ficará disponível em http://redbook-library-abc.mybluemix.net.
    image010_new
  2. O aplicativo será implementado e automaticamente ligado à instância de serviço library_db service. O aplicativo em execução pode ser acessado pelo navegador em http://<NEWHOST>.mybluemix.net. O aplicativo deve ser semelhante a este:
    image011_new

Etapa 7. Testar o aplicativo

O ideal seria ter casos de teste automatizados que pudessem ser executados para verificar se o aplicativo está funcionando. Para esse aplicativo, não temos esse luxo, portanto, aqui estão as etapas para assegurar-se de que ele esteja funcionando.

  1. Com o navegador, acesse a página inicial do aplicativo (por exemplo, http://redbook-library-abc.mybluemix.net). Clique em Desenvolver os bancos de dados. Use o botão Voltar do navegador para retornar à página inicial;
  2. Clique em Preencha o banco de dados com dados de teste. Use o botão Voltar do navegador para retornar à página inicial;
  3. Efetue login como user1 / password1;
  4. Verifique se os resultados são semelhantes a estes:
    image012_new
  5. Insira sua opção de esquema de cores e clique em Configurar. Pensamos que preto com roxo ficaria legal;
    image013_new
  6. Também é possível consultar o Bluemix e o SQLDB usando suas interfaces com o usuário. Efetue login no http://bluemix.net;
  7. No painel, localize o RedbookLibrary. Deve aparecer que ele está usando o buildpack liberty-for-java e está em execução;
    image014_new
  8. Clique em redbooklibrary. Deve aparecer que o serviço do SQL Database está ligado ao aplicativo. Clique em Ativar para abrir a UI do SQL Database e clique em Trabalhar com tabelas. Agora é possível explorar as tabelas e os dados.
    image015

Etapa 8: Desfazendo tudo

Um lembrete quanto ao Bluemix é que (após a avaliação de 30 dias) você será cobrado por gigabyte-hora! Quando estiver implementando um aplicativo de amostra e experimentando um novo procedimento para aprender como aplicá-lo em seus próprios aplicativos, é melhor desfazer tudo que foi feito.

  1. Pare o aplicativo: cf stop redbooklibrary;
  2. Remova a ligação do serviço: cf unbind-service redbooklibrary library-db;
  3. Exclua o serviço: cf delete-service library-db;
  4. Exclua o aplicativo: cf delete redbooklibrary (observe que você deve responder yquando perguntado se realmente deseja excluir o app e o serviço).

Etapa 9 (opcional). Implementar o aplicativo no buildpack Cloud Foundry Java (Tomcat)

Como mencionamos anteriormente, o IBM Bluemix suporta o Liberty for Java Runtime e também inclui o buildpack Cloud Foundry Java, com o Tomcat 8.0.21. Se você preferir continuar usando o Tomcat, poderá implementá-lo facilmente usando o buildpack Java. A única mudança é atualizar o buildpack de destino -b no arquivo manifest. Para facilitar, incluímos um segundo arquivo manifest com as mudanças apropriadas.

  1. Efetue login no Bluemix a partir da linha de comandos: cf login;
  2. Exclua o arquivo manifest.yml existente e renomeie o arquivo manifest.tomcat como manifest.yml (não se preocupe, o manifest.liberty é igual ao manifest.yml original). A versão do Tomcat do arquivo manifest é um pouco diferente da versão do Liberty que examinamos anteriormente. Primeiro, o buildpack aponta para o java_buildpack do Cloud Foundry (que contém o Tomcat). Segundo, o manifest não contém uma seção de serviço, porque a versão do Tomcat usa o banco de dados Derby na memória, cujo arquivo JAR está totalmente contido no arquivo WAR RedbookLibrary;
  3. Implemente o aplicativo no buildpack Java. Por exemplo: cf push -n NEWHOST-TOMCAT;
  4. Teste o aplicativo como foi feito na Etapa 7. Também é possível usar a interface com o usuário do Bluemix, na qual é necessário usar o aplicativo que esteja ligado ao java_buildpack;
    image016_new
  5. Limpe o aplicativo com os seguintes comandos:
    cf stop redbookLibrary
    cf delete redbookLibrary

Caso deseje usar o SQL Database com o aplicativo Tomcat, haverá etapas adicionais necessárias para a configuração do recurso. O java_buildpack não tem os recursos automáticos para ligação de banco de dados que usamos com o buildpack Liberty for Java. Essa é uma das vantagens de usar o buildpack Liberty for Java no Bluemix. Para obter mais informações sobre porque escolher o buildpack Liberty for Java buildpack, consulte “WAS classic or WAS Liberty: How to choose,“, que discute muitos dos recursos que agora estão disponíveis no Liberty.

Conclusão

Neste artigo, vimos as diferentes opções disponíveis para migrar aplicativos Java para a nuvem. Abordamos as principais considerações quanto aos serviços de tempo de execução e também de conjunto de ferramentas. Em seguida, mostramos um passo a passo de como usar o conjunto de ferramentas de linha de comandos para analisar e migrar um aplicativo Tomcat para o buildpack Liberty for Java Runtime ou Cloud Foundry Java. O próximo tutorial na série mostrará como usar o Eclipse para migrar um aplicativo Java.

bluemix

bluemix01

***

Artigo desenvolvido em parceria com:

p-rwillenborg60

Ruth Willenborg

Mensagem do anunciante:

Conheça as APIs do Mercado Livre, monte sua própria aplicação e lucre com ela! Comece agora!

Source: IMasters

Categorizados em:

Este artigo foi escrito pormajor

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *