1717package org .springframework .cloud .zookeeper .discovery .configclient ;
1818
1919import java .util .Collections ;
20- import java .util .List ;
21- import java .util .stream .Stream ;
2220
23- import org .apache .commons .logging .Log ;
24- import org .apache .curator .RetryPolicy ;
2521import org .apache .curator .framework .CuratorFramework ;
26- import org .apache .curator .retry .ExponentialBackoffRetry ;
2722import org .apache .curator .x .discovery .ServiceDiscovery ;
2823import org .apache .curator .x .discovery .ServiceDiscoveryBuilder ;
2924import org .apache .curator .x .discovery .details .InstanceSerializer ;
3328import org .springframework .boot .BootstrapRegistry ;
3429import org .springframework .boot .BootstrapRegistryInitializer ;
3530import org .springframework .boot .context .properties .bind .BindHandler ;
36- import org .springframework .boot .context .properties .bind .Bindable ;
3731import org .springframework .boot .context .properties .bind .Binder ;
38- import org .springframework .cloud .client .ServiceInstance ;
3932import org .springframework .cloud .commons .util .InetUtils ;
4033import org .springframework .cloud .commons .util .InetUtilsProperties ;
4134import org .springframework .cloud .config .client .ConfigClientProperties ;
35+ import org .springframework .cloud .config .client .ConfigServerConfigDataLocationResolver .PropertyResolver ;
4236import org .springframework .cloud .config .client .ConfigServerInstanceProvider ;
4337import org .springframework .cloud .zookeeper .CuratorFactory ;
44- import org .springframework .cloud .zookeeper .ZookeeperProperties ;
4538import org .springframework .cloud .zookeeper .discovery .ConditionalOnZookeeperDiscoveryEnabled ;
4639import org .springframework .cloud .zookeeper .discovery .ZookeeperDiscoveryClient ;
4740import org .springframework .cloud .zookeeper .discovery .ZookeeperDiscoveryProperties ;
5346
5447public class ZookeeperConfigServerBootstrapper implements BootstrapRegistryInitializer {
5548
56- private static boolean isEnabled (Binder binder ) {
57- return binder .bind (ConfigClientProperties .CONFIG_DISCOVERY_ENABLED , Boolean .class ).orElse (false ) &&
58- binder .bind (ConditionalOnZookeeperDiscoveryEnabled .PROPERTY , Boolean .class ).orElse (true ) &&
59- binder .bind ("spring.cloud.discovery.enabled" , Boolean .class ).orElse (true );
49+ private static PropertyResolver getPropertyResolver (BootstrapContext context ) {
50+ return context .getOrElseSupply (PropertyResolver .class , () -> new PropertyResolver (
51+ context .get (Binder .class ), context .getOrElse (BindHandler .class , null )));
52+ }
53+
54+ public static boolean isEnabled (BootstrapContext bootstrapContext ) {
55+ PropertyResolver propertyResolver = getPropertyResolver (bootstrapContext );
56+ return propertyResolver .get (ConfigClientProperties .CONFIG_DISCOVERY_ENABLED , Boolean .class , false ) &&
57+ propertyResolver .get (ConditionalOnZookeeperDiscoveryEnabled .PROPERTY , Boolean .class , true ) &&
58+ propertyResolver .get ("spring.cloud.discovery.enabled" , Boolean .class , true );
6059 }
6160
6261 @ Override
@@ -67,27 +66,28 @@ public void initialize(BootstrapRegistry registry) {
6766 ClassUtils .isPresent ("org.springframework.cloud.bootstrap.marker.Marker" , null )) {
6867 return ;
6968 }
69+
7070 // create curator
71- CuratorFactory .registerCurator (registry , null , true , bootstrapContext -> isEnabled ( bootstrapContext . get ( Binder . class )) );
71+ CuratorFactory .registerCurator (registry , null , true , ZookeeperConfigServerBootstrapper :: isEnabled );
7272
7373 // create discovery
7474 registry .registerIfAbsent (ZookeeperDiscoveryProperties .class , context -> {
75- Binder binder = context .get (Binder .class );
76- if (!isEnabled (binder )) {
75+ if (!isEnabled (context )) {
7776 return null ;
7877 }
79- return binder .bind (ZookeeperDiscoveryProperties .PREFIX , Bindable
80- .of (ZookeeperDiscoveryProperties .class ), getBindHandler (context ))
81- .orElseGet (() -> new ZookeeperDiscoveryProperties (new InetUtils (new InetUtilsProperties ())));
78+ PropertyResolver propertyResolver = getPropertyResolver (context );
79+ return propertyResolver .resolveConfigurationProperties (ZookeeperDiscoveryProperties .PREFIX ,
80+ ZookeeperDiscoveryProperties .class ,
81+ () -> new ZookeeperDiscoveryProperties (new InetUtils (new InetUtilsProperties ())));
8282 });
8383 registry .registerIfAbsent (InstanceSerializer .class , context -> {
84- if (!isEnabled (context . get ( Binder . class ) )) {
84+ if (!isEnabled (context )) {
8585 return null ;
8686 }
8787 return new JsonInstanceSerializer <>(ZookeeperInstance .class );
8888 });
8989 registry .registerIfAbsent (ServiceDiscoveryCustomizer .class , context -> {
90- if (!isEnabled (context . get ( Binder . class ) )) {
90+ if (!isEnabled (context )) {
9191 return null ;
9292 }
9393 CuratorFramework curator = context .get (CuratorFramework .class );
@@ -96,30 +96,31 @@ public void initialize(BootstrapRegistry registry) {
9696 return new DefaultServiceDiscoveryCustomizer (curator , properties , serializer );
9797 });
9898 registry .registerIfAbsent (ServiceDiscovery .class , context -> {
99- if (!isEnabled (context . get ( Binder . class ) )) {
99+ if (!isEnabled (context )) {
100100 return null ;
101101 }
102102 ServiceDiscoveryCustomizer customizer = context .get (ServiceDiscoveryCustomizer .class );
103103 return customizer .customize (ServiceDiscoveryBuilder .builder (ZookeeperInstance .class ));
104104 });
105105 registry .registerIfAbsent (ZookeeperDiscoveryClient .class , context -> {
106- Binder binder = context .get (Binder .class );
107- if (!isEnabled (binder )) {
106+ if (!isEnabled (context )) {
108107 return null ;
109108 }
109+ PropertyResolver propertyResolver = getPropertyResolver (context );
110110 ServiceDiscovery <ZookeeperInstance > serviceDiscovery = context .get (ServiceDiscovery .class );
111- ZookeeperDependencies dependencies = binder .bind (ZookeeperDependencies .PREFIX , Bindable
112- .of (ZookeeperDependencies .class ), getBindHandler (context ))
113- .orElseGet (ZookeeperDependencies ::new );
111+ ZookeeperDependencies dependencies = propertyResolver .resolveConfigurationProperties (ZookeeperDependencies .PREFIX , ZookeeperDependencies .class , ZookeeperDependencies ::new );
114112 ZookeeperDiscoveryProperties discoveryProperties = context .get (ZookeeperDiscoveryProperties .class );
115113
116114 return new ZookeeperDiscoveryClient (serviceDiscovery , dependencies , discoveryProperties );
117115 });
118116
119117 // create instance provider
120- // We need to pass the lambda here so we do not create a new instance of ConfigServerInstanceProvider.Function
121- // which would result in a ClassNotFoundException when Spring Cloud Config is not on the classpath
122- registry .registerIfAbsent (ConfigServerInstanceProvider .Function .class , ZookeeperFunction ::create );
118+ registry .registerIfAbsent (ConfigServerInstanceProvider .Function .class , context -> {
119+ if (!isEnabled (context )) {
120+ return (id ) -> Collections .emptyList ();
121+ }
122+ return context .get (ZookeeperDiscoveryClient .class )::getInstances ;
123+ });
123124
124125 // promote beans to context
125126 registry .addCloseListener (event -> {
@@ -130,68 +131,4 @@ public void initialize(BootstrapRegistry registry) {
130131 }
131132 });
132133 }
133-
134- private BindHandler getBindHandler (org .springframework .boot .BootstrapContext context ) {
135- return context .getOrElse (BindHandler .class , null );
136- }
137-
138- /*
139- * This Function is executed when loading config data. Because of this we cannot rely on the
140- * BootstrapContext because Boot has not finished loading all the configuration data so if we
141- * ask the BootstrapContext for configuration data it will not have it. The apply method in this function
142- * is passed the Binder and BindHandler from the config data context which has the configuration properties that
143- * have been loaded so far in the config data process.
144- *
145- * We will create many of the same beans in this function as we do above in the initializer above. We do both
146- * to maintain compatibility since we are promoting those beans to the main application context.
147- */
148- static final class ZookeeperFunction implements ConfigServerInstanceProvider .Function {
149-
150- private final BootstrapContext context ;
151-
152- private ZookeeperFunction (BootstrapContext context ) {
153- this .context = context ;
154- }
155-
156- static ZookeeperFunction create (BootstrapContext context ) {
157- return new ZookeeperFunction (context );
158- }
159-
160- @ Override
161- public List <ServiceInstance > apply (String serviceId ) {
162- return apply (serviceId , null , null , null );
163- }
164-
165- @ Override
166- public List <ServiceInstance > apply (String serviceId , Binder binder , BindHandler bindHandler , Log log ) {
167- if (binder == null || !isEnabled (binder )) {
168- return Collections .emptyList ();
169- }
170-
171- ZookeeperProperties properties = context .getOrElse (ZookeeperProperties .class , binder .bind (ZookeeperProperties .PREFIX , Bindable .of (ZookeeperProperties .class ))
172- .orElse (new ZookeeperProperties ()));
173- RetryPolicy retryPolicy = context .getOrElse (RetryPolicy .class , new ExponentialBackoffRetry (properties .getBaseSleepTimeMs (), properties .getMaxRetries (),
174- properties .getMaxSleepMs ()));
175- try {
176- CuratorFramework curatorFramework = context .getOrElse (CuratorFramework .class , CuratorFactory .curatorFramework (properties , retryPolicy , Stream ::of ,
177- () -> null , () -> null ));
178- InstanceSerializer <ZookeeperInstance > serializer = context .getOrElse (InstanceSerializer .class , new JsonInstanceSerializer <>(ZookeeperInstance .class ));
179- ZookeeperDiscoveryProperties discoveryProperties = context .getOrElse (ZookeeperDiscoveryProperties .class , binder .bind (ZookeeperDiscoveryProperties .PREFIX , Bindable
180- .of (ZookeeperDiscoveryProperties .class ), bindHandler )
181- .orElseGet (() -> new ZookeeperDiscoveryProperties (new InetUtils (new InetUtilsProperties ()))));
182- ServiceDiscoveryCustomizer customizer = context .getOrElse (ServiceDiscoveryCustomizer .class , new DefaultServiceDiscoveryCustomizer (curatorFramework , discoveryProperties , serializer ));
183- ServiceDiscovery <ZookeeperInstance > serviceDiscovery = customizer .customize (ServiceDiscoveryBuilder .builder (ZookeeperInstance .class ));
184- ZookeeperDependencies dependencies = context .getOrElse (ZookeeperDependencies .class , binder .bind (ZookeeperDependencies .PREFIX , Bindable
185- .of (ZookeeperDependencies .class ), bindHandler )
186- .orElseGet (ZookeeperDependencies ::new ));
187- return new ZookeeperDiscoveryClient (serviceDiscovery , dependencies , discoveryProperties ).getInstances (serviceId );
188- }
189- catch (Exception e ) {
190- log .warn ("Error fetching config server instance from Zookeeper" , e );
191- return Collections .emptyList ();
192- }
193-
194- }
195- }
196-
197134}
0 commit comments