Moves common property source functionality to ZookeeperPropertySources.java
This commit is contained in:
@@ -24,6 +24,8 @@ import org.springframework.cloud.zookeeper.ZookeeperAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Bootstrap Configuration for Zookeeper Configuration.
|
||||
@@ -45,8 +47,12 @@ public class ZookeeperConfigBootstrapConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ZookeeperConfigProperties zookeeperConfigProperties() {
|
||||
return new ZookeeperConfigProperties();
|
||||
public ZookeeperConfigProperties zookeeperConfigProperties(Environment env) {
|
||||
ZookeeperConfigProperties properties = new ZookeeperConfigProperties();
|
||||
if (StringUtils.isEmpty(properties.getName())) {
|
||||
properties.setName(env.getProperty("spring.application.name", "application"));
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,8 +18,6 @@ package org.springframework.cloud.zookeeper.config;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.curator.framework.CuratorFramework;
|
||||
|
||||
import org.springframework.boot.context.config.ConfigData;
|
||||
@@ -29,8 +27,6 @@ import org.springframework.boot.context.config.ConfigDataLocationNotFoundExcepti
|
||||
|
||||
public class ZookeeperConfigDataLoader implements ConfigDataLoader<ZookeeperConfigDataLocation> {
|
||||
|
||||
private static final Log log = LogFactory.getLog(ZookeeperConfigDataLoader.class);
|
||||
|
||||
@Override
|
||||
public ConfigData load(ConfigDataLoaderContext context, ZookeeperConfigDataLocation location) {
|
||||
try {
|
||||
@@ -40,16 +36,8 @@ public class ZookeeperConfigDataLoader implements ConfigDataLoader<ZookeeperConf
|
||||
return new ConfigData(Collections.singletonList(propertySource));
|
||||
}
|
||||
catch (Exception e) {
|
||||
ZookeeperConfigProperties properties = context.getBootstrapContext()
|
||||
.get(ZookeeperConfigProperties.class);
|
||||
if (properties.isFailFast() || !location.isOptional()) {
|
||||
throw new ConfigDataLocationNotFoundException(location, e);
|
||||
}
|
||||
else {
|
||||
log.warn("Unable to load zookeeper config from " + location.getContext(), e);
|
||||
}
|
||||
throw new ConfigDataLocationNotFoundException(location, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.curator.RetryPolicy;
|
||||
import org.apache.curator.drivers.TracerDriver;
|
||||
import org.apache.curator.ensemble.EnsembleProvider;
|
||||
@@ -51,13 +50,17 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
public class ZookeeperConfigDataLocationResolver implements ConfigDataLocationResolver<ZookeeperConfigDataLocation> {
|
||||
|
||||
private static final Log log = LogFactory.getLog(ZookeeperConfigDataLocationResolver.class);
|
||||
|
||||
/**
|
||||
* Zookeeper Config Data prefix.
|
||||
*/
|
||||
public static final String PREFIX = "zookeeper:";
|
||||
|
||||
private final Log log;
|
||||
|
||||
public ZookeeperConfigDataLocationResolver(Log log) {
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResolvable(ConfigDataLocationResolverContext context, String location) {
|
||||
if (!location.startsWith(PREFIX)) {
|
||||
@@ -94,8 +97,10 @@ public class ZookeeperConfigDataLocationResolver implements ConfigDataLocationRe
|
||||
context.getBootstrapContext().registerIfAbsent(CuratorFramework.class, InstanceSupplier
|
||||
.from(() -> curatorFramework(context.getBootstrapContext(), zookeeperProperties, optional)));
|
||||
|
||||
ZookeeperPropertySources sources = new ZookeeperPropertySources(properties, log);
|
||||
|
||||
List<String> contexts = (locationUri == null || CollectionUtils.isEmpty(locationUri.getPathSegments()))
|
||||
? getAutomaticContexts(profiles, properties) : getCustomContexts(locationUri);
|
||||
? sources.getAutomaticContexts(profiles.getAccepted()) : getCustomContexts(locationUri);
|
||||
|
||||
context.getBootstrapContext().addCloseListener(event -> {
|
||||
CuratorFramework curatorFramework = event.getBootstrapContext().get(CuratorFramework.class);
|
||||
@@ -122,27 +127,6 @@ public class ZookeeperConfigDataLocationResolver implements ConfigDataLocationRe
|
||||
return Arrays.asList(uriComponents.getPath().split(";"));
|
||||
}
|
||||
|
||||
protected List<String> getAutomaticContexts(Profiles profiles, ZookeeperConfigProperties properties) {
|
||||
String root = properties.getRoot();
|
||||
List<String> contexts = new ArrayList<>();
|
||||
|
||||
String defaultContext = root + "/" + properties.getDefaultContext();
|
||||
contexts.add(defaultContext);
|
||||
addProfiles(contexts, defaultContext, profiles, properties);
|
||||
|
||||
StringBuilder baseContext = new StringBuilder(root);
|
||||
if (!properties.getName().startsWith("/")) {
|
||||
baseContext.append("/");
|
||||
}
|
||||
// getName() defaults to ${spring.application.name} or application
|
||||
baseContext.append(properties.getName());
|
||||
contexts.add(baseContext.toString());
|
||||
addProfiles(contexts, baseContext.toString(), profiles, properties);
|
||||
|
||||
Collections.reverse(contexts);
|
||||
return contexts;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected UriComponents parseLocation(String location) {
|
||||
String uri = location.substring(PREFIX.length());
|
||||
@@ -158,13 +142,6 @@ public class ZookeeperConfigDataLocationResolver implements ConfigDataLocationRe
|
||||
return UriComponentsBuilder.fromUriString(uri).build();
|
||||
}
|
||||
|
||||
private void addProfiles(List<String> contexts, String baseContext, Profiles profiles,
|
||||
ZookeeperConfigProperties properties) {
|
||||
for (String profile : profiles.getAccepted()) {
|
||||
contexts.add(baseContext + properties.getProfileSeparator() + profile);
|
||||
}
|
||||
}
|
||||
|
||||
protected CuratorFramework curatorFramework(ConfigurableBootstrapContext context, ZookeeperProperties properties,
|
||||
boolean optional) {
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.zookeeper.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -32,8 +31,7 @@ import org.springframework.core.env.CompositePropertySource;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Zookeeper provides a <a href=
|
||||
@@ -78,6 +76,7 @@ public class ZookeeperPropertySourceLocator implements PropertySourceLocator {
|
||||
public ZookeeperPropertySourceLocator(CuratorFramework curator,
|
||||
ZookeeperConfigProperties properties) {
|
||||
this.curator = curator;
|
||||
Assert.hasText(properties.getName(), ZookeeperConfigProperties.PREFIX + ".name must not be empty");
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@@ -89,50 +88,19 @@ public class ZookeeperPropertySourceLocator implements PropertySourceLocator {
|
||||
public PropertySource<?> locate(Environment environment) {
|
||||
if (environment instanceof ConfigurableEnvironment) {
|
||||
ConfigurableEnvironment env = (ConfigurableEnvironment) environment;
|
||||
String appName = properties.getName();
|
||||
if (StringUtils.isEmpty(appName)) {
|
||||
// use default "application" (which config client does)
|
||||
appName = env.getProperty("spring.application.name", "application");
|
||||
if (appName.equals("application")) {
|
||||
log.warn("spring.application.name is not set. Using default of 'application'");
|
||||
}
|
||||
}
|
||||
|
||||
List<String> profiles = Arrays.asList(env.getActiveProfiles());
|
||||
|
||||
String root = this.properties.getRoot();
|
||||
this.contexts = new ArrayList<>();
|
||||
|
||||
String defaultContext = root + "/" + this.properties.getDefaultContext();
|
||||
this.contexts.add(defaultContext);
|
||||
addProfiles(this.contexts, defaultContext, profiles);
|
||||
|
||||
StringBuilder baseContext = new StringBuilder(root);
|
||||
if (!appName.startsWith("/")) {
|
||||
baseContext.append("/");
|
||||
}
|
||||
baseContext.append(appName);
|
||||
this.contexts.add(baseContext.toString());
|
||||
addProfiles(this.contexts, baseContext.toString(), profiles);
|
||||
ZookeeperPropertySources sources = new ZookeeperPropertySources(properties, log);
|
||||
this.contexts = sources.getAutomaticContexts(profiles);
|
||||
|
||||
CompositePropertySource composite = new CompositePropertySource("zookeeper");
|
||||
|
||||
Collections.reverse(this.contexts);
|
||||
|
||||
for (String propertySourceContext : this.contexts) {
|
||||
try {
|
||||
PropertySource propertySource = create(propertySourceContext);
|
||||
composite.addPropertySource(propertySource);
|
||||
// TODO: howto call close when /refresh
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (this.properties.isFailFast()) {
|
||||
ReflectionUtils.rethrowRuntimeException(e);
|
||||
}
|
||||
else {
|
||||
log.warn("Unable to load zookeeper config from "
|
||||
+ propertySourceContext, e);
|
||||
}
|
||||
}
|
||||
PropertySource<CuratorFramework> propertySource = sources.createPropertySource(propertySourceContext, true, this.curator);
|
||||
composite.addPropertySource(propertySource);
|
||||
}
|
||||
|
||||
return composite;
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2015-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.zookeeper.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.curator.framework.CuratorFramework;
|
||||
|
||||
public class ZookeeperPropertySources {
|
||||
private final ZookeeperConfigProperties properties;
|
||||
private final Log log;
|
||||
|
||||
public ZookeeperPropertySources(ZookeeperConfigProperties properties, Log log) {
|
||||
this.properties = properties;
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public List<String> getAutomaticContexts(List<String> profiles) {
|
||||
String root = properties.getRoot();
|
||||
List<String> contexts = new ArrayList<>();
|
||||
|
||||
String defaultContext = root + "/" + properties.getDefaultContext();
|
||||
contexts.add(defaultContext);
|
||||
addProfiles(contexts, defaultContext, profiles);
|
||||
|
||||
StringBuilder baseContext = new StringBuilder(root);
|
||||
if (!properties.getName().startsWith("/")) {
|
||||
baseContext.append("/");
|
||||
}
|
||||
// getName() defaults to ${spring.application.name} or application
|
||||
baseContext.append(properties.getName());
|
||||
contexts.add(baseContext.toString());
|
||||
addProfiles(contexts, baseContext.toString(), profiles);
|
||||
|
||||
Collections.reverse(contexts);
|
||||
return contexts;
|
||||
}
|
||||
|
||||
private void addProfiles(List<String> contexts, String baseContext, List<String> profiles) {
|
||||
for (String profile : profiles) {
|
||||
contexts.add(baseContext + properties.getProfileSeparator() + profile);
|
||||
}
|
||||
}
|
||||
|
||||
public ZookeeperPropertySource createPropertySource(String context, boolean optional, CuratorFramework curator) {
|
||||
try {
|
||||
return new ZookeeperPropertySource(context, curator);
|
||||
// TODO: howto call close when /refresh
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (this.properties.isFailFast() || !optional) {
|
||||
throw new ZookeeperPropertySourceNotFoundException(e);
|
||||
}
|
||||
else {
|
||||
log.warn("Unable to load zookeeper config from " + context, e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static class ZookeeperPropertySourceNotFoundException extends RuntimeException {
|
||||
|
||||
ZookeeperPropertySourceNotFoundException(Exception source) {
|
||||
super(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.ConfigurableBootstrapContext;
|
||||
@@ -39,7 +40,7 @@ public class ZookeeperConfigDataLocationResolverTests {
|
||||
|
||||
@Test
|
||||
public void testParseLocation() {
|
||||
ZookeeperConfigDataLocationResolver resolver = new ZookeeperConfigDataLocationResolver();
|
||||
ZookeeperConfigDataLocationResolver resolver = new ZookeeperConfigDataLocationResolver(LogFactory.getLog(getClass()));
|
||||
UriComponents uriComponents = resolver.parseLocation(
|
||||
"zookeeper:myhost:2182/mypath1;/mypath2;/mypath3");
|
||||
assertThat(uriComponents.toUri()).hasScheme("zookeeper").hasHost("myhost")
|
||||
@@ -102,7 +103,7 @@ public class ZookeeperConfigDataLocationResolverTests {
|
||||
}
|
||||
|
||||
private ZookeeperConfigDataLocationResolver createResolver() {
|
||||
return new ZookeeperConfigDataLocationResolver();
|
||||
return new ZookeeperConfigDataLocationResolver(LogFactory.getLog(getClass()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,8 +34,10 @@ public class ZookeeperPropertySourceLocatorNoApplicationNameTests {
|
||||
public void defaultSpringApplicationNameWorks() {
|
||||
CuratorFramework curator = mock(CuratorFramework.class);
|
||||
when(curator.getChildren()).thenReturn(mock(GetChildrenBuilder.class));
|
||||
ZookeeperConfigProperties properties = new ZookeeperConfigProperties();
|
||||
properties.setName("notempty");
|
||||
ZookeeperPropertySourceLocator locator = new ZookeeperPropertySourceLocator(
|
||||
curator, new ZookeeperConfigProperties());
|
||||
curator, properties);
|
||||
locator.locate(new MockEnvironment());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user