You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2022/07/27 13:47:41 UTC

[servicecomb-java-chassis] branch master updated: [SCB-2645] Fix route rule will throw NPE when version is empty (#3228)

This is an automated email from the ASF dual-hosted git repository.

liubao 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 356126da3 [SCB-2645] Fix route rule will throw NPE when version is empty (#3228)
356126da3 is described below

commit 356126da3581d408d76e45fe72bf01f1727bb177
Author: chenyang(一YOC一) <86...@users.noreply.github.com>
AuthorDate: Wed Jul 27 21:47:36 2022 +0800

    [SCB-2645] Fix route rule will throw NPE when version is empty (#3228)
---
 .../distribute/AbstractRouterDistributor.java      |  3 +
 .../apache/servicecomb/router/model/RouteItem.java |  2 +-
 .../router/distribute/DistributeTest.java          | 95 ++++++++++++++++++++++
 governance/src/test/resources/application.yaml     | 28 +++++++
 4 files changed, 127 insertions(+), 1 deletion(-)

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 500812b37..d3f8f7640 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
@@ -116,6 +116,9 @@ public abstract class AbstractRouterDistributor<T, E> implements
         TagItem targetTag = null;
         int maxMatch = 0;
         for (RouteItem entry : invokeRule.getRoute()) {
+          if (entry.getTagitem() == null){
+            continue;
+          }
           int nowMatch = entry.getTagitem().matchNum(tagItem);
           if (nowMatch > maxMatch) {
             maxMatch = nowMatch;
diff --git a/governance/src/main/java/org/apache/servicecomb/router/model/RouteItem.java b/governance/src/main/java/org/apache/servicecomb/router/model/RouteItem.java
index e48d4ee44..f2017a923 100644
--- a/governance/src/main/java/org/apache/servicecomb/router/model/RouteItem.java
+++ b/governance/src/main/java/org/apache/servicecomb/router/model/RouteItem.java
@@ -36,7 +36,7 @@ public class RouteItem implements Comparable<RouteItem> {
 
 
   public void initTagItem() {
-    if (tags != null && tags.containsKey("version")) {
+    if (tags != null) {
       tagitem = new TagItem(tags);
     }
   }
diff --git a/governance/src/test/java/org/apache/servicecomb/router/distribute/DistributeTest.java b/governance/src/test/java/org/apache/servicecomb/router/distribute/DistributeTest.java
new file mode 100644
index 000000000..e26e4f056
--- /dev/null
+++ b/governance/src/test/java/org/apache/servicecomb/router/distribute/DistributeTest.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.router.distribute;
+
+import org.apache.servicecomb.router.RouterFilter;
+import org.apache.servicecomb.router.ServiceIns;
+import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+@RunWith(SpringRunner.class)
+@ContextConfiguration(locations = "classpath:META-INF/spring/*.xml", initializers = ConfigDataApplicationContextInitializer.class)
+public class DistributeTest {
+  private static final String TARGET_SERVICE_NAME = "test_server1";
+
+  private RouterFilter routerFilter;
+
+  private RouterDistributor<ServiceIns, ServiceIns> routerDistributor;
+
+  @Autowired
+  public void setRouterFilter(RouterFilter routerFilter) {
+    this.routerFilter = routerFilter;
+  }
+
+  @Autowired
+  public void setRouterDistributor(RouterDistributor<ServiceIns, ServiceIns> routerDistributor) {
+    this.routerDistributor = routerDistributor;
+  }
+
+  @Test
+  public void testDistribute() {
+    List<ServiceIns> list = initServiceList();
+    HashMap<String, String> header = new HashMap<>();
+    List<ServiceIns> listOfServers = routerFilter
+        .getFilteredListOfServers(list, TARGET_SERVICE_NAME, header, routerDistributor);
+    Assertions.assertNotNull(listOfServers);
+    for (ServiceIns server : listOfServers) {
+      Assertions.assertEquals(TARGET_SERVICE_NAME, server.getServerName());
+    }
+    int serverNum1 = 0;
+    int serverNum2 = 0;
+
+    for (int i = 0; i < 10; i++) {
+      List<ServiceIns> serverList = routerFilter
+          .getFilteredListOfServers(list, TARGET_SERVICE_NAME, header, routerDistributor);
+      for (ServiceIns serviceIns : serverList) {
+        if ("01".equals(serviceIns.getId())) {
+          serverNum1++;
+        } else if ("02".equals(serviceIns.getId())) {
+          serverNum2++;
+        }
+      }
+    }
+    boolean flag = false;
+    if (Math.round(serverNum2 * 1.0 / serverNum1) == 4) {
+      flag = true;
+    }
+    Assertions.assertTrue(flag);
+  }
+
+  List<ServiceIns> initServiceList() {
+    ServiceIns serviceIns1 = new ServiceIns("01", "test_server1");
+    ServiceIns serviceIns2 = new ServiceIns("02", "test_server1");
+    serviceIns1.setVersion("1.0");
+    serviceIns2.setVersion("2.0");
+    serviceIns1.addTags("x-group", "red");
+    serviceIns2.addTags("x-group", "green");
+    List<ServiceIns> list = new ArrayList<>();
+    list.add(serviceIns1);
+    list.add(serviceIns2);
+    return list;
+  }
+}
diff --git a/governance/src/test/resources/application.yaml b/governance/src/test/resources/application.yaml
index d4cf7575d..e5c0842e6 100644
--- a/governance/src/test/resources/application.yaml
+++ b/governance/src/test/resources/application.yaml
@@ -144,3 +144,31 @@ servicecomb:
     wrongIngored: |
       delayTime: -1
       type: ERROR
+
+  routeRule:
+    test_server1: |                              # 服务名
+      - precedence: 1                        # 优先级,数字越大,优先级越高。
+        match:                               # 请求匹配规则。0..N个,不配置表示匹配。
+          headers:                           # header 匹配
+            region:                          # 如果配置了多个 header,那么所有的 header 规则都必须和请求匹配
+              exact: 'providerRegion'
+              caseInsensitive: false         # 不区分大小写
+            type:
+              regex: gray_[a-z]+             # java 正则表达式匹配
+              caseInsensitive: true          # 区分大小写
+        route:                               # 路由规则
+          - weight: 20                       # 权重值
+            tags:
+              version: 1.0.0                 # 实例标记。满足标记条件的实例放到这一组。
+          - weight: 80                       # 权重值
+            tags:
+              version: 2.0.0                 # 实例标记。满足标记条件的实例放到这一组。
+
+      - precedence: 2
+        route:
+          - weight: 20
+            tags:
+              x-group: red
+          - weight: 80
+            tags:
+              x-group: green