Skip to content

Commit a070aa1

Browse files
committed
transplant pull request 5138 & 5198
1 parent 7fe8f4e commit a070aa1

File tree

7 files changed

+84
-37
lines changed

7 files changed

+84
-37
lines changed

apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/grayReleaseRule/GrayReleaseRulesHolder.java

+34-8
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ public class GrayReleaseRulesHolder implements ReleaseMessageListener, Initializ
6868
private Multimap<String, GrayReleaseRuleCache> grayReleaseRuleCache;
6969
//store clientAppId+clientNamespace+ip -> ruleId map
7070
private Multimap<String, Long> reversedGrayReleaseRuleCache;
71+
//store clientAppId+clientNamespace+label -> ruleId map
72+
private Multimap<String, Long> reversedGrayReleaseRuleLabelCache;
7173
//an auto increment version to indicate the age of rules
7274
private AtomicLong loadVersion;
7375

@@ -80,6 +82,8 @@ public GrayReleaseRulesHolder(final GrayReleaseRuleRepository grayReleaseRuleRep
8082
TreeMultimap.create(String.CASE_INSENSITIVE_ORDER, Ordering.natural()));
8183
reversedGrayReleaseRuleCache = Multimaps.synchronizedSetMultimap(
8284
TreeMultimap.create(String.CASE_INSENSITIVE_ORDER, Ordering.natural()));
85+
reversedGrayReleaseRuleLabelCache = Multimaps.synchronizedSetMultimap(
86+
TreeMultimap.create(String.CASE_INSENSITIVE_ORDER, Ordering.natural()));
8387
executorService = Executors.newScheduledThreadPool(1, ApolloThreadFactory
8488
.create("GrayReleaseRulesHolder", true));
8589
}
@@ -152,15 +156,29 @@ public Long findReleaseIdFromGrayReleaseRule(String clientAppId, String clientIp
152156
}
153157

154158
/**
155-
* Check whether there are gray release rules for the clientAppId, clientIp, namespace
156-
* combination. Please note that even there are gray release rules, it doesn't mean it will always
157-
* load gray releases. Because gray release rules actually apply to one more dimension - cluster.
159+
* Check whether there are gray release rules for the clientAppId, clientIp, clientLabel, namespace combination.
160+
* Please note that even there are gray release rules, it doesn't mean it will always load gray
161+
* releases. Because gray release rules actually apply to one more dimension - cluster.
158162
*/
159-
public boolean hasGrayReleaseRule(String clientAppId, String clientIp, String namespaceName) {
160-
return reversedGrayReleaseRuleCache.containsKey(assembleReversedGrayReleaseRuleKey(clientAppId,
163+
public boolean hasGrayReleaseRule(String clientAppId, String clientIp, String clientLabel,
164+
String namespaceName) {
165+
// check ip gray rule
166+
if (reversedGrayReleaseRuleCache.containsKey(assembleReversedGrayReleaseRuleKey(clientAppId,
161167
namespaceName, clientIp)) || reversedGrayReleaseRuleCache.containsKey
162168
(assembleReversedGrayReleaseRuleKey(clientAppId, namespaceName, GrayReleaseRuleItemDTO
163-
.ALL_IP));
169+
.ALL_IP))) {
170+
return true;
171+
}
172+
// check label gray rule
173+
if (!Strings.isNullOrEmpty(clientLabel) &&
174+
(reversedGrayReleaseRuleLabelCache.containsKey(
175+
assembleReversedGrayReleaseRuleKey(clientAppId, namespaceName, clientLabel)) ||
176+
reversedGrayReleaseRuleLabelCache.containsKey(
177+
assembleReversedGrayReleaseRuleKey(clientAppId, namespaceName,
178+
GrayReleaseRuleItemDTO.ALL_Label)))) {
179+
return true;
180+
}
181+
return false;
164182
}
165183

166184
private void scanGrayReleaseRules() {
@@ -232,6 +250,10 @@ private void addCache(String key, GrayReleaseRuleCache ruleCache) {
232250
reversedGrayReleaseRuleCache.put(assembleReversedGrayReleaseRuleKey(ruleItemDTO
233251
.getClientAppId(), ruleCache.getNamespaceName(), clientIp), ruleCache.getRuleId());
234252
}
253+
for (String label : ruleItemDTO.getClientLabelList()) {
254+
reversedGrayReleaseRuleLabelCache.put(assembleReversedGrayReleaseRuleKey(ruleItemDTO
255+
.getClientAppId(), ruleCache.getNamespaceName(), label), ruleCache.getRuleId());
256+
}
235257
}
236258
}
237259
grayReleaseRuleCache.put(key, ruleCache);
@@ -244,6 +266,10 @@ private void removeCache(String key, GrayReleaseRuleCache ruleCache) {
244266
reversedGrayReleaseRuleCache.remove(assembleReversedGrayReleaseRuleKey(ruleItemDTO
245267
.getClientAppId(), ruleCache.getNamespaceName(), clientIp), ruleCache.getRuleId());
246268
}
269+
for (String label : ruleItemDTO.getClientLabelList()) {
270+
reversedGrayReleaseRuleLabelCache.remove(assembleReversedGrayReleaseRuleKey(ruleItemDTO
271+
.getClientAppId(), ruleCache.getNamespaceName(), label), ruleCache.getRuleId());
272+
}
247273
}
248274
}
249275

