Pular para o conteúdo principal

Implantando o Flyway em sistemas Java - Parte 3

 Ao final do post anterior (segunda parte da série sobre o Flyway), deixamos três problemas para serem resolvidos na nossa implantação do Flyway no nosso projeto. Eis os problemas que foram expostos:

  1. Senhas expostas no arquivo pom.xml;
  2. Como diferenciar ambientes diferentes para o projeto;
  3. Scripts incluídos no arquivo jar / war gerado.

Vamos às soluções para esses problemas!

Problema 1 - senhas expostas:

A solução para este problema se dá em duas partes. Primeiramente, removemos as credenciais de acesso do pom.xml e colocamos no arquivo settings.xml do Maven. Esse arquivo traz toda a configuração do framework e fica localizado na subpasta conf da pasta de instalação. Localize a seção <servers> no arquivo, e adicione uma entrada <server>, contendo um identificador para essa entrada, mais o usuário e a senha. Como no exemplo abaixo:

<server>
   <id>ripando</id>
   <username>usrmusica</username>
   <password>usrmusica</password>
</server>

Salve o arquivo settings.xml. Agora, vamos editar o arquivo pom.xml. Na seção <configuration> do plugin do Flyway, remova as informações relativas ao usuário e a senha e adicione uma entrada <serverId>, utilizando o id adicionado no settings.xml. Assim:

<plugin>
   <groupId>org.flywaydb</groupId>
   <artifactId>flyway-maven-plugin</artifactId>
   <version>7.7.3</version>
   <dependencies>
      <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <version>8.0.16</version>
      </dependency>
   </dependencies>
   <configuration>
      <driver>com.mysql.cj.jdbc.Driver</driver>
      <url>jdbc:mysql://localhost:3306/musicas?serverTimezone=UTC</url>
      <serverId>ripando</serverId>
      ...
   </configuration>
</plugin>

Executemos o plugin do Flyway; confiram que continua funcionando adequadamente:


OK, não guardamos mais a senha no arquivo pom.xml, mas alguém que conseguir acesso ao computador terá a senha a seu dispor em um arquivo texto - o arquivo settings.xml. Ainda bem que o Maven possui um recurso de criptografar as senhas guardadas em seu arquivo de configuração. Primeiro, crie o arquivo settings-security.xml, contendo uma senha master. Eis o conteúdo do arquivo:

<settingsSecurity>
   <master>{<senha master criptografada>}</master>
</settingsSecurity>

Esse arquivo deve ficar localizado na subpasta .m2 que fica na pasta do usuário do Windows. A senha criptografada pode ser gerada com o seguinte comando: mvn --encrypt-password. Esse comando irá exibir a senha criptografada, que deve ser copiada para o arquivo acima (ver print abaixo; copiar o abre e fecha chaves também).

Com a senha master, já podemos substituir as senhas no arquivo settings.xml por senhas criptografadas, usando exatamente o mesmo comando. Pronto! As senhas não estão mais expostas! Primeiro problema resolvido. Vamos ao segundo.

Problema 2 - diferenciando ambientes:

A solução para diferenciar ambientes no Maven é o uso de profiles. Um profile (perfil) consiste em um conjunto de configurações que poderão se diferenciar por uma série de fatores: através da ativação de um dos profiles, presença ou não de uma variável de ambiente, dentre muitas outras opções. A opção que mais utilizo é a ativação do profile desejado na execução do build. Podemos fazer isso com a opção -P do Maven. Assim: mvn -Phmg clean install.

Para criar um profile no seu pom.xml, adicione uma seção <profiles>, e para cada profile diferente, adicione uma subseção <profile>. Vamos criar dois profiles para o nosso projeto:

<profiles>
   <profile>
      <id>dev</id>
      <properties>
         <database.url>jdbc:mysql://localhost:3306/musicas?serverTimezone=UTC</database.url>
         <database.serverId>ripando</database.serverId>
      </properties>
   </profile>
   <profile>
      <id>prod</id>
      <properties>
         <database.url>jdbc:mysql://servidor_prod:3306/bdn_musicas?serverTimezone=UTC</database.url>
         <database.serverId>ripando_prd</database.serverId>
      </properties>
   </profile>
</profiles>

Veja que criamos os dois profiles com os ids dev e prod. Diferenciamos a URL JDBC de conexão ao banco e também o serverId. Para cada serverId relacionado no seu pom.xml, não se esqueça de adicionar a respectiva entrada no arquivo settings.xml.

Agora, precisamos alterar a configuração do plugin do Flyway, para passar a referenciar as properties contidas nos profiles. Você referencia uma property no Maven com a sintaxe ${<nome da property>} (parecido com Javascript e substituição de variáveis em strings delimitadas por ``).Ver abaixo:

<configuration>
   <driver>com.mysql.cj.jdbc.Driver</driver>
   <url>${database.url}</url>
   <serverId>${database.serverId}</serverId>
