Servidor configuraciones usando Spring Cloud

En esta ocasión vamos a usar el paquete Spring Cloud Config para poder tener configuraciones remotas para nuestras aplicaciones.

La idea es que nuestro programa o programas puedan ir a buscar sus parámetros de configuración a un lugar externo, de tal manera que nuestra aplicación sea fácilmente parametrizable e incluso se puedan cambiar sus configuraciones en caliente.

Esto se utiliza ampliamente en microservicios pues una mismo servicio o aplicación puede estar lanzada muchas veces en diferentes contenedores y es interesante tener un lugar central desde donde se puedan aplicar las configuraciones a estos servicios.

Para ello vamos a crear un servidor de configuraciones y un cliente que buscara su configuración en ese servidor.

El servidor de configuraciones, usara un repositorio GIT de GitHub donde estarán los ficheros de configuración.

Los datos de las aplicaciones serán los siguientes.

*** Servidor de configuraciones**
* Cliente de configuraciones
  • Proyecto: config-client
  • Puerto: 8080
  • Nombre Spring: config-client

Los fuentes de los programas están en: https://github.com/chuchip/servercloudconfig

  1. Servidor de configuraciones

La única dependencia para poder crear un servidor de configuraciones es incluir este paquete en nuestro proyecto maven

El starter de Spring seria Config Server

El servidor de configuraciones se compone de una sola clase, que detallo a continuación:

Como se ve, lo único destacable es la anotación @EnableConfigServer .

En el fichero application.properties pondremos donde debe buscar las configuraciones, con el parámetro: spring.cloud.config.server.git.uri

En este caso le decimos que use un servidor Git que tenemos alojado en GitHub. También podríamos especificar que el use un repositorio GIT local de este modo:

Los servidores de configuración de Spring Cloud soportan los siguientes orígenes (backends):

  • GIT
  • Vault
  • JDBC ,

Estos orígenes incluso se pueden mezclar, de tal manera que dependiendo del perfil elegido se use uno u otro. Pero esto se escapa al ámbito de este documento.

En el caso del servidor GIT, que es el utilizado en el ejemplo, lo importante es tener un fichero que se llame como el cliente que va a solicitar los datos, terminado en .properties. Así si queremos guardar configuración para una aplicación cliente que se llame config-client , es decir que en la variable spring.application.namesea igual a config-client, deberemos tener un fichero llamado config-client.propertiesEn este fichero pondremos los valores, de esta manera:

Obsérvese que el valor puede ser asignado con : (dos puntos) o = (igual)

NO usar comillas para delimitar los literales, a no ser que se quiera que nuestro literal (String) incluya esas comillas.

Para ver los valores pasados a nuestros cliente, realizaremos una petición GET especificando el nombre del cliente y el perfil.

En este caso solicitamos la configuración para el cliente config-clienty el perfil defaultque es el perfil utilizado si no especifica ninguno.

Para ver la configuración para el perfil production se llamaría a la URL:http://localhost:8888/config-client/production. Lo cual muestra la siguiente salida:

Como se puede observar, muestra el contenido del fichero config-client-production.propertiesy después el contenido del ficheroconfig-client.properties.

De esta manera, si un cliente solicita un valor y ese valor existe en el perfil solicitado, se devolverá ese valor. En caso contrario se buscaría en el perfil default , devolviendo el valor asignado si lo tuviera.

  1. Cliente de configuraciones

Una vez tenemos nuestro servidor de configuraciones y levantado, pasaremos a crear el cliente.

La única dependencia en nuestro fichero maven será la siguiente:

Usando Spring Initializr seria añadir la dependencia Config Client . Además, para poder refrescar la configuración en caliente, añadiremos el starter Actuator

Ahora deberemos configurar la aplicación para especificar donde esta el servidor de configuraciones, para ello, lo primero será cambiar el fichero config.properties por bootstrap.properties. De esta manera Spring Boot sabrá que debe buscar un servidor de configuraciones

En este fichero añadiremos la propiedad spring.cloud.config.uriespecificando la URL de nuestro servidor de configuraciones.

También estableceremos la propiedad management.endpoints.web.exposure.include a refreshpara configurar el paquete actuator de tal modo que se pueda acceder a la URL http://localhost:8080/actuator/refreshque será la que obligara a refrescar las diferentes propiedades.

Recordar que la variable spring.application.nameestablecera el nombre de la aplicación e indicara el fichero del repositorio git donde se buscaran los valores de configuración.

Con la variable spring.profiles.activeindicariamos que perfil es el que debemos usar. Si no ponemos ninguno (como es el caso pues esta comentada la línea), se utilizara el perfil default

En este ejemplo uso varios métodos para leer la configuración.

  1. Crear un componente que incluye la etiqueta @ConfigurationProperties

En este método, que es el mas sencillo, indicamos cual es la raíz de las propiedades a leer y luego definimos las variables que Spring debe rellenar.

En la clase configuration.java especificamos que queremos coger las variables que empiecen por limites.

De este modo la variable dato1 tendrá el valor especificado en limites.dato1

Si limites.dato1tuviera un valor que no se puede pasar a un entero nuestra aplicación fallaría, sin embargo si no encuentra el valor simplemente no lo rellena, sin dar ningún tipo de error.

Este componente será inyectado a través de una etiqueta @Autowired

2. Crear una variable con la anotación @Value

De esta manera también se leerá el valor del servidor de configuraciones. La mayor diferencia es que ese valor será fijo pues será asignado al ejecutar la aplicación y no se refrescara nunca.

La variable valorFijotendra el valor asignado en la línea: valores.valor_fijo

3. Usar la anotación @Value en el parámetro de una función

  • Igualmente el valor se leerá desde el servidor de configuraciones con la ventaja de que el valor podrá ser refrescado.

En nuestro ejemplo se exponen las URL /limites, refrescadoy datos.

La llamada a limitesnos devolverá esta salida:

Suponiendo que realizáramos un commit de tal manera que los valores en nuestro servidor GIT hayan cambiado, sucesivas llamadas a esta URL nos mostrarían los antiguos datos, pues el cliente solo lee la configuración al principio, a no ser que se le obligue a refrescar sus datos.

Imaginemos que cambiamos el fichero `config-client.properties’ de tal manera que ahora tiene estos valores

Hacemos el correspondiente commit y push

Cuando llamemos a la URL http://localhost:8080/actuator/refresh con un método POST obligaremos a Spring a llamar al servidor de configuraciones y refrescar los valores.

Como se ve, la salida de esta petición nos devuelve las variables refrescadas.

Ahora, si llamamos a http://localhost:8080/limites veríamos que el valor de minResultados y maxResultados han cambiado. Sin embargo ni valorFijo ni valorFuncion no lo han hecho.

Si llamamos a la URL http://localhost:8080/refrescado veremos que la variable valorFuncion se ha actualizado pues en la llamada esta puesta la etiqueta @Value de tal manera que la variable es leída en ese momento. Sin embargo la variable valorFijo no es cambiada pues se estableció al inicio del programa y su valor permanece inalterado.

Es importante destacar que si quitamos una variable en nuestro fichero de configuración, el valor de la variable no se pondrá a null sino que mantendrá el valor anteriormente establecido. Esto es valido tanto si la variable es leída con @Value como si utilizamos un @ConfigurationProperties en un @Bean

Y eso es todo por ahora, en próximas lecciones explicare como hacer que las configuraciones se refresquen automagicamenteutilizando el componente Spring Bus Cloud