@@ -282,8 +308,8 @@ private String assembleGrayReleaseRuleKey(String configAppId, String configClust
282308
}
283309

284310
private String assembleReversedGrayReleaseRuleKey(String clientAppId, String
285-
clientNamespaceName, String clientIp) {
286-
return STRING_JOINER.join(clientAppId, clientNamespaceName, clientIp);
311+
clientNamespaceName, String clientIpOrLabel) {
312+
return STRING_JOINER.join(clientAppId, clientNamespaceName, clientIpOrLabel);
287313
}
288314

289315
}

apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/registry/configuration/support/ApolloServiceRegistryProperties.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
package com.ctrip.framework.apollo.biz.registry.configuration.support;
1818

1919
import com.ctrip.framework.apollo.biz.registry.ServiceInstance;
20+
import com.google.common.base.Strings;
2021
import java.net.URI;
2122
import java.util.HashMap;
2223
import java.util.Map;
2324
import javax.annotation.PostConstruct;
25+
import javax.servlet.ServletContext;
2426
import org.springframework.beans.factory.annotation.Autowired;
2527
import org.springframework.boot.context.properties.ConfigurationProperties;
2628
import org.springframework.cloud.commons.util.InetUtils;
@@ -72,6 +74,9 @@ public class ApolloServiceRegistryProperties implements ServiceInstance {
7274
@Autowired
7375
private InetUtils inetUtils;
7476

77+
@Autowired
78+
private ServletContext servletContext;
79+
7580
/**
7681
* if user doesn't config, then resolve them on the runtime.
7782
*/
@@ -84,7 +89,9 @@ public void postConstruct() {
8489
if (this.uri == null) {
8590
String host = this.inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
8691
Integer port = propertyResolver.getRequiredProperty("server.port", Integer.class);
87-
String uriString = "http://" + host + ":" + port + "/";
92+
String contextPath = Strings.isNullOrEmpty(this.servletContext.getContextPath()) ? "/"
93+
: this.servletContext.getContextPath();
94+
String uriString = "http://" + host + ":" + port + contextPath;
8895
this.uri = URI.create(uriString);
8996
}
9097
}

apollo-biz/src/test/java/com/ctrip/framework/apollo/biz/grayReleaseRule/GrayReleaseRulesHolderTest.java

+33-19
Original file line numberDiff line numberDiff line change
@@ -109,19 +109,29 @@ public void testScanGrayReleaseRules() throws Exception {
109109
assertNull(grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule(anotherClientAppId,
110110
anotherClientIp, anotherClientLabel, someAppId, someClusterName, someNamespaceName));
111111

112-
assertTrue(grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, someClientIp,
113-
someNamespaceName));
114-
assertTrue(grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId.toUpperCase(), someClientIp,
115-
someNamespaceName.toUpperCase()));
116-
assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, anotherClientIp,
117-
someNamespaceName));
118-
assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, someClientIp,
119-
anotherNamespaceName));
112+
assertTrue(
113+
grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, someClientIp, someClientLabel,
114+
someNamespaceName));
115+
assertTrue(
116+
grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId.toUpperCase(), someClientIp,
117+
someClientLabel, someNamespaceName.toUpperCase()));
118+
assertTrue(
119+
grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, anotherClientIp, someClientLabel,
120+
someNamespaceName));
121+
assertTrue(
122+
grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId.toUpperCase(), anotherClientIp,
123+
someClientLabel, someNamespaceName.toUpperCase()));
124+
assertFalse(
125+
grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, anotherClientIp,
126+
anotherClientLabel, someNamespaceName));
127+
assertFalse(
128+
grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, someClientIp, someClientLabel,
129+
anotherNamespaceName));
120130