</configuration>

Pronto! Agora podemos diferenciar nosso ambiente de desenvolvimento do nosso ambiente de produção e realizar os builds apropriados. Um último ponto: se quisermos deixar um dos profiles como profile default, adicionamos o seguinte trecho XML no profile:

<profile>
   ...
   <activation>
      <activeByDefault>true</activeByDefault>
   </activation>
   ...
</profile>

Dessa forma, se não mencionarmos nenhum profile ao executar o build no Maven, esse profile será ativado por default. Vamos agora resolver o terceiro e último problema.

Problema 3 - não incluir scritps no arquivo jar/war gerado:

Este problema é o menos grave e o mais simples de ser resolvido. O Maven permite excluir arquivos do build, baseado em uma configuração. Na seção <build>, adicione uma subseção <resources> com uma subseção <resource> que configura os arquivos a serem copiados da pasta /src/main/resources. Desse jeito:

<build>
   <resources>
      <resource>
         <directory>src/main/resources</directory>
         <excludes>
            <exclude>db/migration/*.*</exclude>
         </excludes>
         <filtering>false</filtering>
      </resource>
   </resources>
   ...
</build>

Pronto, seu arquivo jar / war não mais conterá seus scripts! Problema resolvido!

Com as informações dos três posts sobre o Flyway, conseguimos configurar o plugin, colocando-o em funcionamento e resolvendo alguns problemas identificados pelo caminho. Na última parte, vamos falar sobre um recurso bem interessante da ferramenta: os placeholders! Esse recurso permite realizar uma espécie de substituição de variáveis nos scripts, tornando-os ainda mais flexíveis e poderosos. Até o próximo post!!


Comentários

Postagens mais visitadas deste blog

Jakarta EE 10, A nova versão corporativa do Java

Mais de um ano atrás, fiz um post sobre o lançamento da versão 9.1 do Jakarta EE (confira esse post aqui ). Nesse post, eu expliquei um pouco sobre a transferência do Java EE da Oracle para a Eclipse Foundation e a mudança necessária ocorrida nessa versão no nome dos pacotes: de javax para jakarta . Agora, acabou de sair uma nova versão do Jakarta EE , versão 10 , a primeira versão que verdadeiramente traz novidades nas especificações que tanto conhecemos: JPA agora evoluiu para a versão 3.1; CDI para a versão 4.0; JAX-RS  para a versão 3.1; e assim por diante. Foram mais de vinte especificações atualizadas / evoluídas nesta versão, que criou também um novo perfil de implementação. Agora, temos três perfis para implementação do Jakarta EE :  Jakarta EE 10 Platform , o perfil completo com todas as especificações (este perfil somente os servidores de aplicação costumam implementar, como Wildfly e Glassfish ); Jakarta EE 10 Web Profile , um perfil com especificações volta...

Maven - Versão nova lançada

  Saiu versão nova do Maven - 3.8.2. Esta foi apenas uma versão de correção de bugs, mas a versão anterior, a 3.8.l, foi uma versão importante e vou aproveitar para falar sobre ela. Quem acompanha o histórico de versões do Maven , deve ter percebido o pulo de versão, da 3.6.3 para esta 3.8.1. A razão está explicada neste link , e o grande motivo foi tentar evitar problemas de segurança pelo acesso a repositórios via protocolo HTTP. Por default, esta versão 3.8.1 do Maven bloqueia o acesso a repositórios HTTP - você precisa acessar repositórios HTTPS . O bloqueio acontece com a adição de um mirror chamado "maven-default-http-blocker", bloqueando todo e qualquer acesso a repositórios HTTP externos. <mirror>    <id>maven-default-http-blocker</id>    <mirrorOf>external:http:*</mirrorOf>   <name>Pseudo repository to mirror external repositories initially using HTTP.</name>    <url>http://0.0.0.0/</u...

Implantando o Flyway em sistemas Java - Parte 1

  Quando temos uma empresa terceirizada de fábrica de software desenvolvendo, geralmente especificamos no edital de licitação que essa empresa precisa entregar alguns artefatos obrigatórios para poder receber pelos serviços prestados: o código-fonte (óbvio!), diagramas UML (quando necessário), evidências de testes (artefato que cada vez mais me convenço que de nada serve)... e um plano de implantação. Esse plano de implantação precisa trazer os passos necessários para colocar o produto no ambiente de homologação (e, posteriormente, no ambiente de produção). Na maioria das vezes, um ou mais scripts de banco de dados que devem ser executados. Nós, servidores, tínhamos que abrir o plano de implantação, verificar os passos, acessar o versionador, abrir a ferramenta de banco de dados, copiar o(s) script(s), executá-los, tudo manualmente, gerando um trabalhinho chato e propenso a erros. Além disso, os scripts sempre ficavam meio perdidos: as vezes espalhados por pastas relativas às orden...