Nesse post, vamos falar como organizar seus projetos (micro serviços) para utilizar o Spring Cloud Config Server, esta é a forma como eu acredito ser a melhor organização, a qual sempre resolveu meus problemas nesses anos de trabalho.
Precisamos começar “nivelando o terreno”.
Primeiro o obvio. Usando as configurações “dentro” da aplicação cria um problema: “A cada nova configuração, uma nova publicação (deploy) precisa ser feita. Usar uma fonte externa, é a solução para este problema, você muda a configuração e faz “restart”.
Segundo. O Spring Boot tem uma forma complexa de ler e carregar suas configurações, ele carrega de diversas fontes, faz merge (fundir) dos valores e sobrescreve os dados dependendo do seus tipo e da sua ordem.
Eu não vou explicar nesse post sobre como essa ordem funciona, mas vou deixar o link para a leitura (link). O mais importante é saber que existe uma ordem e que ela influencia no seu carregamento.
Terceiro. Para colocar tudo em pratica, você vai precisar fazer a leitura de outros 2 posts. Eles não são pré-requisitos para o entendimento deste, mas são para complementares para a solução final.
Agora que já aplainamos o terreno, vamos começar.
Importando as dependências
Começamos fazendo nossa aplicação ser compatível com Spring Cloud, para isso temos que importar algumas dependências (link), ou no https://start.spring.io
marcar a dependência Config Client:
Para projetos Maven, você precisa configurar a properties, dependency e o plugin. Abaixo tem um exemplo dos valores para serem adicionados. Compare com o seu próprio pom.xml e adicione os faltantes no seu projeto:
<project> <properties> <java.version>11</java.version> <spring-cloud.version>2021.0.0</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Para projetos Gradle, precisa crias os itens ext, dependencies e dependencyManagement, abaixo segue um exemplo dos valores. Adicione os faltantes no seu projeto :
ext { set('springCloudVersion', "2021.0.0") } dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-config' } dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" } }
Não tem muito o que (dizer) “escrever”, é só ter as bibliotecas do Spring Cloud e a sua versão. Só é importante nunca estar usando uma versão mais antiga que o Spring Cloud Server.
Removendo tudo de src/main/resources
A primeira coisa que faço, é remover todos os arquivos existentes no diretório:
src/main/resources
Isso mesmo, apago tudo, tiro todos, deixo a casa vazia. 🙂
Criando o arquivo src/main/resources/bootstrap.yml
Em sequencia, crio o arquivo:
src/main/resources/bootstrap.yml
Este arquivo é o que “substitui” os arquivos application (yaml ou propreties) quando você esta usando as funções do Spring Cloud, mais informações em link.
(REVISÃO 2022, abril – Bootstrap se tornou opcional (https://github.com/spring-cloud/spring-cloud-config/issues/1695#issuecomment-693482499), desta forma, precisa ser habilitado ou migrar para o novo modelo. Contudo, até o momento desta revisão a documentação oficial esta em transição, ou seja, tem coisas escritas no modelo antigo e coisas escritas no modelo novo. Recomendo, manter no antigo até ele se tornar depreciado.)
O conteúdo deste arquivo vai ser:
spring: profiles: active: - local application: name: NOME_DA_MINHA_APP cloud: config: name: CONFIGURAÇÃO_COMUM_UM,CONFIGURAÇÃO_COMUM_DOIS,CONFIGURAÇÃO_COMUM_N,NOME_DA_MINHA_APP uri: ${CONFIG_SERVER_URI:https://endereço.padrão.do.meu.config.server} username: ${CONFIG_SERVER_USER:usuário.do.config.server} password: ${CONFIG_SERVER_PASS:senha.forte.do.config.server}
Explicando o seu conteúdo:
spring.profiles.active
Esta configuração representa qual é o profile ativo por padrão. Recomendado o valor ser local.
spring.application.name
Aqui fica o nome do seu projeto (micro serviço / aplicação), esta atributo é muito utilizado por outras bibliotecas em identificar “quem é a aplicação” em execução.
spring.cloud.config.name
Este atributo é quem cria um pouco de “dificuldade” no seu entendimento. Dá a impressão que é o mesmo que o atributo anterior: spring.application.name
, mas não é.
Este atributo representa os nomes dos arquivos ou diretórios que vão ser usados para compor o objeto que o Spring Cloud Config Server vai produzir.
No nosso exemplo, ele ira solicitar todas as configurações do profile local
para todos os arquivos:
- CONFIGURAÇÃO_COMUM_UM;
- CONFIGURAÇÃO_COMUM_DOIS;
- CONFIGURAÇÃO_COMUM_N;
- NOME_DA_MINHA_APP.
Depois disso, ele vai fazer um fusão (merge) dos valores, e entregar os atributos de cada elemento.
Este é a grande “sacada” desse modelo, pois você pode ter pré configurações para resolver assuntos específicos e especializar quando precisa.
Por exemplo, supondo que no lugar de CONFIGURAÇÃO_COMUM_UM, este arquivo tivesse o nome, MySQLCommon. Nele, você poderia já tratar todos os seus atributos de configurações para MySQL como:
- Tamanho do Connection Pool
- Query SQL de Teste de conexão
- Habilitar a conexão com o servidor precisa de SSL
Desta forma, qualquer projeto que definir o uso do MySQLCommon, já vai estar com estas configurações “base”. E se por acaso, uma aplicação precisar trocar um valor, basta colocar o atributo e seu valor dentro do arquivo da própria aplicação.
A ordem dos itens nesse atributo é muito importante, pois é ela quem dita como ira ocorrer a fusão (merge) dos atributos, sendo assim, o arquivo da aplicação precisa se sempre o ultimo para ter a prioridade em sobrepor o valor.
spring.cloud.config.uri/username/password
Este atributos representam a forma de como se conectar no Spring Cloud Config Server. Nada de mais, endereço, usuário e senha.
Configuração com valor padrão
Um “adendo” é sobre configurar valores padrões para os atributos, como por exemplo: ${CONFIG_SERVER_URI:https://endereço.padrão.do.meu.config.server}
Esta é uma sintaxe do Spring que diz:
- Se existir a variável de ambiente (env)
CONFIG_SERVER_URI
, utilize ela. - Se não, utilize o valor
https://endereço.padrão.do.meu.config.server
Esse tipo de configuração também é muito útil, pois define um valor padrão que pode ser alterado facilmente. Exemplo, no desenvolvimento local (maquina do desenvolvedor) o atributo utiliza o valor padrão, nos ambientes é passado por parâmetro o valor.
Fazer tudo via Spring Cloud Config Server
Neste modelo, todas as configurações são feitas usando o Spring Cloud Config Server, nenhuma configuração fica dentro da aplicação. Mesmo as configurações usadas para a maquina do desenvolvedor (profile “local”).
Durante o desenvolvimento as configurações já são criadas e enviada no repositório. Assim evita o “Ops! Esqueci de…”
Conclusão
Desta forma, conseguimos trocar toda a responsabilidade de parametrizar as nossas aplicações para um local fora do nosso artefato (build/deploy). Temos uma forma organizada de reutilização de configurações e podemos fazer ajustes sem precisar trocar o programa que esta em execução.
Nos vemos nos próximos posts.