121131
assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(anotherClientAppId, anotherClientIp,
122-
someNamespaceName));
132+
anotherClientLabel, someNamespaceName));
123133
assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(anotherClientAppId, anotherClientIp,
124-
anotherNamespaceName));
134+
anotherClientLabel, anotherNamespaceName));
125135

126136
GrayReleaseRule anotherRule = assembleGrayReleaseRule(someAppId, someClusterName,
127137
someNamespaceName, Lists.newArrayList(assembleRuleItem(anotherClientAppId, Sets.newHashSet
@@ -143,18 +153,22 @@ public void testScanGrayReleaseRules() throws Exception {
143153
assertEquals(someReleaseId, grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule
144154
(anotherClientAppId, anotherClientIp, anotherClientLabel, someAppId, someClusterName, someNamespaceName));
145155

156+
assertFalse(
157+
grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, someClientIp, someClientLabel, someNamespaceName));
158+
assertFalse(
159+
grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, someClientIp, someClientLabel, anotherNamespaceName));
146160

147-
assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, someClientIp,
148-
someNamespaceName));
149-
assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, someClientIp,
150-
anotherNamespaceName));
151-
152161
assertTrue(grayReleaseRulesHolder.hasGrayReleaseRule(anotherClientAppId, anotherClientIp,
153-
someNamespaceName));
154-
assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(anotherClientAppId, someClientIp,
155-
someNamespaceName));
162+
anotherClientLabel, someNamespaceName));
163+
assertTrue(grayReleaseRulesHolder.hasGrayReleaseRule(anotherClientAppId, anotherClientIp,
164+
someClientLabel, someNamespaceName));
165+
assertTrue(grayReleaseRulesHolder.hasGrayReleaseRule(anotherClientAppId, someClientIp,
166+
anotherClientLabel, someNamespaceName));
167+
assertFalse(
168+
grayReleaseRulesHolder.hasGrayReleaseRule(anotherClientAppId, someClientIp, someClientLabel,
169+
someNamespaceName));
156170
assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(anotherClientAppId, anotherClientIp,
157-
anotherNamespaceName));
171+
anotherClientLabel, anotherNamespaceName));
158172
}
159173

