Spring Search in Cloud Config Server via Eureka using Java instead of bootstrap.yml

I am trying to create code in our base pom that will auto-configure Spring to view Cloud Config server through Eureka. We do this to avoid .yml property templates for microservice developers. For example, we want java to configure all the behavior caused by these properties:

spring: application: name: MyMicroservice cloud: config: enabled: true server: prefix: /diagnostics/admin/config failFast: true discovery: enabled: true serviceId: echo management: context-path: /diagnostics/admin eureka: password: password client: serviceUrl: defaultZone: http://user:${eureka.password}@localhost:8761/eureka/ instance: leaseRenewalIntervalInSeconds: 10 statusPageUrlPath: /diagnostics/admin/info healthCheckUrlPath: /diagnostics/admin/health 

After long experiments, it basically works, except for the configuration server open in Eureka (as a result of which there were no overridden configuration properties):

 @Order(-1) public class AdditionalBootstrapPropertySourceLocator implements PropertySourceLocator { @Override public PropertySource<?> locate(Environment environment) { Map<String, Object> theBootstrapYmlConfig = new HashMap<>(); theBootstrapYmlConfig.put("spring.cloud.config.enabled", new Boolean(true)); theBootstrapYmlConfig.put("spring.cloud.config.server.prefix", "/diagnostics/admin/config"); theBootstrapYmlConfig.put("spring.cloud.config.failFast", new Boolean(true)); theBootstrapYmlConfig.put("spring.cloud.config.discovery.enabled", new Boolean(true)); theBootstrapYmlConfig.put("spring.cloud.config.discovery.serviceId", "echo"); theBootstrapYmlConfig.put("management.context-path", "/diagnostics/admin"); theBootstrapYmlConfig.put("eureka.client.serviceUrl.defaultZone", "http://user: password@localhost :8761/eureka/"); theBootstrapYmlConfig.put("eureka.instance.leaseRenewalIntervalInSeconds", new Integer(10)); theBootstrapYmlConfig.put("eureka.instance.statusPageUrlPath", "/diagnostics/admin/info"); theBootstrapYmlConfig.put("eureka.instance.healthCheckUrlPath", "/diagnostics/admin/health"); return new MapPropertySource("myExtraBootstrap", theBootstrapYmlConfig); } } 

I also need this Bean:

 @ConditionalOnWebApplication @Configuration @Import(EurekaClientAutoConfiguration.class) public class WorkfrontDiscoveryClientConfigServiceBootstrapConfiguration { @Bean @ConditionalOnClass({ DiscoveryClient.class, ConfigServicePropertySourceLocator.class }) @ConditionalOnMissingBean DiscoveryClientConfigServiceBootstrapConfiguration discoveryClientConfigServiceBootstrapConfiguration() { DiscoveryClientConfigServiceBootstrapConfiguration discoveryClientConfigServiceBootstrapConfiguration = new DiscoveryClientConfigServiceBootstrapConfiguration(); return discoveryClientConfigServiceBootstrapConfiguration; } } 

Finally, I placed both in spring.factories so that they are built. The problem is that PropertySourceLocator is never used to build a call to ConfigServicePropertySourceLocator to retrieve properties. No matter what I do, I don't seem to agree with the behavior defining properties in bootstrap.yml.

Edit after 4 days

The key factor (and limitation) here is the ability to search for a configuration server through Eureka. In the current release of cloud Spring (1.0.2), the source code of the source is extracted and created too early in the Spring initialization cycle to configure the config-look-through-eureka java configuration source described above. Plus, if the Eureka server is slow or unavailable at boot time, the original Config server resource is never restored when Eureka finally appears. This, in my opinion, is a mistake.

I solved all this by excluding the concept of searching for a configuration server through Eureka and requiring this minimal configuration in bootstrap.yml:

 spring: application: name: MyMicroservice cloud: config: uri: http://localhost:8888/diagnostics/admin/config eureka: client: serviceUrl: defaultZone: http://user: password@localhost :8761/eureka/ 

and then set the rest to java AdditionalBootstrapPropertySourceLocator

Edit after 30 days

The bootstrap properties for the Java configuration remain a problem. I do this because I am developing a framework without templates or code generation (Spring boot premise). I added spring-retry to the mix and client-to-config will repeat again, but re-registering with Eureka does not. That's why Eureka - first had to leave for me. I would include my voice in spring-retry integration in the Eureka registration process so that I can return to Eureka - first for my frameworks. Still on Spring Cloud 1.0.2.

Edit after 100 days

An update for where we ended up. Continuing our mantra to avoid property patterns, applying policy and practice in code, and continuing without the Eureka concept, we abandoned the PropertySourceLocator and simply used SpringApplicationRunListener as follows:

 public class OurFrameworkProperties implements SpringApplicationRunListener { : public void started() { if (TestCaseUtils.isRunningFromTestCase()) { System.setProperty("spring.cloud.config.failFast", "false"); System.setProperty("spring.cloud.config.enabled", "false"); System.setProperty("eureka.client.enabled", "false"); } else { // set production values same way } } } 

A warning that this start () is actually called twice inside Spring code (once without passing any btw programmatic arguments) every time a Spring application starts or receives an Actuator () update.

+5
source share
1 answer

If your PropertySourceLocator is listed in spring.factories (I assume as BootstrapConfiguration ), then it should be @Component (or maybe even @Configuration ).

0
source

All Articles