Skip to content

Commit

Permalink
Remove ConsulFunction and Use PropertyResolver (#833)
Browse files Browse the repository at this point in the history
This relates to spring-cloud/spring-cloud-config#2375

It reverts portions of #819

Co-authored-by: Ryan Baxter <524254+ryanjbaxter@users.noreply.github.com>
  • Loading branch information
ryanjbaxter and ryanjbaxter committed Jan 24, 2024
1 parent b9ec6ee commit daae7d2
Showing 1 changed file with 30 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,18 @@
package org.springframework.cloud.consul.discovery.configclient;

import java.util.Collections;
import java.util.List;

import com.ecwid.consul.v1.ConsulClient;
import org.apache.commons.logging.Log;

import org.springframework.boot.BootstrapContext;
import org.springframework.boot.BootstrapRegistry;
import org.springframework.boot.BootstrapRegistryInitializer;
import org.springframework.boot.context.properties.bind.BindHandler;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.commons.util.InetUtilsProperties;
import org.springframework.cloud.config.client.ConfigClientProperties;
import org.springframework.cloud.config.client.ConfigServerConfigDataLocationResolver;
import org.springframework.cloud.config.client.ConfigServerInstanceProvider;
import org.springframework.cloud.consul.ConsulAutoConfiguration;
import org.springframework.cloud.consul.ConsulProperties;
Expand All @@ -51,36 +48,35 @@ public void initialize(BootstrapRegistry registry) {
}
// create consul client
registry.registerIfAbsent(ConsulProperties.class, context -> {
Binder binder = context.get(Binder.class);
if (!isDiscoveryEnabled(binder)) {
if (!isDiscoveryEnabled(context)) {
return null;
}
return binder.bind(ConsulProperties.PREFIX, Bindable.of(ConsulProperties.class), getBindHandler(context))
.orElseGet(ConsulProperties::new);
ConfigServerConfigDataLocationResolver.PropertyResolver propertyResolver = getPropertyResolver(context);
return propertyResolver.resolveConfigurationProperties(ConsulProperties.PREFIX, ConsulProperties.class,
ConsulProperties::new);
});
registry.registerIfAbsent(ConsulClient.class, context -> {
if (!isDiscoveryEnabled(context.get(Binder.class))) {
if (!isDiscoveryEnabled(context)) {
return null;
}
ConsulProperties consulProperties = context.get(ConsulProperties.class);
return ConsulAutoConfiguration.createConsulClient(consulProperties,
ConsulAutoConfiguration.createConsulRawClientBuilder());
});
registry.registerIfAbsent(ConsulDiscoveryClient.class, context -> {
Binder binder = context.get(Binder.class);
if (!isDiscoveryEnabled(binder)) {
if (!isDiscoveryEnabled(context)) {
return null;
}
ConfigServerConfigDataLocationResolver.PropertyResolver propertyResolver = getPropertyResolver(context);
ConsulClient consulClient = context.get(ConsulClient.class);
ConsulDiscoveryProperties properties = binder
.bind(ConsulDiscoveryProperties.PREFIX, Bindable.of(ConsulDiscoveryProperties.class),
getBindHandler(context))
.orElseGet(() -> new ConsulDiscoveryProperties(new InetUtils(new InetUtilsProperties())));
ConsulDiscoveryProperties properties = propertyResolver.resolveConfigurationProperties(
ConsulDiscoveryProperties.PREFIX, ConsulDiscoveryProperties.class,
() -> new ConsulDiscoveryProperties(new InetUtils(new InetUtilsProperties())));
return new ConsulDiscoveryClient(consulClient, properties);
});
// promote discovery client if created
registry.addCloseListener(event -> {
if (!isDiscoveryEnabled(event.getBootstrapContext().get(Binder.class))) {
if (!isDiscoveryEnabled(event.getBootstrapContext())) {
return;
}
ConsulDiscoveryClient discoveryClient = event.getBootstrapContext().get(ConsulDiscoveryClient.class);
Expand All @@ -90,71 +86,28 @@ public void initialize(BootstrapRegistry registry) {
}
});

// We need to pass the lambda here so we do not create a new instance of
// ConfigServerInstanceProvider.Function
// which would result in a ClassNotFoundException when Spring Cloud Config is not
// on the classpath
registry.registerIfAbsent(ConfigServerInstanceProvider.Function.class, ConsulFunction::create);
}

private BindHandler getBindHandler(org.springframework.boot.BootstrapContext context) {
return context.getOrElse(BindHandler.class, null);
registry.registerIfAbsent(ConfigServerInstanceProvider.Function.class, context -> {
if (!isDiscoveryEnabled(context)) {
return (id) -> Collections.emptyList();
}
ConsulDiscoveryClient discoveryClient = context.get(ConsulDiscoveryClient.class);
return discoveryClient::getInstances;
});
}

private static boolean isDiscoveryEnabled(Binder binder) {
return binder.bind(ConfigClientProperties.CONFIG_DISCOVERY_ENABLED, Boolean.class).orElse(false)
&& binder.bind(ConditionalOnConsulDiscoveryEnabled.PROPERTY, Boolean.class).orElse(true)
&& binder.bind("spring.cloud.discovery.enabled", Boolean.class).orElse(true);
private static ConfigServerConfigDataLocationResolver.PropertyResolver getPropertyResolver(
BootstrapContext context) {
return context.getOrElseSupply(ConfigServerConfigDataLocationResolver.PropertyResolver.class,
() -> new ConfigServerConfigDataLocationResolver.PropertyResolver(context.get(Binder.class),
context.getOrElse(BindHandler.class, null)));
}

/*
* This Function is executed when loading config data. Because of this we cannot rely
* on the BootstrapContext because Boot has not finished loading all the configuration
* data so if we ask the BootstrapContext for configuration data it will not have it.
* The apply method in this function is passed the Binder and BindHandler from the
* config data context which has the configuration properties that have been loaded so
* far in the config data process.
*
* We will create many of the same beans in this function as we do above in the
* initializer above. We do both to maintain compatibility since we are promoting
* those beans to the main application context.
*/
static final class ConsulFunction implements ConfigServerInstanceProvider.Function {

private final BootstrapContext context;

private ConsulFunction(BootstrapContext context) {
this.context = context;
}

public static ConsulFunction create(BootstrapContext context) {
return new ConsulFunction(context);
}

@Override
public List<ServiceInstance> apply(String serviceId) {
return apply(serviceId, null, null, null);
}

@Override
public List<ServiceInstance> apply(String serviceId, Binder binder, BindHandler bindHandler, Log log) {
if (binder == null || !isDiscoveryEnabled(binder)) {
return Collections.emptyList();
}

ConsulProperties consulProperties = binder
.bind(ConsulProperties.PREFIX, Bindable.of(ConsulProperties.class), bindHandler)
.orElseGet(ConsulProperties::new);
ConsulClient consulClient = ConsulAutoConfiguration.createConsulClient(consulProperties,
ConsulAutoConfiguration.createConsulRawClientBuilder());
ConsulDiscoveryProperties properties = binder
.bind(ConsulDiscoveryProperties.PREFIX, Bindable.of(ConsulDiscoveryProperties.class), bindHandler)
.orElseGet(() -> new ConsulDiscoveryProperties(new InetUtils(new InetUtilsProperties())));
ConsulDiscoveryClient discoveryClient = new ConsulDiscoveryClient(consulClient, properties);

return discoveryClient.getInstances(serviceId);
}

public static boolean isDiscoveryEnabled(BootstrapContext bootstrapContext) {
ConfigServerConfigDataLocationResolver.PropertyResolver propertyResolver = getPropertyResolver(
bootstrapContext);
return propertyResolver.get(ConfigClientProperties.CONFIG_DISCOVERY_ENABLED, Boolean.class, false)
&& propertyResolver.get(ConditionalOnConsulDiscoveryEnabled.PROPERTY, Boolean.class, true)
&& propertyResolver.get("spring.cloud.discovery.enabled", Boolean.class, true);
}

}

0 comments on commit daae7d2

Please sign in to comment.