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

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...

REST Assured

Recentemente, fiz uma apresentação no meu trabalho falando sobre o framework REST Assured, que permite construir testes unitários que verificam o funcionamento de serviços REST. Confira a apresentação abaixo!

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...