Ejemplo de Servidor Spring Cloud Config
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
config-client
config-server
.gitignore
captura1.png
captura2.png
captura3.png
captura4.png
captura5.png
captura6.png
config-client-production.properties
config-client.properties
readme.md

readme.md

Servidor Configuraciones en 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

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-config-server</artifactId>
</dependency>

El starter de Spring seria Config Server

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

package com.profesorp.configserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConfigServerApplication.class, args);
	}
}

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

spring.application.name=config-server
server.port=8888

spring.cloud.config.server.git.uri=https://github.com/chuchip/servercloudconfig.git

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:

spring.cloud.config.server.git.uri=file://eclipe/spring-config/

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:

datosservidor.minimum=11
datosservidor.maximum=20
limites.minimum=-1
limites.maximum=2
valores.valor_fijo: VALORFIJO
valores.valor_funcion: "VALORDEFUNCION"

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.

captura2

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:

captura3

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:

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-config</artifactId>
</dependency>

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 . En este fichero añadiremos la propiedad spring.cloud.config.uriespecificara la URL de nuestro servidor de configuraciones.

spring.application.name=config-client
spring.cloud.config.uri=http://localhost:8888
#spring.profiles.active=production
management.endpoints.web.exposure.include=refresh

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

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import lombok.Data;

@Data
@Component
@ConfigurationProperties("limites")
public class Configuration {
	private int minimum;
	private int maximum;	
}

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

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

@Autowired
private Configuration configuration;
  1. 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.

@Value("${valores.valor_fijo}")
String valorFijo;

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

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

@GetMapping("/refrescado")
public BeanConfiguration getConfiguracionRefrescada(@Value("${valores.valor_funcion}") String valorFuncion)
	{ .... }
  • Funcionamiento

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

La llamada a limitesnos devolverá esta salida:

captura4

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

datosservidor.minimum=10
datosservidor.maximum=20
limites.minimum=-101
limites.maximum=201
valores.valor_fijo: OTROVALORFIJO
valores.valor_funcion: "OTROVALORDEFUNCION"

Hacemos el correspondiente commit y push

 > git commit -a -m "cambiada configuracion";git 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.

captura5

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