Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature:expands grayscale publishing capabilities to support dimensio… #4013

Merged
merged 10 commits into from
Oct 9, 2021
Merged
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Apollo 1.10.0
* [feat(scripts): use bash to call openapi](https://github.com/apolloconfig/apollo/pull/3980)
* [Support search by item](https://github.com/apolloconfig/apollo/pull/3977)
* [Implement password policies to avoid weak passwords](https://github.com/apolloconfig/apollo/pull/4008)
* [Extend the gray release capability to support dimensions other than IP](https://github.com/apolloconfig/apollo/pull/4013)

------------------
All issues and pull requests are [here](https://github.com/ctripcorp/apollo/milestone/8?closed=1)
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ public String getNamespaceName() {
return namespaceName;
}

public boolean matches(String clientAppId, String clientIp) {
public boolean matches(String clientAppId, String clientIp, String clientLabel) {
for (GrayReleaseRuleItemDTO ruleItem : ruleItems) {
if (ruleItem.matches(clientAppId, clientIp)) {
if (ruleItem.matches(clientAppId, clientIp, clientLabel)) {
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ private void periodicScanRules() {
}
}

public Long findReleaseIdFromGrayReleaseRule(String clientAppId, String clientIp, String
public Long findReleaseIdFromGrayReleaseRule(String clientAppId, String clientIp, String clientLabel, String
configAppId, String configCluster, String configNamespaceName) {
String key = assembleGrayReleaseRuleKey(configAppId, configCluster, configNamespaceName);
if (!grayReleaseRuleCache.containsKey(key)) {
Expand All @@ -147,7 +147,7 @@ public Long findReleaseIdFromGrayReleaseRule(String clientAppId, String clientIp
if (rule.getBranchStatus() != NamespaceBranchStatus.ACTIVE) {
continue;
}
if (rule.matches(clientAppId, clientIp)) {
if (rule.matches(clientAppId, clientIp, clientLabel)) {
return rule.getReleaseId();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,14 @@ public void testScanGrayReleaseRules() throws Exception {

String someClientAppId = "clientAppId1";
String someClientIp = "1.1.1.1";
String someClientLabel = "myLabel";
String anotherClientAppId = "clientAppId2";
String anotherClientIp = "2.2.2.2";
String anotherClientLabel = "testLabel";

GrayReleaseRule someRule = assembleGrayReleaseRule(someAppId, someClusterName,
someNamespaceName, Lists.newArrayList(assembleRuleItem(someClientAppId, Sets.newHashSet
(someClientIp))), someReleaseId, activeBranchStatus);
(someClientIp), Sets.newHashSet(someClientLabel))), someReleaseId, activeBranchStatus);

when(bizConfig.grayReleaseRuleScanInterval()).thenReturn(30);
when(grayReleaseRuleRepository.findFirst500ByIdGreaterThanOrderByIdAsc(0L)).thenReturn(Lists
Expand All @@ -99,16 +101,18 @@ public void testScanGrayReleaseRules() throws Exception {
grayReleaseRulesHolder.afterPropertiesSet();

assertEquals(someReleaseId, grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule
(someClientAppId, someClientIp, someAppId, someClusterName, someNamespaceName));
(someClientAppId, someClientIp, anotherClientLabel, someAppId, someClusterName, someNamespaceName));
assertEquals(someReleaseId, grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule
(someClientAppId.toUpperCase(), someClientIp, someAppId.toUpperCase(), someClusterName, someNamespaceName.toUpperCase()));
(someClientAppId, anotherClientIp, someClientLabel, someAppId, someClusterName, someNamespaceName));
assertEquals(someReleaseId, grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule
(someClientAppId.toUpperCase(), someClientIp, someClientLabel, someAppId.toUpperCase(), someClusterName, someNamespaceName.toUpperCase()));
assertNull(grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule(someClientAppId,
anotherClientIp, someAppId, someClusterName, someNamespaceName));
anotherClientIp, anotherClientLabel, someAppId, someClusterName, someNamespaceName));

assertNull(grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule(anotherClientAppId,
someClientIp, someAppId, someClusterName, someNamespaceName));
someClientIp, someClientLabel, someAppId, someClusterName, someNamespaceName));
assertNull(grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule(anotherClientAppId,
anotherClientIp, someAppId, someClusterName, someNamespaceName));
anotherClientIp, anotherClientLabel, someAppId, someClusterName, someNamespaceName));

assertTrue(grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, someClientIp,
someNamespaceName));
Expand All @@ -126,7 +130,7 @@ public void testScanGrayReleaseRules() throws Exception {

GrayReleaseRule anotherRule = assembleGrayReleaseRule(someAppId, someClusterName,
someNamespaceName, Lists.newArrayList(assembleRuleItem(anotherClientAppId, Sets.newHashSet
(anotherClientIp))), someReleaseId, activeBranchStatus);
(anotherClientIp),Sets.newHashSet(anotherClientLabel))), someReleaseId, activeBranchStatus);

when(grayReleaseRuleRepository.findByAppIdAndClusterNameAndNamespaceName(someAppId,
someClusterName, someNamespaceName)).thenReturn(Lists.newArrayList(anotherRule));
Expand All @@ -136,9 +140,14 @@ public void testScanGrayReleaseRules() throws Exception {
someNamespaceName), Topics.APOLLO_RELEASE_TOPIC);

assertNull(grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule
(someClientAppId, someClientIp, someAppId, someClusterName, someNamespaceName));
(someClientAppId, someClientIp, someClientLabel, someAppId, someClusterName, someNamespaceName));
assertEquals(someReleaseId, grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule
(anotherClientAppId, anotherClientIp, someClientLabel, someAppId, someClusterName, someNamespaceName));
assertEquals(someReleaseId, grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule
(anotherClientAppId, anotherClientIp, someAppId, someClusterName, someNamespaceName));
(anotherClientAppId, someClientIp, anotherClientLabel, someAppId, someClusterName, someNamespaceName));
assertEquals(someReleaseId, grayReleaseRulesHolder.findReleaseIdFromGrayReleaseRule
(anotherClientAppId, anotherClientIp, anotherClientLabel, someAppId, someClusterName, someNamespaceName));
nobodyiam marked this conversation as resolved.
Show resolved Hide resolved


assertFalse(grayReleaseRulesHolder.hasGrayReleaseRule(someClientAppId, someClientIp,
someNamespaceName));
Expand Down Expand Up @@ -168,8 +177,8 @@ private GrayReleaseRule assembleGrayReleaseRule(String appId, String clusterName
return rule;
}

private GrayReleaseRuleItemDTO assembleRuleItem(String clientAppId, Set<String> clientIpList) {
return new GrayReleaseRuleItemDTO(clientAppId, clientIpList);
private GrayReleaseRuleItemDTO assembleRuleItem(String clientAppId, Set<String> clientIpList, Set<String> clientLabelList) {
return new GrayReleaseRuleItemDTO(clientAppId, clientIpList, clientLabelList);
}

private ReleaseMessage assembleReleaseMessage(String appId, String clusterName, String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,11 @@ String assembleQueryConfigUrl(String uri, String appId, String cluster, String n
queryParams.put("ip", queryParamEscaper.escape(localIp));
}

String label = m_configUtil.getApolloLabel();
if (!Strings.isNullOrEmpty(label)) {
queryParams.put("label", queryParamEscaper.escape(label));
}

if (remoteMessages != null) {
queryParams.put("messages", queryParamEscaper.escape(GSON.toJson(remoteMessages)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,15 @@ public String getAppId() {
return appId;
}

/**
* Get the apollo label for the current application.
*
* @return apollo Label
*/
public String getApolloLabel() {
return Foundation.app().getApolloLabel();
}

/**
* Get the access key secret for the current application.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,20 @@
*/
public class GrayReleaseRuleItemDTO {
public static final String ALL_IP = "*";
public static final String ALL_Label = "*";

private String clientAppId;
private Set<String> clientIpList;
private Set<String> clientLabelList;

public GrayReleaseRuleItemDTO(String clientAppId) {
this(clientAppId, Sets.newHashSet());
this(clientAppId, Sets.newHashSet(), Sets.newHashSet());
}

public GrayReleaseRuleItemDTO(String clientAppId, Set<String> clientIpList) {
public GrayReleaseRuleItemDTO(String clientAppId, Set<String> clientIpList, Set<String> clientLabelList) {
this.clientAppId = clientAppId;
this.clientIpList = clientIpList;
this.clientLabelList = clientLabelList;
}

public String getClientAppId() {
Expand All @@ -48,8 +51,12 @@ public Set<String> getClientIpList() {
return clientIpList;
}

public boolean matches(String clientAppId, String clientIp) {
return appIdMatches(clientAppId) && ipMatches(clientIp);
public Set<String> getClientLabelList() {
return clientLabelList;
}

public boolean matches(String clientAppId, String clientIp,String clientLabel) {
return (appIdMatches(clientAppId) && ipMatches(clientIp))||(appIdMatches(clientAppId) && labelMatches(clientLabel));
}

private boolean appIdMatches(String clientAppId) {
Expand All @@ -60,9 +67,14 @@ private boolean ipMatches(String clientIp) {
return this.clientIpList.contains(ALL_IP) || clientIpList.contains(clientIp);
}

private boolean labelMatches(String clientLabel) {
return this.clientLabelList.contains(ALL_Label) || clientLabelList.contains(clientLabel);
}

@Override
public String toString() {
return toStringHelper(this).add("clientAppId", clientAppId)
.add("clientIpList", clientIpList).toString();
.add("clientIpList", clientIpList)
.add("clientLabelList", clientLabelList).toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public ApolloConfig queryConfig(@PathVariable String appId, @PathVariable String
@RequestParam(value = "dataCenter", required = false) String dataCenter,
@RequestParam(value = "releaseKey", defaultValue = "-1") String clientSideReleaseKey,
@RequestParam(value = "ip", required = false) String clientIp,
@RequestParam(value = "label", required = false) String clientLabel,
@RequestParam(value = "messages", required = false) String messagesAsString,
HttpServletRequest request, HttpServletResponse response) throws IOException {
String originalNamespace = namespace;
Expand All @@ -101,7 +102,7 @@ public ApolloConfig queryConfig(@PathVariable String appId, @PathVariable String

String appClusterNameLoaded = clusterName;
if (!ConfigConsts.NO_APPID_PLACEHOLDER.equalsIgnoreCase(appId)) {
Release currentAppRelease = configService.loadConfig(appId, clientIp, appId, clusterName, namespace,
Release currentAppRelease = configService.loadConfig(appId, clientIp, clientLabel, appId, clusterName, namespace,
dataCenter, clientMessages);

if (currentAppRelease != null) {
Expand All @@ -113,7 +114,7 @@ public ApolloConfig queryConfig(@PathVariable String appId, @PathVariable String

//if namespace does not belong to this appId, should check if there is a public configuration
if (!namespaceBelongsToAppId(appId, namespace)) {
Release publicRelease = this.findPublicConfig(appId, clientIp, clusterName, namespace,
Release publicRelease = this.findPublicConfig(appId, clientIp, clientLabel, clusterName, namespace,
dataCenter, clientMessages);
if (Objects.nonNull(publicRelease)) {
releases.add(publicRelease);
Expand Down Expand Up @@ -173,7 +174,7 @@ private boolean namespaceBelongsToAppId(String appId, String namespaceName) {
* @param namespace the namespace
* @param dataCenter the datacenter
*/
private Release findPublicConfig(String clientAppId, String clientIp, String clusterName,
private Release findPublicConfig(String clientAppId, String clientIp, String clientLabel, String clusterName,
String namespace, String dataCenter, ApolloNotificationMessages clientMessages) {
AppNamespace appNamespace = appNamespaceService.findPublicNamespaceByName(namespace);

Expand All @@ -184,7 +185,7 @@ private Release findPublicConfig(String clientAppId, String clientIp, String clu

String publicConfigAppId = appNamespace.getAppId();

return configService.loadConfig(clientAppId, clientIp, publicConfigAppId, clusterName, namespace, dataCenter,
return configService.loadConfig(clientAppId, clientIp, clientLabel, publicConfigAppId, clusterName, namespace, dataCenter,
clientMessages);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,14 @@ public ResponseEntity<String> queryConfigAsProperties(@PathVariable String appId
@PathVariable String namespace,
@RequestParam(value = "dataCenter", required = false) String dataCenter,
@RequestParam(value = "ip", required = false) String clientIp,
@RequestParam(value = "label", required = false) String clientLabel,
HttpServletRequest request,
HttpServletResponse response)
throws IOException {

String result =
queryConfig(ConfigFileOutputFormat.PROPERTIES, appId, clusterName, namespace, dataCenter,
clientIp, request, response);
clientIp, clientLabel, request, response);

if (result == null) {
return NOT_FOUND_RESPONSE;
Expand All @@ -146,12 +147,13 @@ public ResponseEntity<String> queryConfigAsJson(@PathVariable String appId,
@PathVariable String namespace,
@RequestParam(value = "dataCenter", required = false) String dataCenter,
@RequestParam(value = "ip", required = false) String clientIp,
@RequestParam(value = "label", required = false) String clientLabel,
HttpServletRequest request,
HttpServletResponse response) throws IOException {

String result =
queryConfig(ConfigFileOutputFormat.JSON, appId, clusterName, namespace, dataCenter,
clientIp, request, response);
clientIp, clientLabel, request, response);

if (result == null) {
return NOT_FOUND_RESPONSE;
Expand All @@ -161,7 +163,7 @@ public ResponseEntity<String> queryConfigAsJson(@PathVariable String appId,
}

String queryConfig(ConfigFileOutputFormat outputFormat, String appId, String clusterName,
String namespace, String dataCenter, String clientIp,
String namespace, String dataCenter, String clientIp, String clientLabel,
HttpServletRequest request,
HttpServletResponse response) throws IOException {
//strip out .properties suffix
Expand All @@ -182,7 +184,7 @@ String queryConfig(ConfigFileOutputFormat outputFormat, String appId, String clu
//2. try to load gray release and return
if (hasGrayReleaseRule) {
Tracer.logEvent("ConfigFile.Cache.GrayRelease", cacheKey);
return loadConfig(outputFormat, appId, clusterName, namespace, dataCenter, clientIp,
return loadConfig(outputFormat, appId, clusterName, namespace, dataCenter, clientIp, clientLabel,
request, response);
}

Expand All @@ -192,7 +194,7 @@ String queryConfig(ConfigFileOutputFormat outputFormat, String appId, String clu
//4. if not exists, load from ConfigController
if (Strings.isNullOrEmpty(result)) {
Tracer.logEvent("ConfigFile.Cache.Miss", cacheKey);
result = loadConfig(outputFormat, appId, clusterName, namespace, dataCenter, clientIp,
result = loadConfig(outputFormat, appId, clusterName, namespace, dataCenter, clientIp, clientLabel,
request, response);

if (result == null) {
Expand All @@ -202,7 +204,7 @@ String queryConfig(ConfigFileOutputFormat outputFormat, String appId, String clu
//This step is mainly to avoid cache pollution
if (grayReleaseRulesHolder.hasGrayReleaseRule(appId, clientIp, namespace)) {
Tracer.logEvent("ConfigFile.Cache.GrayReleaseConflict", cacheKey);
return loadConfig(outputFormat, appId, clusterName, namespace, dataCenter, clientIp,
return loadConfig(outputFormat, appId, clusterName, namespace, dataCenter, clientIp, clientLabel,
request, response);
}

Expand All @@ -226,11 +228,11 @@ String queryConfig(ConfigFileOutputFormat outputFormat, String appId, String clu
}

private String loadConfig(ConfigFileOutputFormat outputFormat, String appId, String clusterName,
String namespace, String dataCenter, String clientIp,
String namespace, String dataCenter, String clientIp, String clientLabel,
HttpServletRequest request,
HttpServletResponse response) throws IOException {
ApolloConfig apolloConfig = configController.queryConfig(appId, clusterName, namespace,
dataCenter, "-1", clientIp, null, request, response);
dataCenter, "-1", clientIp, clientLabel, null, request, response);

if (apolloConfig == null || apolloConfig.getConfigurations() == null) {
return null;
Expand Down
Loading