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

liubao pushed a commit to branch 1.3.x
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git

commit ef6895ef508b1fbd00d40e8cd92a1e51cd0bec04
Author: bao liu <[email protected]>
AuthorDate: Tue Nov 26 10:47:28 2019 +0800

    [SCB-1616]refactor edge dispatcher to make them more extensible (#1406)
---
 .../edge/core/DefaultEdgeDispatcher.java           |  4 +-
 .../edge/core/URLMappedConfigurationItem.java      | 72 ++++++++++++++++
 .../edge/core/URLMappedConfigurationLoader.java    | 83 +++++++++++++++++++
 .../edge/core/URLMappedEdgeDispatcher.java         | 95 +++++-----------------
 .../edge/core/TestURLMappedEdgeDispatcher.java     | 21 +++--
 .../transport/rest/vertx/VertxRestDispatcher.java  | 16 +++-
 6 files changed, 200 insertions(+), 91 deletions(-)

diff --git 
a/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/DefaultEdgeDispatcher.java
 
b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/DefaultEdgeDispatcher.java
index 0d195c6..19f9f65 100644
--- 
a/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/DefaultEdgeDispatcher.java
+++ 
b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/DefaultEdgeDispatcher.java
@@ -30,6 +30,8 @@ import io.vertx.ext.web.RoutingContext;
 public class DefaultEdgeDispatcher extends AbstractEdgeDispatcher {
   private static final String KEY_ENABLED = 
"servicecomb.http.dispatcher.edge.default.enabled";
 
+  private static final String KEY_ORDER = 
"servicecomb.http.dispatcher.edge.default.order";
+
   private static final String KEY_PREFIX = 
"servicecomb.http.dispatcher.edge.default.prefix";
 
   private static final String KEY_WITH_VERSION = 
"servicecomb.http.dispatcher.edge.default.withVersion";
@@ -46,7 +48,7 @@ public class DefaultEdgeDispatcher extends 
AbstractEdgeDispatcher {
 
   @Override
   public int getOrder() {
-    return 20000;
+    return DynamicPropertyFactory.getInstance().getIntProperty(KEY_ORDER, 
20_000).get();
   }
 
   @Override
diff --git 
a/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/URLMappedConfigurationItem.java
 
b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/URLMappedConfigurationItem.java
new file mode 100644
index 0000000..2fa3846
--- /dev/null
+++ 
b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/URLMappedConfigurationItem.java
@@ -0,0 +1,72 @@
+/*
+ * 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.edge.core;
+
+import java.util.regex.Pattern;
+
+public class URLMappedConfigurationItem {
+  private String microserviceName;
+
+  private String versionRule;
+
+  private int prefixSegmentCount;
+
+  private Pattern pattern;
+
+  private String stringPattern;
+
+  public String getMicroserviceName() {
+    return microserviceName;
+  }
+
+  public void setMicroserviceName(String microserviceName) {
+    this.microserviceName = microserviceName;
+  }
+
+  public String getVersionRule() {
+    return versionRule;
+  }
+
+  public void setVersionRule(String versionRule) {
+    this.versionRule = versionRule;
+  }
+
+  public int getPrefixSegmentCount() {
+    return prefixSegmentCount;
+  }
+
+  public void setPrefixSegmentCount(int prefixSegmentCount) {
+    this.prefixSegmentCount = prefixSegmentCount;
+  }
+
+  public Pattern getPattern() {
+    return pattern;
+  }
+
+  public void setPattern(Pattern pattern) {
+    this.pattern = pattern;
+  }
+
+  public String getStringPattern() {
+    return stringPattern;
+  }
+
+  public void setStringPattern(String stringPattern) {
+    this.stringPattern = stringPattern;
+  }
+}
diff --git 
a/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/URLMappedConfigurationLoader.java
 
b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/URLMappedConfigurationLoader.java
new file mode 100644
index 0000000..a6f7522
--- /dev/null
+++ 
b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/URLMappedConfigurationLoader.java
@@ -0,0 +1,83 @@
+/*
+ * 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.edge.core;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.netflix.config.ConcurrentCompositeConfiguration;
+import com.netflix.config.DynamicPropertyFactory;
+
+public class URLMappedConfigurationLoader {
+  private static final Logger LOG = 
LoggerFactory.getLogger(URLMappedConfigurationLoader.class);
+
+  private static final String KEY_MAPPING_PATH = ".path";
+
+  private static final String KEY_MAPPING_SERVICE_NAME = 
"%s.%s.microserviceName";
+
+  private static final String KEY_MAPPING_VERSION_RULE = "%s.%s.versionRule";
+
+  private static final String KEY_MAPPING_PREFIX_SEGMENT_COUNT = 
"%s.%s.prefixSegmentCount";
+
+  public static Map<String, URLMappedConfigurationItem> loadConfigurations(
+      ConcurrentCompositeConfiguration config, String configPrefix) {
+    Map<String, URLMappedConfigurationItem> configurations = new HashMap<>();
+    Iterator<String> configsItems = config.getKeys(configPrefix);
+    while (configsItems.hasNext()) {
+      String pathKey = configsItems.next();
+      if (pathKey.endsWith(KEY_MAPPING_PATH)) {
+        URLMappedConfigurationItem configurationItem = new 
URLMappedConfigurationItem();
+        String pattern = DynamicPropertyFactory.getInstance()
+            .getStringProperty(pathKey, null).get();
+        if (StringUtils.isEmpty(pattern)) {
+          continue;
+        }
+        configurationItem.setPattern(Pattern.compile(pattern));
+        configurationItem.setStringPattern(pattern);
+        String pathKeyItem = pathKey
+            .substring(configPrefix.length() + 1, pathKey.length() - 
KEY_MAPPING_PATH.length());
+        
configurationItem.setMicroserviceName(DynamicPropertyFactory.getInstance()
+            .getStringProperty(String.format(KEY_MAPPING_SERVICE_NAME, 
configPrefix, pathKeyItem), null).get());
+        if (StringUtils.isEmpty(configurationItem.getMicroserviceName())) {
+          continue;
+        }
+        
configurationItem.setPrefixSegmentCount(DynamicPropertyFactory.getInstance()
+            .getIntProperty(String.format(KEY_MAPPING_PREFIX_SEGMENT_COUNT, 
configPrefix, pathKeyItem), 0).get());
+        configurationItem.setVersionRule(DynamicPropertyFactory.getInstance()
+            .getStringProperty(String.format(KEY_MAPPING_VERSION_RULE, 
configPrefix, pathKeyItem), "0.0.0+").get());
+        configurations.put(pathKeyItem, configurationItem);
+      }
+    }
+    logConfigurations(configurations);
+    return configurations;
+  }
+
+  private static void logConfigurations(Map<String, 
URLMappedConfigurationItem> configurations) {
+    configurations.entrySet().forEach(stringConfigurationItemEntry -> {
+      URLMappedConfigurationItem item = 
stringConfigurationItemEntry.getValue();
+      LOG.info("config item: key=" + stringConfigurationItemEntry.getKey() + 
";pattern=" + item.getStringPattern()
+          + ";service=" + item.getMicroserviceName() + ";versionRule=" + 
item.getVersionRule());
+    });
+  }
+}
diff --git 
a/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/URLMappedEdgeDispatcher.java
 
b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/URLMappedEdgeDispatcher.java
index c734b40..31d6936 100644
--- 
a/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/URLMappedEdgeDispatcher.java
+++ 
b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/URLMappedEdgeDispatcher.java
@@ -18,11 +18,8 @@
 package org.apache.servicecomb.edge.core;
 
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
-import java.util.regex.Pattern;
 
-import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,35 +33,19 @@ import io.vertx.ext.web.RoutingContext;
  * Provide a URL mapping based dispatcher. Users configure witch URL patterns 
dispatch to a target service.
  */
 public class URLMappedEdgeDispatcher extends AbstractEdgeDispatcher {
-  class ConfigurationItem {
-    String microserviceName;
-
-    String versionRule;
-
-    int prefixSegmentCount;
-
-    Pattern pattern;
-
-    String stringPattern;
-  }
-
   private static final Logger LOG = 
LoggerFactory.getLogger(URLMappedEdgeDispatcher.class);
 
   private static final String PATTERN_ANY = "/(.*)";
 
-  private static final String KEY_ENABLED = 
"servicecomb.http.dispatcher.edge.url.enabled";
-
-  private static final String KEY_MAPPING_PREIX = 
"servicecomb.http.dispatcher.edge.url.mappings";
-
-  private static final String KEY_MAPPING_PATH = ".path";
+  private static final String KEY_ORDER = 
"servicecomb.http.dispatcher.edge.url.order";
 
-  private static final String KEY_MAPPING_SERVICE_NAME = 
"servicecomb.http.dispatcher.edge.url.mappings.%s.microserviceName";
+  private static final String KEY_ENABLED = 
"servicecomb.http.dispatcher.edge.url.enabled";
 
-  private static final String KEY_MAPPING_VERSION_RULE = 
"servicecomb.http.dispatcher.edge.url.mappings.%s.versionRule";
+  private static final String KEY_PATTERN = 
"servicecomb.http.dispatcher.edge.url.pattern";
 
-  private static final String KEY_MAPPING_PREFIX_SEGMENT_COUNT = 
"servicecomb.http.dispatcher.edge.url.mappings.%s.prefixSegmentCount";
+  private static final String KEY_MAPPING_PREIX = 
"servicecomb.http.dispatcher.edge.url.mappings";
 
-  private Map<String, ConfigurationItem> configurations = new HashMap<>();
+  private Map<String, URLMappedConfigurationItem> configurations = new 
HashMap<>();
 
   public URLMappedEdgeDispatcher() {
     if (this.enabled()) {
@@ -74,7 +55,7 @@ public class URLMappedEdgeDispatcher extends 
AbstractEdgeDispatcher {
 
   @Override
   public int getOrder() {
-    return 30000;
+    return DynamicPropertyFactory.getInstance().getIntProperty(KEY_ORDER, 
30_000).get();
   }
 
   @Override
@@ -85,82 +66,44 @@ public class URLMappedEdgeDispatcher extends 
AbstractEdgeDispatcher {
   @Override
   public void init(Router router) {
     // cookies handler are enabled by default start from 3.8.3
-    router.routeWithRegex(PATTERN_ANY).handler(createBodyHandler());
-    
router.routeWithRegex(PATTERN_ANY).failureHandler(this::onFailure).handler(this::onRequest);
+    String pattern = 
DynamicPropertyFactory.getInstance().getStringProperty(KEY_PATTERN, 
PATTERN_ANY).get();
+    router.routeWithRegex(pattern).handler(createBodyHandler());
+    
router.routeWithRegex(pattern).failureHandler(this::onFailure).handler(this::onRequest);
   }
 
   private void loadConfigurations() {
     ConcurrentCompositeConfiguration config = 
(ConcurrentCompositeConfiguration) DynamicPropertyFactory
         .getBackingConfigurationSource();
-    loadConfigurations(config);
+    configurations = URLMappedConfigurationLoader.loadConfigurations(config, 
KEY_MAPPING_PREIX);
     config.addConfigurationListener(event -> {
       if (event.getPropertyName().startsWith(KEY_MAPPING_PREIX)) {
         LOG.info("Map rule have been changed. Reload configurations. Event=" + 
event.getType());
-        loadConfigurations(config);
+        configurations = 
URLMappedConfigurationLoader.loadConfigurations(config, KEY_MAPPING_PREIX);
       }
     });
   }
 
-  private void loadConfigurations(ConcurrentCompositeConfiguration config) {
-    Map<String, ConfigurationItem> configurations = new HashMap<>();
-    Iterator<String> configsItems = config.getKeys(KEY_MAPPING_PREIX);
-    while (configsItems.hasNext()) {
-      String pathKey = configsItems.next();
-      if (pathKey.endsWith(KEY_MAPPING_PATH)) {
-        ConfigurationItem configurationItem = new ConfigurationItem();
-        String pattern = DynamicPropertyFactory.getInstance()
-            .getStringProperty(pathKey, null).get();
-        if (StringUtils.isEmpty(pattern)) {
-          continue;
-        }
-        configurationItem.pattern = Pattern.compile(pattern);
-        configurationItem.stringPattern = pattern;
-        String pathKeyItem = pathKey
-            .substring(KEY_MAPPING_PREIX.length() + 1, pathKey.length() - 
KEY_MAPPING_PATH.length());
-        configurationItem.microserviceName = 
DynamicPropertyFactory.getInstance()
-            .getStringProperty(String.format(KEY_MAPPING_SERVICE_NAME, 
pathKeyItem), null).get();
-        if (StringUtils.isEmpty(configurationItem.microserviceName)) {
-          continue;
-        }
-        configurationItem.prefixSegmentCount = 
DynamicPropertyFactory.getInstance()
-            .getIntProperty(String.format(KEY_MAPPING_PREFIX_SEGMENT_COUNT, 
pathKeyItem), 0).get();
-        configurationItem.versionRule = DynamicPropertyFactory.getInstance()
-            .getStringProperty(String.format(KEY_MAPPING_VERSION_RULE, 
pathKeyItem), "0.0.0+").get();
-        configurations.put(pathKeyItem, configurationItem);
-      }
-    }
-    this.configurations = configurations;
-    logConfigurations();
-  }
-
-  private void logConfigurations() {
-    configurations.entrySet().forEach(stringConfigurationItemEntry -> {
-      ConfigurationItem item = stringConfigurationItemEntry.getValue();
-      LOG.info("config item: key=" + stringConfigurationItemEntry.getKey() + 
";pattern=" + item.stringPattern
-          + ";service=" + item.microserviceName + ";versionRule=" + 
item.versionRule);
-    });
-  }
 
   protected void onRequest(RoutingContext context) {
-    ConfigurationItem configurationItem = 
findConfigurationItem(context.request().path());
+    URLMappedConfigurationItem configurationItem = 
findConfigurationItem(context.request().path());
     if (configurationItem == null) {
       context.next();
       return;
     }
 
-    String path = Utils.findActualPath(context.request().path(), 
configurationItem.prefixSegmentCount);
+    String path = Utils.findActualPath(context.request().path(), 
configurationItem.getPrefixSegmentCount());
 
     EdgeInvocation edgeInvocation = createEdgeInvocation();
-    if (configurationItem.versionRule != null) {
-      edgeInvocation.setVersionRule(configurationItem.versionRule);
+    if (configurationItem.getVersionRule() != null) {
+      edgeInvocation.setVersionRule(configurationItem.getVersionRule());
     }
-    edgeInvocation.init(configurationItem.microserviceName, context, path, 
httpServerFilters);
+    edgeInvocation.init(configurationItem.getMicroserviceName(), context, 
path, httpServerFilters);
     edgeInvocation.edgeInvoke();
   }
 
-  private ConfigurationItem findConfigurationItem(String path) {
-    for (ConfigurationItem item : configurations.values()) {
-      if (item.pattern.matcher(path).matches()) {
+  private URLMappedConfigurationItem findConfigurationItem(String path) {
+    for (URLMappedConfigurationItem item : configurations.values()) {
+      if (item.getPattern().matcher(path).matches()) {
         return item;
       }
     }
diff --git 
a/edge/edge-core/src/test/java/org/apache/servicecomb/edge/core/TestURLMappedEdgeDispatcher.java
 
b/edge/edge-core/src/test/java/org/apache/servicecomb/edge/core/TestURLMappedEdgeDispatcher.java
index 353051c..b308d2c 100644
--- 
a/edge/edge-core/src/test/java/org/apache/servicecomb/edge/core/TestURLMappedEdgeDispatcher.java
+++ 
b/edge/edge-core/src/test/java/org/apache/servicecomb/edge/core/TestURLMappedEdgeDispatcher.java
@@ -19,7 +19,6 @@ package org.apache.servicecomb.edge.core;
 
 import java.util.Map;
 
-import 
org.apache.servicecomb.edge.core.URLMappedEdgeDispatcher.ConfigurationItem;
 import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
 import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
 import org.junit.After;
@@ -51,7 +50,7 @@ public class TestURLMappedEdgeDispatcher {
     ArchaiusUtils.setProperty("servicecomb.http.dispatcher.edge.url.enabled", 
true);
 
     URLMappedEdgeDispatcher dispatcher = new URLMappedEdgeDispatcher();
-    Map<String, ConfigurationItem> items = Deencapsulation
+    Map<String, URLMappedConfigurationItem> items = Deencapsulation
         .getField(dispatcher, "configurations");
     Assert.assertEquals(items.size(), 0);
 
@@ -68,21 +67,21 @@ public class TestURLMappedEdgeDispatcher {
     
ArchaiusUtils.setProperty("servicecomb.http.dispatcher.edge.url.mappings.service1.versionRule",
 "2.0.0+");
     items = Deencapsulation.getField(dispatcher, "configurations");
     Assert.assertEquals(items.size(), 1);
-    ConfigurationItem item = items.get("service1");
-    Assert.assertEquals(item.microserviceName, "serviceName");
-    Assert.assertEquals(item.prefixSegmentCount, 2);
-    Assert.assertEquals(item.stringPattern, "/a/b/c/.*");
-    Assert.assertEquals(item.versionRule, "2.0.0+");
+    URLMappedConfigurationItem item = items.get("service1");
+    Assert.assertEquals(item.getMicroserviceName(), "serviceName");
+    Assert.assertEquals(item.getPrefixSegmentCount(), 2);
+    Assert.assertEquals(item.getStringPattern(), "/a/b/c/.*");
+    Assert.assertEquals(item.getVersionRule(), "2.0.0+");
 
     
ArchaiusUtils.setProperty("servicecomb.http.dispatcher.edge.url.mappings.service2.versionRule",
 "2.0.0+");
     
ArchaiusUtils.setProperty("servicecomb.http.dispatcher.edge.url.mappings.service3.path",
 "/b/c/d/.*");
     items = Deencapsulation.getField(dispatcher, "configurations");
     Assert.assertEquals(items.size(), 1);
     item = items.get("service1");
-    Assert.assertEquals(item.microserviceName, "serviceName");
-    Assert.assertEquals(item.prefixSegmentCount, 2);
-    Assert.assertEquals(item.stringPattern, "/a/b/c/.*");
-    Assert.assertEquals(item.versionRule, "2.0.0+");
+    Assert.assertEquals(item.getMicroserviceName(), "serviceName");
+    Assert.assertEquals(item.getPrefixSegmentCount(), 2);
+    Assert.assertEquals(item.getStringPattern(), "/a/b/c/.*");
+    Assert.assertEquals(item.getVersionRule(), "2.0.0+");
 
     new Expectations() {
       {
diff --git 
a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestDispatcher.java
 
b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestDispatcher.java
index 763a360..bbecec5 100644
--- 
a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestDispatcher.java
+++ 
b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/VertxRestDispatcher.java
@@ -46,13 +46,17 @@ import io.vertx.ext.web.RoutingContext;
 public class VertxRestDispatcher extends AbstractVertxHttpDispatcher {
   private static final Logger LOGGER = 
LoggerFactory.getLogger(VertxRestDispatcher.class);
 
+  private static final String KEY_ORDER = 
"servicecomb.http.dispatcher.rest.order";
+
   private static final String KEY_ENABLED = 
"servicecomb.http.dispatcher.rest.enabled";
 
+  private static final String KEY_PATTERN = 
"servicecomb.http.dispatcher.rest.pattern";
+
   private Transport transport;
 
   @Override
   public int getOrder() {
-    return Integer.MAX_VALUE;
+    return DynamicPropertyFactory.getInstance().getIntProperty(KEY_ORDER, 
Integer.MAX_VALUE).get();
   }
 
   @Override
@@ -63,8 +67,14 @@ public class VertxRestDispatcher extends 
AbstractVertxHttpDispatcher {
   @Override
   public void init(Router router) {
     // cookies handler are enabled by default start from 3.8.3
-    router.route().handler(createBodyHandler());
-    
router.route().failureHandler(this::failureHandler).handler(this::onRequest);
+    String pattern = 
DynamicPropertyFactory.getInstance().getStringProperty(KEY_PATTERN, null).get();
+    if(pattern == null) {
+      router.route().handler(createBodyHandler());
+      
router.route().failureHandler(this::failureHandler).handler(this::onRequest);
+    } else {
+      router.routeWithRegex(pattern).handler(createBodyHandler());
+      
router.routeWithRegex(pattern).failureHandler(this::failureHandler).handler(this::onRequest);
+    }
   }
 
   protected void failureHandler(RoutingContext context) {

Reply via email to