Skip to content

Commit

Permalink
Revert changes in config server bootstrapper and use new PropertyReso…
Browse files Browse the repository at this point in the history
…lver class
  • Loading branch information
ryanjbaxter committed Jan 18, 2024
1 parent 6bd3908 commit ad32f45
Showing 1 changed file with 32 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,8 @@
package org.springframework.cloud.zookeeper.discovery.configclient;

import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

import org.apache.commons.logging.Log;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.x.discovery.ServiceDiscovery;
import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
import org.apache.curator.x.discovery.details.InstanceSerializer;
Expand All @@ -33,15 +28,14 @@
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.ConfigServerConfigDataLocationResolver.PropertyResolver;
import org.springframework.cloud.config.client.ConfigServerInstanceProvider;
import org.springframework.cloud.zookeeper.CuratorFactory;
import org.springframework.cloud.zookeeper.ZookeeperProperties;
import org.springframework.cloud.zookeeper.discovery.ConditionalOnZookeeperDiscoveryEnabled;
import org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryClient;
import org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryProperties;
Expand All @@ -53,10 +47,15 @@

public class ZookeeperConfigServerBootstrapper implements BootstrapRegistryInitializer {

private static boolean isEnabled(Binder binder) {
return binder.bind(ConfigClientProperties.CONFIG_DISCOVERY_ENABLED, Boolean.class).orElse(false) &&
binder.bind(ConditionalOnZookeeperDiscoveryEnabled.PROPERTY, Boolean.class).orElse(true) &&
binder.bind("spring.cloud.discovery.enabled", Boolean.class).orElse(true);
private static PropertyResolver getPropertyResolver(BootstrapContext context) {
return context.getOrElse(PropertyResolver.class, new ConfigServerConfigDataLocationResolver.PropertyResolver(context.get(Binder.class), getBindHandler(context)));
}

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

@Override
Expand All @@ -67,27 +66,28 @@ public void initialize(BootstrapRegistry registry) {
ClassUtils.isPresent("org.springframework.cloud.bootstrap.marker.Marker", null)) {
return;
}

// create curator
CuratorFactory.registerCurator(registry, null, true, bootstrapContext -> isEnabled(bootstrapContext.get(Binder.class)));
CuratorFactory.registerCurator(registry, null, true, ZookeeperConfigServerBootstrapper::isEnabled);

// create discovery
registry.registerIfAbsent(ZookeeperDiscoveryProperties.class, context -> {
Binder binder = context.get(Binder.class);
if (!isEnabled(binder)) {
PropertyResolver propertyResolver = getPropertyResolver(context);
if (!isEnabled(context)) {
return null;
}
return binder.bind(ZookeeperDiscoveryProperties.PREFIX, Bindable
.of(ZookeeperDiscoveryProperties.class), getBindHandler(context))
.orElseGet(() -> new ZookeeperDiscoveryProperties(new InetUtils(new InetUtilsProperties())));
return propertyResolver.resolveConfigurationProperties(ZookeeperDiscoveryProperties.PREFIX,
ZookeeperDiscoveryProperties.class,
() -> new ZookeeperDiscoveryProperties(new InetUtils(new InetUtilsProperties())));
});
registry.registerIfAbsent(InstanceSerializer.class, context -> {
if (!isEnabled(context.get(Binder.class))) {
if (!isEnabled(context)) {
return null;
}
return new JsonInstanceSerializer<>(ZookeeperInstance.class);
});
registry.registerIfAbsent(ServiceDiscoveryCustomizer.class, context -> {
if (!isEnabled(context.get(Binder.class))) {
if (!isEnabled(context)) {
return null;
}
CuratorFramework curator = context.get(CuratorFramework.class);
Expand All @@ -96,30 +96,31 @@ public void initialize(BootstrapRegistry registry) {
return new DefaultServiceDiscoveryCustomizer(curator, properties, serializer);
});
registry.registerIfAbsent(ServiceDiscovery.class, context -> {
if (!isEnabled(context.get(Binder.class))) {
if (!isEnabled(context)) {
return null;
}
ServiceDiscoveryCustomizer customizer = context.get(ServiceDiscoveryCustomizer.class);
return customizer.customize(ServiceDiscoveryBuilder.builder(ZookeeperInstance.class));
});
registry.registerIfAbsent(ZookeeperDiscoveryClient.class, context -> {
Binder binder = context.get(Binder.class);
if (!isEnabled(binder)) {
PropertyResolver propertyResolver = getPropertyResolver(context);
if (!isEnabled(context)) {
return null;
}
ServiceDiscovery<ZookeeperInstance> serviceDiscovery = context.get(ServiceDiscovery.class);
ZookeeperDependencies dependencies = binder.bind(ZookeeperDependencies.PREFIX, Bindable
.of(ZookeeperDependencies.class), getBindHandler(context))
.orElseGet(ZookeeperDependencies::new);
ZookeeperDependencies dependencies = propertyResolver.resolveConfigurationProperties(ZookeeperDependencies.PREFIX, ZookeeperDependencies.class, ZookeeperDependencies::new);
ZookeeperDiscoveryProperties discoveryProperties = context.get(ZookeeperDiscoveryProperties.class);

return new ZookeeperDiscoveryClient(serviceDiscovery, dependencies, discoveryProperties);
});

// create instance provider
// 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, ZookeeperFunction::create);
registry.registerIfAbsent(ConfigServerInstanceProvider.Function.class, context -> {
if (!isEnabled(context)) {
return (id) -> Collections.emptyList();
}
return context.get(ZookeeperDiscoveryClient.class)::getInstances;
});

// promote beans to context
registry.addCloseListener(event -> {
Expand All @@ -131,67 +132,9 @@ public void initialize(BootstrapRegistry registry) {
});
}

private BindHandler getBindHandler(org.springframework.boot.BootstrapContext context) {
return 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 ZookeeperFunction implements ConfigServerInstanceProvider.Function {

private final BootstrapContext context;

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

static ZookeeperFunction create(BootstrapContext context) {
return new ZookeeperFunction(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 || !isEnabled(binder)) {
return Collections.emptyList();
}

ZookeeperProperties properties = context.getOrElse(ZookeeperProperties.class, binder.bind(ZookeeperProperties.PREFIX, Bindable.of(ZookeeperProperties.class))
.orElse(new ZookeeperProperties()));
RetryPolicy retryPolicy = context.getOrElse(RetryPolicy.class, new ExponentialBackoffRetry(properties.getBaseSleepTimeMs(), properties.getMaxRetries(),
properties.getMaxSleepMs()));
try {
CuratorFramework curatorFramework = context.getOrElse(CuratorFramework.class, CuratorFactory.curatorFramework(properties, retryPolicy, Stream::of,
() -> null, () -> null));
InstanceSerializer<ZookeeperInstance> serializer = context.getOrElse(InstanceSerializer.class, new JsonInstanceSerializer<>(ZookeeperInstance.class));
ZookeeperDiscoveryProperties discoveryProperties = context.getOrElse(ZookeeperDiscoveryProperties.class, binder.bind(ZookeeperDiscoveryProperties.PREFIX, Bindable
.of(ZookeeperDiscoveryProperties.class), bindHandler)
.orElseGet(() -> new ZookeeperDiscoveryProperties(new InetUtils(new InetUtilsProperties()))));
ServiceDiscoveryCustomizer customizer = context.getOrElse(ServiceDiscoveryCustomizer.class, new DefaultServiceDiscoveryCustomizer(curatorFramework, discoveryProperties, serializer));
ServiceDiscovery<ZookeeperInstance> serviceDiscovery = customizer.customize(ServiceDiscoveryBuilder.builder(ZookeeperInstance.class));
ZookeeperDependencies dependencies = context.getOrElse(ZookeeperDependencies.class, binder.bind(ZookeeperDependencies.PREFIX, Bindable
.of(ZookeeperDependencies.class), bindHandler)
.orElseGet(ZookeeperDependencies::new));
return new ZookeeperDiscoveryClient(serviceDiscovery, dependencies, discoveryProperties).getInstances(serviceId);
}
catch (Exception e) {
log.warn("Error fetching config server instance from Zookeeper", e);
return Collections.emptyList();
}

}
private static BindHandler getBindHandler(org.springframework.boot.BootstrapContext context) {
return context.getOrElse(BindHandler.class, null);
}

}

0 comments on commit ad32f45

Please sign in to comment.