This is an automated email from the ASF dual-hosted git repository.
youling1128 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/master by this push:
new afe5c88d8 [#4423] add switch to control return empty instance when
router rule not matched (#4424)
afe5c88d8 is described below
commit afe5c88d862d5b9cc5446d67a68b96106a0a42e9
Author: Alex <[email protected]>
AuthorDate: Fri Jul 26 19:48:40 2024 +0800
[#4423] add switch to control return empty instance when router rule not
matched (#4424)
---
.../consumer/src/main/resources/application.yml | 48 +++++++++++++
.../apache/servicecomb/samples/HelloWorldIT.java | 82 ++++++++++++++++++++++
.../distribute/AbstractRouterDistributor.java | 8 ++-
.../servicecomb/router/model/PolicyRuleItem.java | 11 +++
4 files changed, 148 insertions(+), 1 deletion(-)
diff --git a/demo/demo-cse-v1/consumer/src/main/resources/application.yml
b/demo/demo-cse-v1/consumer/src/main/resources/application.yml
index 3708895be..355ce5ba3 100644
--- a/demo/demo-cse-v1/consumer/src/main/resources/application.yml
+++ b/demo/demo-cse-v1/consumer/src/main/resources/application.yml
@@ -75,6 +75,54 @@ servicecomb:
- weight: 80
tags:
version: 0.0.2
+ - precedence: 4
+ emptyProtection: false
+ match:
+ headers:
+ canary:
+ exact: emptyProtectionClose100
+ route:
+ - weight: 100
+ tags:
+ version: 0.0.3
+ - precedence: 5
+ emptyProtection: false
+ match:
+ headers:
+ canary:
+ exact: emptyProtectionCloseLess100
+ route:
+ - weight: 50
+ tags:
+ version: 0.0.3
+ - precedence: 6
+ emptyProtection: false
+ match:
+ headers:
+ canary:
+ exact: emptyProtectionCloseFallback
+ route:
+ - weight: 100
+ tags:
+ version: 0.0.3
+ fallback:
+ - weight: 100
+ tags:
+ version: 0.0.1
+ - precedence: 7
+ emptyProtection: false
+ match:
+ headers:
+ canary:
+ exact: emptyProtectionClose100-2
+ route:
+ - weight: 50
+ tags:
+ version: 0.0.1
+ - weight: 50
+ tags:
+ version: 0.0.3
+
router:
type: router
diff --git
a/demo/demo-cse-v1/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java
b/demo/demo-cse-v1/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java
index 0ceb48feb..423d3b58d 100644
---
a/demo/demo-cse-v1/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java
+++
b/demo/demo-cse-v1/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java
@@ -38,6 +38,10 @@ public class HelloWorldIT implements CategorizedTestCase {
testHelloWorldNoHeader();
testHelloWorld();
testHelloWorldCanary();
+ testHelloWorldEmptyProtectionCloseWeight100();
+ testHelloWorldeEptyProtectionCloseWeightLess100();
+ testHelloWorldEmptyProtectionCloseFallback();
+ testHelloWorldEmptyProtectionCloseWeight100Two();
}
private void testHelloWorld() {
@@ -119,4 +123,82 @@ public class HelloWorldIT implements CategorizedTestCase {
double ratio = oldCount / (float) (oldCount + newCount);
TestMgr.check(Double.compare(ratio, 0.5) == 0, true);
}
+
+ private void testHelloWorldEmptyProtectionCloseWeight100() {
+ int failCount = 0;
+
+ for (int i = 0; i < 20; i++) {
+ MultiValueMap<String, String> headers = new HttpHeaders();
+ headers.add("canary", "emptyProtectionClose100");
+ HttpEntity<Object> entity = new HttpEntity<>(headers);
+ try {
+ template.exchange(Config.GATEWAY_URL + "/sayHelloCanary?name=World",
HttpMethod.GET,
+ entity, String.class);
+ } catch (Exception e) {
+ failCount++;
+ }
+ }
+
+ TestMgr.check(failCount == 20, true);
+ }
+
+ private void testHelloWorldeEptyProtectionCloseWeightLess100() {
+ int failCount = 0;
+ int succCount = 0;
+
+ for (int i = 0; i < 20; i++) {
+ MultiValueMap<String, String> headers = new HttpHeaders();
+ headers.add("canary", "emptyProtectionCloseLess100");
+ HttpEntity<Object> entity = new HttpEntity<>(headers);
+ try {
+ template.exchange(Config.GATEWAY_URL + "/sayHelloCanary?name=World",
HttpMethod.GET,
+ entity, String.class);
+ succCount++;
+ } catch (Exception e) {
+ failCount++;
+ }
+ }
+
+ TestMgr.check(succCount == 20, true);
+ }
+
+ private void testHelloWorldEmptyProtectionCloseFallback() {
+ int failCount = 0;
+ int succCount = 0;
+
+ for (int i = 0; i < 20; i++) {
+ MultiValueMap<String, String> headers = new HttpHeaders();
+ headers.add("canary", "emptyProtectionCloseFallback");
+ HttpEntity<Object> entity = new HttpEntity<>(headers);
+ try {
+ template.exchange(Config.GATEWAY_URL + "/sayHelloCanary?name=World",
HttpMethod.GET,
+ entity, String.class);
+ succCount++;
+ } catch (Exception e) {
+ failCount++;
+ }
+ }
+
+ TestMgr.check(succCount == 20, true);
+ }
+
+ private void testHelloWorldEmptyProtectionCloseWeight100Two() {
+ int failCount = 0;
+ int succCount = 0;
+
+ for (int i = 0; i < 20; i++) {
+ MultiValueMap<String, String> headers = new HttpHeaders();
+ headers.add("canary", "emptyProtectionClose100-2");
+ HttpEntity<Object> entity = new HttpEntity<>(headers);
+ try {
+ template.exchange(Config.GATEWAY_URL + "/sayHelloCanary?name=World",
HttpMethod.GET,
+ entity, String.class);
+ succCount++;
+ } catch (Exception e) {
+ failCount++;
+ }
+ }
+
+ TestMgr.check(failCount == succCount, true);
+ }
}
diff --git
a/governance/src/main/java/org/apache/servicecomb/router/distribute/AbstractRouterDistributor.java
b/governance/src/main/java/org/apache/servicecomb/router/distribute/AbstractRouterDistributor.java
index 8e5b1af1f..c34ad909a 100644
---
a/governance/src/main/java/org/apache/servicecomb/router/distribute/AbstractRouterDistributor.java
+++
b/governance/src/main/java/org/apache/servicecomb/router/distribute/AbstractRouterDistributor.java
@@ -17,6 +17,7 @@
package org.apache.servicecomb.router.distribute;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -95,7 +96,12 @@ public abstract class AbstractRouterDistributor<INSTANCE>
implements
if (invokeRule.isWeightLess() && !unSetTagInstances.isEmpty()) {
return unSetTagInstances;
}
- return list;
+ if (invokeRule.isEmptyProtection()) {
+ return list;
+ }
+
+ // weight set 100 but not matched any instance, then return empty when
emptyProtection close
+ return Collections.emptyList();
}
@Override
diff --git
a/governance/src/main/java/org/apache/servicecomb/router/model/PolicyRuleItem.java
b/governance/src/main/java/org/apache/servicecomb/router/model/PolicyRuleItem.java
index 11c95099f..fa2d285ef 100644
---
a/governance/src/main/java/org/apache/servicecomb/router/model/PolicyRuleItem.java
+++
b/governance/src/main/java/org/apache/servicecomb/router/model/PolicyRuleItem.java
@@ -46,6 +46,8 @@ public class PolicyRuleItem implements
Comparable<PolicyRuleItem> {
private Integer fallbackTotal;
+ private boolean emptyProtection = true;
+
public PolicyRuleItem() {
}
@@ -133,6 +135,14 @@ public class PolicyRuleItem implements
Comparable<PolicyRuleItem> {
this.fallbackTotal = fallbackTotal;
}
+ public boolean isEmptyProtection() {
+ return emptyProtection;
+ }
+
+ public void setEmptyProtection(boolean emptyProtection) {
+ this.emptyProtection = emptyProtection;
+ }
+
@Override
public String toString() {
return "PolicyRuleItem{" +
@@ -143,6 +153,7 @@ public class PolicyRuleItem implements
Comparable<PolicyRuleItem> {
", weightLess=" + weightLess +
", fallback=" + fallback +
", fallbackTotal=" + fallbackTotal +
+ ", emptyProtection=" + emptyProtection +
'}';
}
}