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 2021/04/27 07:56:01 UTC

[servicecomb-java-chassis] branch master updated: [SCB-2257][SCB-2258]governance support http based match (#2361)

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 09e5381  [SCB-2257][SCB-2258]governance support http based match (#2361)
09e5381 is described below

commit 09e538166a6902cd55cc0495d2439149b8f16d84
Author: bao liu <bi...@qq.com>
AuthorDate: Tue Apr 27 15:55:52 2021 +0800

    [SCB-2257][SCB-2258]governance support http based match (#2361)
    
    * [SCB-2257][SCB-2258]governance support http based match
    
    * [SCB-2257][SCB-2258]add swagger arguments to header
    
    * [SCB-2257][SCB-2258]ignore null value
---
 .../core/definition/OperationConfig.java           | 11 +++
 .../demo/zeroconfig/client/GovernanceEndpoint.java | 12 ++++
 .../src/main/resources/application.yml             | 29 ++++++--
 .../demo/zeroconfig/server/GovernanceEndpoint.java |  8 +++
 .../demo/zeroconfig/tests/GovernanceTest.java      | 30 ++++++--
 .../src/main/resources/application.yml             |  5 +-
 .../governance/ConsumerGovernanceHandler.java      | 10 +--
 .../servicecomb/handler/governance/MatchType.java  | 84 ++++++++++++++++++++++
 .../governance/ProviderGovernanceHandler.java      | 10 +--
 9 files changed, 170 insertions(+), 29 deletions(-)

diff --git a/core/src/main/java/org/apache/servicecomb/core/definition/OperationConfig.java b/core/src/main/java/org/apache/servicecomb/core/definition/OperationConfig.java
index c210efd..17e5cf1 100644
--- a/core/src/main/java/org/apache/servicecomb/core/definition/OperationConfig.java
+++ b/core/src/main/java/org/apache/servicecomb/core/definition/OperationConfig.java
@@ -108,6 +108,9 @@ public class OperationConfig {
   })
   private String transport;
 
+  @InjectProperty(keys = {"governance.${op-any-priority}.matchType", "governance.matchType"}, defaultValue = "rest")
+  private String governanceMatchType;
+
   public boolean isSlowInvocationEnabled() {
     return slowInvocationEnabled;
   }
@@ -195,6 +198,14 @@ public class OperationConfig {
     this.nanoInvocationTimeout = TimeUnit.MILLISECONDS.toNanos(msInvocationTimeout);
   }
 
+  public String getGovernanceMatchType() {
+    return governanceMatchType;
+  }
+
+  public void setGovernanceMatchType(String governanceMatchType) {
+    this.governanceMatchType = governanceMatchType;
+  }
+
   public long getNanoInvocationTimeout() {
     return this.nanoInvocationTimeout;
   }
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/GovernanceEndpoint.java b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/GovernanceEndpoint.java
index 0d99ffe..8c77c7c 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/GovernanceEndpoint.java
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/java/org/apache/servicecomb/demo/zeroconfig/client/GovernanceEndpoint.java
@@ -38,6 +38,11 @@ public class GovernanceEndpoint {
     return restTemplate.getForObject(SERVER + "/governance/hello", String.class);
   }
 
+  @GetMapping("/helloRpc")
+  public String helloRpc() {
+    return restTemplate.getForObject(SERVER + "/governance/hello", String.class);
+  }
+
   @GetMapping("/retry")
   public String retry(@RequestParam(name = "invocationID") String invocationID) {
     return restTemplate
@@ -45,6 +50,13 @@ public class GovernanceEndpoint {
             invocationID);
   }
 
+  @GetMapping("/retryRpc")
+  public String retryRpc(@RequestParam(name = "invocationID") String invocationID) {
+    return restTemplate
+        .getForObject(SERVER + "/governance/retryRpc?invocationID={1}", String.class,
+            invocationID);
+  }
+
   @GetMapping("/circuitBreaker")
   public String circuitBreaker() throws Exception {
     count++;
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/resources/application.yml b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/resources/application.yml
index c43c4ce..1eb345f 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/resources/application.yml
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-client/src/main/resources/application.yml
@@ -41,33 +41,54 @@ servicecomb:
       Provider:
         default: governance-provider
 
+  governance:
+    GovernanceEndpoint.helloRpc:
+      matchType: rpc
+    demo-zeroconfig-schemadiscovery-registry-server.GovernanceEndpoint.retryRpc:
+      matchType: rpc
   matchGroup:
     demo-rateLimiting: |
       matches:
         - apiPath:
-            exact: "GovernanceEndpoint.hello"
+            exact: "/governance/hello"
+    demo-rateLimiting-rpc: |
+      matches:
+        - apiPath:
+            exact: "GovernanceEndpoint.helloRpc"
     demo-retry: |
       matches:
         - apiPath:
-            exact: "GovernanceEndpoint.retry"
+            exact: "/governance/retry"
+    demo-retry-rpc: |
+      matches:
+        - apiPath:
+            exact: "demo-zeroconfig-schemadiscovery-registry-server.GovernanceEndpoint.retryRpc"
     demo-circuitBreaker: |
       matches:
         - apiPath:
-            exact: "GovernanceEndpoint.circuitBreaker"
+            exact: "/governance/circuitBreaker"
     demo-bulkhead: |
       matches:
         - apiPath:
-            exact: "GovernanceEndpoint.bulkhead"
+            exact: "/governance/bulkhead"
   rateLimiting:
     demo-rateLimiting: |
       rate: 10
       ## services is optional in configuration file
       services: demo-zeroconfig-schemadiscovery-registry-client
+    demo-rateLimiting-rpc: |
+      rate: 10
+      ## services is optional in configuration file
+      services: demo-zeroconfig-schemadiscovery-registry-client
   retry:
     demo-retry: |
       maxAttempts: 3
       ## services is optional in configuration file
       services: demo-zeroconfig-schemadiscovery-registry-client
+    demo-retry-rpc: |
+      maxAttempts: 3
+      ## services is optional in configuration file
+      services: demo-zeroconfig-schemadiscovery-registry-client
   circuitBreaker:
     demo-circuitBreaker: |
       minimumNumberOfCalls: 10
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-server/src/main/java/org/apache/servicecomb/demo/zeroconfig/server/GovernanceEndpoint.java b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-server/src/main/java/org/apache/servicecomb/demo/zeroconfig/server/GovernanceEndpoint.java
index 718a242..4e7e15f 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-server/src/main/java/org/apache/servicecomb/demo/zeroconfig/server/GovernanceEndpoint.java
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-server/src/main/java/org/apache/servicecomb/demo/zeroconfig/server/GovernanceEndpoint.java
@@ -60,6 +60,14 @@ public class GovernanceEndpoint {
     throw new InvocationException(502, "retry", "retry");
   }
 
+  @GetMapping("/retryRpc")
+  @ApiResponses({
+      @ApiResponse(code = 200, response = String.class, message = ""),
+      @ApiResponse(code = 502, response = String.class, message = "")})
+  public String retryRpc(@RequestParam(name = "invocationID") String invocationID) {
+    return retry(invocationID);
+  }
+
   @GetMapping("/circuitBreaker")
   public String circuitBreaker() {
     throw new RuntimeException("circuitBreaker by provider.");
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/GovernanceTest.java b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/GovernanceTest.java
index 40161bf..dfb4bba 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/GovernanceTest.java
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/java/org/apache/servicecomb/demo/zeroconfig/tests/GovernanceTest.java
@@ -38,13 +38,23 @@ public class GovernanceTest implements CategorizedTestCase {
   public void testRestTransport() throws Exception {
     testCircuitBreaker();
     testBulkhead();
-    testRateLimiting();
-    testRetry();
+    testRateLimitingRest();
+    testRateLimitingRpc();
+    testRetryRest();
+    testRetryRpc();
   }
 
-  private void testRetry() {
+  private void testRetryRest() {
+    testRetry("/retry");
+  }
+
+  private void testRetryRpc() {
+    testRetry("/retryRpc");
+  }
+
+  private void testRetry(String operation) {
     String invocationID = UUID.randomUUID().toString();
-    String result = template.getForObject(url + "/retry?invocationID={1}", String.class, invocationID);
+    String result = template.getForObject(url + operation + "?invocationID={1}", String.class, invocationID);
     TestMgr.check(result, "try times: 3");
   }
 
@@ -121,7 +131,15 @@ public class GovernanceTest implements CategorizedTestCase {
     TestMgr.check(false, notExpectedFailed.get());
   }
 
-  private void testRateLimiting() throws Exception {
+  private void testRateLimitingRest() throws Exception {
+    testRateLimiting("/hello");
+  }
+
+  private void testRateLimitingRpc() throws Exception {
+    testRateLimiting("/helloRpc");
+  }
+
+  private void testRateLimiting(String operation) throws Exception {
     CountDownLatch latch = new CountDownLatch(100);
     AtomicBoolean expectedFailed = new AtomicBoolean(false);
     AtomicBoolean notExpectedFailed = new AtomicBoolean(false);
@@ -132,7 +150,7 @@ public class GovernanceTest implements CategorizedTestCase {
         new Thread(name) {
           public void run() {
             try {
-              String result = template.getForObject(url + "/hello", String.class);
+              String result = template.getForObject(url + operation, String.class);
               if (!"Hello world!".equals(result)) {
                 notExpectedFailed.set(true);
               }
diff --git a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/application.yml b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/application.yml
index 9d610e0..e139ef0 100644
--- a/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/application.yml
+++ b/demo/demo-zeroconfig-schemadiscovery-registry/demo-zeroconfig-schemadiscovery-registry-tests/src/main/resources/application.yml
@@ -25,4 +25,7 @@ servicecomb:
   handler:
     chain:
       Consumer:
-        default: loadbalance
\ No newline at end of file
+        default: loadbalance
+  loadbalance:
+    isolation:
+      enabled: false
\ No newline at end of file
diff --git a/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ConsumerGovernanceHandler.java b/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ConsumerGovernanceHandler.java
index 15e6b08..e52e4d2 100644
--- a/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ConsumerGovernanceHandler.java
+++ b/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ConsumerGovernanceHandler.java
@@ -63,7 +63,7 @@ public class ConsumerGovernanceHandler implements Handler {
   public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception {
     Supplier<CompletionStage<Response>> next = createBusinessCompletionStageSupplier(invocation);
     DecorateCompletionStage<Response> dcs = Decorators.ofCompletionStage(next);
-    GovernanceRequest request = createGovHttpRequest(invocation);
+    GovernanceRequest request = MatchType.createGovHttpRequest(invocation);
 
     try {
       ServiceCombInvocationContext.setInvocationContext(invocation);
@@ -138,12 +138,4 @@ public class ConsumerGovernanceHandler implements Handler {
       return result;
     };
   }
-
-  private GovernanceRequest createGovHttpRequest(Invocation invocation) {
-    GovernanceRequest request = new GovernanceRequest();
-    request.setUri(invocation.getSchemaId() + "." + invocation.getOperationName());
-    request.setMethod(invocation.getOperationMeta().getHttpMethod());
-    request.setHeaders(invocation.getContext());
-    return request;
-  }
 }
diff --git a/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/MatchType.java b/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/MatchType.java
new file mode 100644
index 0000000..f9f08bd
--- /dev/null
+++ b/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/MatchType.java
@@ -0,0 +1,84 @@
+/*
+ * 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.handler.governance;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.governance.marker.GovernanceRequest;
+
+public final class MatchType {
+  public static final String REST = "rest";
+
+  public static final String RPC = "rpc";
+
+  public static GovernanceRequest createGovHttpRequest(Invocation invocation) {
+    GovernanceRequest request = new GovernanceRequest();
+
+    if (MatchType.REST.equalsIgnoreCase(invocation.getOperationMeta().getConfig().getGovernanceMatchType())) {
+      if (invocation.isConsumer()) {
+        request.setUri(
+            invocation.getSchemaMeta().getSwagger().getBasePath() + invocation.getOperationMeta().getOperationPath());
+        request.setMethod(invocation.getOperationMeta().getHttpMethod());
+        request.setHeaders(getHeaderMap(invocation, true));
+        return request;
+      }
+      request.setUri(invocation.getRequestEx().getRequestURI());
+      request.setMethod(invocation.getRequestEx().getMethod());
+      request.setHeaders(getHeaderMap(invocation, false));
+      return request;
+    }
+
+    if (invocation.isConsumer()) {
+      request.setUri(invocation.getOperationMeta().getMicroserviceQualifiedName());
+    } else {
+      request.setUri(invocation.getOperationMeta().getSchemaQualifiedName());
+    }
+    request.setMethod(invocation.getOperationMeta().getHttpMethod());
+    request.setHeaders(getHeaderMap(invocation, true));
+
+    return request;
+  }
+
+  private static Map<String, String> getHeaderMap(Invocation invocation, boolean fromContext) {
+    Map<String, String> headers = new HashMap<>();
+    if (fromContext) {
+      headers.putAll(invocation.getContext());
+    } else {
+      Enumeration<String> names = invocation.getRequestEx().getHeaderNames();
+      while (names.hasMoreElements()) {
+        String name = names.nextElement();
+        if (invocation.getRequestEx().getHeader(name) != null) {
+          headers.put(name, invocation.getRequestEx().getHeader(name));
+        }
+      }
+    }
+
+    Map<String, Object> arguments = invocation.getSwaggerArguments();
+    if (arguments != null) {
+      arguments.forEach((k, v) -> {
+        if (v != null) {
+          headers.put(k, v.toString());
+        }
+      });
+    }
+    return headers;
+  }
+}
diff --git a/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ProviderGovernanceHandler.java b/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ProviderGovernanceHandler.java
index fefae9f..e31cfd2 100644
--- a/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ProviderGovernanceHandler.java
+++ b/handlers/handler-governance/src/main/java/org/apache/servicecomb/handler/governance/ProviderGovernanceHandler.java
@@ -58,7 +58,7 @@ public class ProviderGovernanceHandler implements Handler {
 
     Supplier<CompletionStage<Response>> next = createBusinessCompletionStageSupplier(invocation);
     DecorateCompletionStage<Response> dcs = Decorators.ofCompletionStage(next);
-    GovernanceRequest request = createGovHttpRequest(invocation);
+    GovernanceRequest request = MatchType.createGovHttpRequest(invocation);
 
     try {
       ServiceCombInvocationContext.setInvocationContext(invocation);
@@ -136,12 +136,4 @@ public class ProviderGovernanceHandler implements Handler {
       return result;
     };
   }
-
-  private GovernanceRequest createGovHttpRequest(Invocation invocation) {
-    GovernanceRequest request = new GovernanceRequest();
-    request.setUri(invocation.getSchemaId() + "." + invocation.getOperationName());
-    request.setMethod(invocation.getOperationMeta().getHttpMethod());
-    request.setHeaders(invocation.getContext());
-    return request;
-  }
 }