Native profile support

Let’s begin with the simplest example, based on a filesystem backend. By default, Spring Cloud Config Server tries to fetch configuration data from a Git repository. To enable the native profile, we should launch the server with the spring.profiles.active option set to native. It searches for files stored in the following locations, classpath:/, classpath:/config, file:./, file:./config. It means that properties or YAML files may be also placed inside a JAR file. For test purposes, I created a config folder inside src/main/resources. Our configuration files will be stored in that location. Now, we need to go back for a moment to the example from the previous chapter. As you probably remember, I introduced the configuration for a clustered discovery environment, where each client service instance was launched in a different zone. There were three available zones and three client instances, each of them has its own profile in the application.yml file. The source code for that example is available in the config branch. Here's the link:

https://github.com/piomin/sample-spring-cloud-netflix/tree/config

Our current task is to migrate that configuration to the Spring Cloud Config Server. Let's remind ourselves the properties set for that example. Here are the profile settings used for the first instance of the client application. According to the selected profile, there are a changing instance running port, a default discovery server URL and a zone name:

---
spring:
profiles: zone1

eureka:
instance:
metadataMap:
zone: zone1
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/

server:
port: ${PORT:8081}

In the described example I placed all of the profiles settings in a single application.yml file for simplicity. That file might as well be divided into three different files with the names including the profiles, application-zone1.yml, application-zone2.yml, and application-zone3.yml. Of course, such names are unique to a single application, so if we decided to move the files into a remote configuration server, we should take care of their names. The client application name is injected from spring.application.name and in this case, it is client-service. So, to conclude, I created three configuration files with the name client-service-zone[n].yml in the src/main/resources/config catalog, where [n] is an instance's number. Now, when you call the http://localhost:8888/client-service/zone1 endpoint, you will receive the following response in JSON format:

{
"name":"client-service",
"profiles":["zone1"],
"label":null,
"version":null,
"state":null,
"propertySources":[{
"name":"classpath:/config/client-service-zone1.yml",
"source":{
"eureka.instance.metadataMap.zone":"zone1",
"eureka.client.serviceUrl.defaultZone":"http://localhost:8761/eureka/",
"server.port":"${PORT:8081}"
}
}]
}

We can also call http://localhost:8888/client-service-zone2.properties for the second instance, which returns the following response as a list of properties:

eureka.client.serviceUrl.defaultZone: http://localhost:8762/eureka/
eureka.instance.metadataMap.zone: zone2
server.port: 8082

The last available version of the HTTP API endpoint, http://localhost:8889/client-service-zone3.yml, returns data identical to the input file. Here's the result for the third instance:

eureka:
client:
serviceUrl:
defaultZone: http://localhost:8763/eureka/
instance:
metadataMap:
zone: zone3
server:
port: 8083