Skip to content

Commit

Permalink
Use new strategy to load config.
Browse files Browse the repository at this point in the history
1. specified cluster
2. data center as cluster
3. default cluster
  • Loading branch information
nobodyiam committed May 26, 2016
1 parent 4ef524e commit b04949c
Show file tree
Hide file tree
Showing 13 changed files with 205 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,13 @@ private ApolloConfig loadApolloConfig() {
logger.debug("Config server responds with 304 HTTP status code.");
return m_configCache.get();
}
logger.debug("Loaded config: {}", response.getBody());

return response.getBody();
ApolloConfig result = response.getBody();

Cat.logEvent("Apollo.Client.ConfigLoaded." + result.getNamespaceName(), result.getReleaseKey());
logger.debug("Loaded config for {}: {}", m_namespace, result);

return result;
} catch (Throwable ex) {
Cat.logError(ex);
transaction.setStatus(ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class ConfigUtil {

/**
* Get the app id for the current application.
*
* @return the app id
* @throws IllegalStateException if app id is not set
*/
Expand All @@ -36,18 +37,30 @@ public String getAppId() {

/**
* Get the data center info for the current application.
*
* @return the current data center, null if there is no such info.
*/
public String getDataCenter() {
return Foundation.server().getDataCenter();
String dataCenter = Foundation.server().getDataCenter();
//TODO use sub env from framework foundation if data center is null
return dataCenter;
}

/**
* Get the cluster name for the current application.
*
* @return the cluster name, or "default" if not specified
*/
public String getCluster() {
//Load data center from system property
String cluster = System.getProperty("apollo.cluster");

//Use data center as cluster
if (cluster == null) {
cluster = getDataCenter();
}

//Use default cluster
if (cluster == null) {
cluster = ConfigConsts.CLUSTER_NAME_DEFAULT;
}
Expand All @@ -56,6 +69,7 @@ public String getCluster() {

/**
* Get the current environment.
*
* @return the env
* @throws IllegalStateException if env is set
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,18 @@ public ApolloConfig queryConfig(@PathVariable String appId, @PathVariable String
HttpServletResponse response) throws IOException {
List<Release> releases = Lists.newLinkedList();

Release currentAppRelease = configService.findRelease(appId, clusterName, namespace);
Release currentAppRelease = loadConfig(appId, clusterName, namespace, dataCenter);
String appClusterNameLoaded = clusterName;

if (currentAppRelease != null) {
releases.add(currentAppRelease);
//we have cluster search process, so the cluster name might be overridden
appClusterNameLoaded = currentAppRelease.getClusterName();
}

//if namespace is not 'application', should check if it's a public configuration
if (!Objects.equals(ConfigConsts.NAMESPACE_DEFAULT, namespace)) {
Release publicRelease = this.findPublicConfig(appId, namespace, dataCenter);
Release publicRelease = this.findPublicConfig(appId, clusterName, namespace, dataCenter);
if (!Objects.isNull(publicRelease)) {
releases.add(publicRelease);
}
Expand All @@ -96,14 +99,14 @@ public ApolloConfig queryConfig(@PathVariable String appId, @PathVariable String
// Client side configuration is the same with server side, return 304
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
Cat.logEvent("Apollo.Config.NotModified",
assembleKey(appId, clusterName, namespace, dataCenter));
assembleKey(appId, appClusterNameLoaded, namespace, dataCenter));
return null;
}

ApolloConfig apolloConfig = new ApolloConfig(appId, clusterName, namespace, mergedReleaseKey);
ApolloConfig apolloConfig = new ApolloConfig(appId, appClusterNameLoaded, namespace, mergedReleaseKey);
apolloConfig.setConfigurations(mergeReleaseConfigurations(releases));

Cat.logEvent("Apollo.Config.Found", assembleKey(appId, clusterName, namespace, dataCenter));
Cat.logEvent("Apollo.Config.Found", assembleKey(appId, appClusterNameLoaded, namespace, dataCenter));
return apolloConfig;
}

Expand All @@ -112,7 +115,7 @@ public ApolloConfig queryConfig(@PathVariable String appId, @PathVariable String
* @param namespace the namespace
* @param dataCenter the datacenter
*/
private Release findPublicConfig(String applicationId, String namespace, String dataCenter) {
private Release findPublicConfig(String applicationId, String clusterName, String namespace, String dataCenter) {
AppNamespace appNamespace = appNamespaceService.findByNamespaceName(namespace);

//check whether the namespace's appId equals to current one
Expand All @@ -122,18 +125,32 @@ private Release findPublicConfig(String applicationId, String namespace, String

String publicConfigAppId = appNamespace.getAppId();

return loadConfig(publicConfigAppId, clusterName, namespace, dataCenter);
}

private Release loadConfig(String appId, String clusterName, String namespace, String dataCenter) {
//load from specified cluster fist
if (!Objects.equals(ConfigConsts.CLUSTER_NAME_DEFAULT, clusterName)) {
Release clusterRelease =
configService.findRelease(appId, clusterName, namespace);

if (!Objects.isNull(clusterRelease)) {
return clusterRelease;
}
}

//try to load via data center
if (!Objects.isNull(dataCenter)) {
if (!Objects.isNull(dataCenter) && !Objects.equals(dataCenter, clusterName)) {
Release dataCenterRelease =
configService.findRelease(publicConfigAppId, dataCenter, namespace);
configService.findRelease(appId, dataCenter, namespace);
if (!Objects.isNull(dataCenterRelease)) {
return dataCenterRelease;
}
}

//fallback to default release
return configService
.findRelease(publicConfigAppId, ConfigConsts.CLUSTER_NAME_DEFAULT, namespace);
.findRelease(appId, ConfigConsts.CLUSTER_NAME_DEFAULT, namespace);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;

import com.ctrip.framework.apollo.biz.entity.AppNamespace;
import com.ctrip.framework.apollo.biz.message.MessageListener;
Expand All @@ -30,6 +31,7 @@

import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
* @author Jason Song([email protected])
Expand Down Expand Up @@ -59,11 +61,11 @@ public DeferredResult<ResponseEntity<ApolloConfigNotification>> pollNotification
@RequestParam(value = "cluster") String cluster,
@RequestParam(value = "namespace", defaultValue = ConfigConsts.NAMESPACE_DEFAULT) String namespace,
@RequestParam(value = "dataCenter", required = false) String dataCenter) {
List<String> watchedKeys = Lists.newArrayList(assembleKey(appId, cluster, namespace));
Set<String> watchedKeys = assembleWatchKeys(appId, cluster, namespace, dataCenter);

//Listen on more namespaces, since it's not the default namespace
if (!Objects.equals(ConfigConsts.NAMESPACE_DEFAULT, namespace)) {
watchedKeys.addAll(this.findPublicConfigWatchKey(appId, namespace, dataCenter));
watchedKeys.addAll(this.findPublicConfigWatchKey(appId, cluster, namespace, dataCenter));
}

DeferredResult<ResponseEntity<ApolloConfigNotification>> deferredResult =
Expand Down Expand Up @@ -94,9 +96,9 @@ private String assembleKey(String appId, String cluster, String namespace) {
return STRING_JOINER.join(appId, cluster, namespace);
}

private List<String> findPublicConfigWatchKey(String applicationId, String namespace,
String dataCenter) {
List<String> publicWatchedKeys = Lists.newArrayList();
private Set<String> findPublicConfigWatchKey(String applicationId, String clusterName,
String namespace,
String dataCenter) {
AppNamespace appNamespace = appNamespaceService.findByNamespaceName(namespace);
/**
* Manually close the entity manager.
Expand All @@ -108,21 +110,32 @@ private List<String> findPublicConfigWatchKey(String applicationId, String names

//check whether the namespace's appId equals to current one
if (Objects.isNull(appNamespace) || Objects.equals(applicationId, appNamespace.getAppId())) {
return publicWatchedKeys;
return Sets.newHashSet();
}

String publicConfigAppId = appNamespace.getAppId();

return assembleWatchKeys(publicConfigAppId, clusterName, namespace, dataCenter);
}

private Set<String> assembleWatchKeys(String appId, String clusterName, String namespace,
String dataCenter) {
Set<String> watchedKeys = Sets.newHashSet();

//watch specified cluster config change
if (!Objects.equals(ConfigConsts.CLUSTER_NAME_DEFAULT, clusterName)) {
watchedKeys.add(assembleKey(appId, clusterName, namespace));
}

//watch data center config change
if (!Objects.isNull(dataCenter)) {
publicWatchedKeys.add(assembleKey(publicConfigAppId, dataCenter, namespace));
if (!Objects.isNull(dataCenter) && !Objects.equals(dataCenter, clusterName)) {
watchedKeys.add(assembleKey(appId, dataCenter, namespace));
}

//watch default cluster config change
publicWatchedKeys
.add(assembleKey(publicConfigAppId, ConfigConsts.CLUSTER_NAME_DEFAULT, namespace));
watchedKeys.add(assembleKey(appId, ConfigConsts.CLUSTER_NAME_DEFAULT, namespace));

return publicWatchedKeys;
return watchedKeys;
}

@Override
Expand Down Expand Up @@ -154,7 +167,7 @@ public void handleMessage(String message, String channel) {
logger.info("Notification completed");
}

private void logWatchedKeysToCat(List<String> watchedKeys, String eventName) {
private void logWatchedKeysToCat(Set<String> watchedKeys, String eventName) {
for (String watchedKey : watchedKeys) {
Cat.logEvent(eventName, watchedKey);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class ConfigControllerTest {
private AppNamespaceService appNamespaceService;
private String someAppId;
private String someClusterName;
private String defaultClusterName;
private String defaultNamespaceName;
private String somePublicNamespaceName;
private String someDataCenter;
Expand All @@ -61,12 +62,14 @@ public void setUp() throws Exception {

someAppId = "1";
someClusterName = "someClusterName";
defaultClusterName = ConfigConsts.CLUSTER_NAME_DEFAULT;
defaultNamespaceName = ConfigConsts.NAMESPACE_DEFAULT;
somePublicNamespaceName = "somePublicNamespace";
someDataCenter = "someDC";
String someValidConfiguration = "{\"apollo.bar\": \"foo\"}";
String somePublicConfiguration = "{\"apollo.public.bar\": \"foo\"}";

when(someRelease.getClusterName()).thenReturn(someClusterName);
when(someRelease.getConfigurations()).thenReturn(someValidConfiguration);
when(somePublicRelease.getConfigurations()).thenReturn(somePublicConfiguration);
}
Expand Down Expand Up @@ -128,6 +131,55 @@ public void testQueryConfigWithApolloConfigNotModified() throws Exception {
verify(someResponse, times(1)).setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}

@Test
public void testQueryConfigWithDefaultClusterWithDataCenterRelease() throws Exception {
String someClientSideReleaseKey = "1";
String someServerSideNewReleaseKey = "2";
HttpServletResponse someResponse = mock(HttpServletResponse.class);

when(configService.findRelease(someAppId, someDataCenter, defaultNamespaceName))
.thenReturn(someRelease);
when(someRelease.getReleaseKey()).thenReturn(someServerSideNewReleaseKey);
when(someRelease.getClusterName()).thenReturn(someDataCenter);

ApolloConfig result = configController.queryConfig(someAppId, defaultClusterName,
defaultNamespaceName, someDataCenter, someClientSideReleaseKey,
someResponse);

verify(configService, times(1)).findRelease(someAppId, someDataCenter, defaultNamespaceName);
assertEquals(someAppId, result.getAppId());
assertEquals(someDataCenter, result.getCluster());
assertEquals(defaultNamespaceName, result.getNamespaceName());
assertEquals(someServerSideNewReleaseKey, result.getReleaseKey());
}

@Test
public void testQueryConfigWithDefaultClusterWithNoDataCenterRelease() throws Exception {
String someClientSideReleaseKey = "1";
String someServerSideNewReleaseKey = "2";
HttpServletResponse someResponse = mock(HttpServletResponse.class);

when(configService.findRelease(someAppId, someDataCenter, defaultNamespaceName))
.thenReturn(null);
when(configService.findRelease(someAppId, defaultClusterName, defaultNamespaceName))
.thenReturn(someRelease);
when(someRelease.getReleaseKey()).thenReturn(someServerSideNewReleaseKey);
when(someRelease.getClusterName()).thenReturn(defaultClusterName);

ApolloConfig result = configController.queryConfig(someAppId, defaultClusterName,
defaultNamespaceName, someDataCenter, someClientSideReleaseKey,
someResponse);

verify(configService, times(1)).findRelease(someAppId, someDataCenter, defaultNamespaceName);
verify(configService, times(1)).findRelease(someAppId, defaultClusterName, defaultNamespaceName);
assertEquals(someAppId, result.getAppId());
assertEquals(defaultClusterName, result.getCluster());
assertEquals(defaultNamespaceName, result.getNamespaceName());
assertEquals(someServerSideNewReleaseKey, result.getReleaseKey());


}

@Test
public void testQueryConfigWithAppOwnNamespace() throws Exception {
String someClientSideReleaseKey = "1";
Expand Down
Loading

0 comments on commit b04949c

Please sign in to comment.