Skip to content

Commit

Permalink
Merge branch 'master' into patch-3
Browse files Browse the repository at this point in the history
  • Loading branch information
lonre authored Jul 21, 2021
2 parents 207c1c7 + 9bd4703 commit 832963d
Show file tree
Hide file tree
Showing 34 changed files with 384 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ Apollo 1.9.0
* [feature: add the delegating password encoder for apollo-portal simple auth](https://github.com/ctripcorp/apollo/pull/3804)
* [support release apollo-client-config-data](https://github.com/ctripcorp/apollo/pull/3822)
* [Fix possiable NPE](https://github.com/ctripcorp/apollo/pull/3832)
* [Reduce bootstrap time in the situation with large properties](https://github.com/ctripcorp/apollo/pull/3816)
* [docs: English catalog in sidebar](https://github.com/ctripcorp/apollo/pull/3831)
------------------
All issues and pull requests are [here](https://github.com/ctripcorp/apollo/milestone/6?closed=1)

Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@

import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigService;
import com.ctrip.framework.apollo.build.ApolloInjector;
import com.ctrip.framework.apollo.core.ApolloClientSystemConsts;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.utils.DeferredLogger;
import com.ctrip.framework.apollo.spring.config.CachedCompositePropertySource;
import com.ctrip.framework.apollo.spring.config.ConfigPropertySourceFactory;
import com.ctrip.framework.apollo.spring.config.PropertySourcesConstants;
import com.ctrip.framework.apollo.spring.util.SpringInjector;
import com.ctrip.framework.apollo.util.ConfigUtil;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import java.util.List;
Expand Down Expand Up @@ -85,11 +88,14 @@ public class ApolloApplicationContextInitializer implements
ApolloClientSystemConsts.APOLLO_ACCESS_KEY_SECRET,
ApolloClientSystemConsts.APOLLO_META,
ApolloClientSystemConsts.APOLLO_CONFIG_SERVICE,
ApolloClientSystemConsts.APOLLO_PROPERTY_ORDER_ENABLE};
ApolloClientSystemConsts.APOLLO_PROPERTY_ORDER_ENABLE,
ApolloClientSystemConsts.APOLLO_PROPERTY_NAMES_CACHE_ENABLE};

private final ConfigPropertySourceFactory configPropertySourceFactory = SpringInjector
.getInstance(ConfigPropertySourceFactory.class);

private final ConfigUtil configUtil = ApolloInjector.getInstance(ConfigUtil.class);

private int order = DEFAULT_ORDER;

@Override
Expand Down Expand Up @@ -123,7 +129,12 @@ protected void initialize(ConfigurableEnvironment environment) {
logger.debug("Apollo bootstrap namespaces: {}", namespaces);
List<String> namespaceList = NAMESPACE_SPLITTER.splitToList(namespaces);

CompositePropertySource composite = new CompositePropertySource(PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME);
CompositePropertySource composite;
if (configUtil.isPropertyNamesCacheEnabled()) {
composite = new CachedCompositePropertySource(PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME);
} else {
composite = new CompositePropertySource(PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME);
}
for (String namespace : namespaceList) {
Config config = ConfigService.getConfig(namespace);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright 2021 Apollo 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
*
* http://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 com.ctrip.framework.apollo.spring.config;

import com.ctrip.framework.apollo.ConfigChangeListener;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.PropertySource;

/**
* @author Shawyeok ([email protected])
*/
public class CachedCompositePropertySource extends CompositePropertySource implements
ConfigChangeListener {

private volatile String[] names;

public CachedCompositePropertySource(String name) {
super(name);
}

@Override
public String[] getPropertyNames() {
String[] propertyNames = this.names;
if (propertyNames == null) {
this.names = propertyNames = super.getPropertyNames();
}
return propertyNames;
}

@Override
public void addPropertySource(PropertySource<?> propertySource) {
super.addPropertySource(propertySource);
if (propertySource instanceof ConfigPropertySource) {
((ConfigPropertySource) propertySource).addChangeListener(this);
}
}

@Override
public void addFirstPropertySource(PropertySource<?> propertySource) {
super.addFirstPropertySource(propertySource);
if (propertySource instanceof ConfigPropertySource) {
((ConfigPropertySource) propertySource).addChangeListener(this);
}
}

@Override
public void onChange(ConfigChangeEvent changeEvent) {
// clear property names cache if any sources has changed
this.names = null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ public class ConfigPropertySource extends EnumerablePropertySource<Config> {
super(name, source);
}

@Override
public boolean containsProperty(String name) {
return this.source.getProperty(name, null) != null;
}

@Override
public String[] getPropertyNames() {
Set<String> propertyNames = this.source.getPropertyNames();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,12 @@ private void initializePropertySources() {
//already initialized
return;
}
CompositePropertySource composite = new CompositePropertySource(PropertySourcesConstants.APOLLO_PROPERTY_SOURCE_NAME);
CompositePropertySource composite;
if (configUtil.isPropertyNamesCacheEnabled()) {
composite = new CachedCompositePropertySource(PropertySourcesConstants.APOLLO_PROPERTY_SOURCE_NAME);
} else {
composite = new CompositePropertySource(PropertySourcesConstants.APOLLO_PROPERTY_SOURCE_NAME);
}

//sort by order asc
ImmutableSortedSet<Integer> orders = ImmutableSortedSet.copyOf(NAMESPACE_NAMES.keySet());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public class ConfigUtil {
private boolean autoUpdateInjectedSpringProperties = true;
private final RateLimiter warnLogRateLimiter;
private boolean propertiesOrdered = false;
private boolean propertyNamesCacheEnabled = false;

public ConfigUtil() {
warnLogRateLimiter = RateLimiter.create(0.017); // 1 warning log output per minute
Expand All @@ -68,6 +69,7 @@ public ConfigUtil() {
initLongPollingInitialDelayInMills();
initAutoUpdateInjectedSpringProperties();
initPropertiesOrdered();
initPropertyNamesCacheEnabled();
}

/**
Expand Down Expand Up @@ -394,4 +396,28 @@ private void initPropertiesOrdered() {
public boolean isPropertiesOrderEnabled() {
return propertiesOrdered;
}

public boolean isPropertyNamesCacheEnabled() {
return propertyNamesCacheEnabled;
}

private void initPropertyNamesCacheEnabled() {
String propertyName = ApolloClientSystemConsts.APOLLO_PROPERTY_NAMES_CACHE_ENABLE;
String propertyEnvName = ApolloClientSystemConsts.APOLLO_PROPERTY_NAMES_CACHE_ENABLE_ENVIRONMENT_VARIABLES;
String enablePropertyNamesCache = System.getProperty(propertyName);
if (Strings.isNullOrEmpty(enablePropertyNamesCache)) {
enablePropertyNamesCache = System.getenv(propertyEnvName);
}
if (Strings.isNullOrEmpty(enablePropertyNamesCache)) {
enablePropertyNamesCache = Foundation.app().getProperty(propertyName, "false");
}
if (!Strings.isNullOrEmpty(enablePropertyNamesCache)) {
try {
propertyNamesCacheEnabled = Boolean.parseBoolean(enablePropertyNamesCache);
} catch (Throwable ex) {
logger.warn("Config for {} is invalid: {}, set default value: false",
propertyName, enablePropertyNamesCache);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigChangeListener;
import com.ctrip.framework.apollo.ConfigFileChangeListener;
import com.ctrip.framework.apollo.core.ApolloClientSystemConsts;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.internals.SimpleConfig;
import com.ctrip.framework.apollo.internals.YamlConfigFile;
Expand Down Expand Up @@ -93,6 +94,7 @@ public void tearDown() throws Exception {
System.clearProperty(SystemPropertyKeyConstants.FROM_SYSTEM_YAML_NAMESPACE);
System.clearProperty(SystemPropertyKeyConstants.FROM_NAMESPACE_APPLICATION_KEY);
System.clearProperty(SystemPropertyKeyConstants.FROM_NAMESPACE_APPLICATION_KEY_YAML);
System.clearProperty(ApolloClientSystemConsts.APOLLO_PROPERTY_NAMES_CACHE_ENABLE);
super.tearDown();
}

Expand Down Expand Up @@ -456,13 +458,17 @@ public void testApolloConfigChangeListenerResolveExpressionSimple() {
Config applicationConfig = mock(Config.class);
mockConfig(ConfigConsts.NAMESPACE_APPLICATION, applicationConfig);

System.setProperty(ApolloClientSystemConsts.APOLLO_PROPERTY_NAMES_CACHE_ENABLE, "true");

getSimpleBean(TestApolloConfigChangeListenerResolveExpressionSimpleConfiguration.class);

// no using
verify(ignoreConfig, never()).addChangeListener(any(ConfigChangeListener.class));

// one invocation for spring value auto update and another for the @ApolloConfigChangeListener annotation
verify(applicationConfig, times(2)).addChangeListener(any(ConfigChangeListener.class));
// one invocation for spring value auto update
// one invocation for the @ApolloConfigChangeListener annotation
// one invocation for CachedCompositePropertySource clear cache listener
verify(applicationConfig, times(3)).addChangeListener(any(ConfigChangeListener.class));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,20 @@

import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.build.MockInjector;
import com.ctrip.framework.apollo.core.ApolloClientSystemConsts;
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.spring.config.CachedCompositePropertySource;
import com.ctrip.framework.apollo.spring.config.PropertySourcesConstants;
import com.ctrip.framework.apollo.util.ConfigUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;

public class ApolloApplicationContextInitializerTest {

Expand All @@ -42,6 +48,8 @@ public void tearDown() throws Exception {
System.clearProperty(ConfigConsts.APOLLO_CLUSTER_KEY);
System.clearProperty(ApolloClientSystemConsts.APOLLO_CACHE_DIR);
System.clearProperty(ConfigConsts.APOLLO_META_KEY);

MockInjector.reset();
}

@Test
Expand Down Expand Up @@ -109,4 +117,30 @@ public void testFillFromEnvironmentWithNoPropertyFromEnvironment() throws Except
assertNull(System.getProperty(ApolloClientSystemConsts.APOLLO_CACHE_DIR));
assertNull(System.getProperty(ConfigConsts.APOLLO_META_KEY));
}

@Test
public void testPropertyNamesCacheEnabled() {
ConfigurableEnvironment environment = mock(ConfigurableEnvironment.class);
MutablePropertySources propertySources = new MutablePropertySources();
when(environment.getPropertySources()).thenReturn(propertySources);
when(environment.getProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_NAMESPACES,
ConfigConsts.NAMESPACE_APPLICATION)).thenReturn("");

apolloApplicationContextInitializer.initialize(environment);

assertTrue(propertySources.contains(PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME));
assertFalse(propertySources.iterator().next() instanceof CachedCompositePropertySource);

ConfigUtil configUtil = new ConfigUtil();
configUtil = spy(configUtil);
when(configUtil.isPropertyNamesCacheEnabled()).thenReturn(true);
MockInjector.setInstance(ConfigUtil.class, configUtil);
apolloApplicationContextInitializer = new ApolloApplicationContextInitializer();
propertySources.remove(PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME);

apolloApplicationContextInitializer.initialize(environment);

assertTrue(propertySources.contains(PropertySourcesConstants.APOLLO_BOOTSTRAP_PROPERTY_SOURCE_NAME));
assertTrue(propertySources.iterator().next() instanceof CachedCompositePropertySource);
}
}
Loading

0 comments on commit 832963d

Please sign in to comment.