160174
private GrayReleaseRule assembleGrayReleaseRule(String appId, String clusterName, String

apollo-configservice/src/main/java/com/ctrip/framework/apollo/configservice/controller/ConfigFileController.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ String queryConfig(ConfigFileOutputFormat outputFormat, String appId, String clu
175175

176176
//1. check whether this client has gray release rules
177177
boolean hasGrayReleaseRule = grayReleaseRulesHolder.hasGrayReleaseRule(appId, clientIp,
178-
namespace);
178+
clientLabel, namespace);
179179

180180
String cacheKey = assembleCacheKey(outputFormat, appId, clusterName, namespace, dataCenter);
181181

@@ -200,7 +200,7 @@ String queryConfig(ConfigFileOutputFormat outputFormat, String appId, String clu
200200
}
201201
//5. Double check if this client needs to load gray release, if yes, load from db again
202202
//This step is mainly to avoid cache pollution
203-
if (grayReleaseRulesHolder.hasGrayReleaseRule(appId, clientIp, namespace)) {
203+
if (grayReleaseRulesHolder.hasGrayReleaseRule(appId, clientIp, clientLabel, namespace)) {
204204
Tracer.logEvent("ConfigFile.Cache.GrayReleaseConflict", cacheKey);
205205
return loadConfig(outputFormat, appId, clusterName, namespace, dataCenter, clientIp, clientLabel,
206206
request, response);

apollo-configservice/src/test/java/com/ctrip/framework/apollo/configservice/controller/ConfigFileControllerTest.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ public void setUp() throws Exception {
9595

9696
when(namespaceUtil.filterNamespaceName(someNamespace)).thenReturn(someNamespace);
9797
when(namespaceUtil.normalizeNamespace(someAppId, someNamespace)).thenReturn(someNamespace);
98-
when(grayReleaseRulesHolder.hasGrayReleaseRule(anyString(), anyString(), anyString()))
99-
.thenReturn(false);
98+
when(grayReleaseRulesHolder.hasGrayReleaseRule(anyString(), anyString(), anyString(),
99+
anyString())).thenReturn(false);
100100

101101
watchedKeys2CacheKey =
102102
(Multimap<String, String>) ReflectionTestUtils
@@ -199,8 +199,8 @@ public void testQueryConfigWithGrayRelease() throws Exception {
199199
Map<String, String> configurations =
200200
ImmutableMap.of(someKey, someValue);
201201

202-
when(grayReleaseRulesHolder.hasGrayReleaseRule(someAppId, someClientIp, someNamespace))
203-
.thenReturn(true);
202+
when(grayReleaseRulesHolder.hasGrayReleaseRule(someAppId, someClientIp, someClientLabel,
203+
someNamespace)).thenReturn(true);
204204

205205
ApolloConfig someApolloConfig = mock(ApolloConfig.class);
206206
when(someApolloConfig.getConfigurations()).thenReturn(configurations);

apollo-portal/src/main/resources/static/scripts/controller/ConfigExportController.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ config_export_module.controller('ConfigExportController',
6363
}
6464

6565
var selectedEnvStr = selectedEnvs.join(",");
66-
$window.location.href = '/configs/export?envs=' + selectedEnvStr;
66+
$window.location.href = AppUtil.prefixPath() + '/configs/export?envs=' + selectedEnvStr;
6767

6868
toastr.success($translate.instant('ConfigExport.ExportSuccess'));
6969
};
@@ -93,7 +93,7 @@ config_export_module.controller('ConfigExportController',
9393
form.append('file', file);
9494
$http({
9595
method: 'POST',
96-
url: '/configs/import?envs=' + selectedEnvStr + "&conflictAction="
96+
url: AppUtil.prefixPath() + '/configs/import?envs=' + selectedEnvStr + "&conflictAction="
9797
+ $scope.conflictAction,
9898
data: form,
9999
headers: {'Content-Type': undefined},

apollo-portal/src/main/resources/static/scripts/directive/import-namespace-modal-directive.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ function importNamespaceModalDirective($window, $q, $translate, $http, toastr, A
5454
form.append('file', file);
5555
$http({
5656
method: 'POST',
57-
url: '/apps/' + toImportNamespace.baseInfo.appId + '/envs/' + scope.env + '/clusters/'
57+
url: AppUtil.prefixPath() + '/apps/' + toImportNamespace.baseInfo.appId + '/envs/' + scope.env + '/clusters/'
5858
+ toImportNamespace.baseInfo.clusterName
5959
+ '/namespaces/' + toImportNamespace.baseInfo.namespaceName + "/items/import",
6060
data: form,

0 commit comments

Comments
 (0)