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

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

commit ddf9805aad01662f3e566ef694922ad8a0da1b20
Author: yhs0092 <[email protected]>
AuthorDate: Sun Dec 8 13:35:15 2024 +0800

    [SCB-2894] support @Transport annotation
    
    sync '[SCB-2888]support configuring operation transport (#4413)'(a4468c47) 
from master branch to 2.8.x branch
---
 .../java/org/apache/servicecomb/core/Const.java    |  4 ++
 .../org/apache/servicecomb/core/Invocation.java    | 27 +++++++++++++
 .../servicecomb/core/annotation/Transport.java     | 47 ++++++++++++++++++++++
 .../TransportClassAnnotationProcessor.java         | 43 ++++++++++++++++++++
 .../TransportMethodAnnotationProcessor.java        | 44 ++++++++++++++++++++
 ...comb.swagger.generator.ClassAnnotationProcessor | 18 +++++++++
 ...omb.swagger.generator.MethodAnnotationProcessor | 18 +++++++++
 .../loadbalance/TestLoadBalanceHandler2.java       | 14 ++++++-
 8 files changed, 214 insertions(+), 1 deletion(-)

diff --git a/core/src/main/java/org/apache/servicecomb/core/Const.java 
b/core/src/main/java/org/apache/servicecomb/core/Const.java
index 03c751def..4b860e000 100644
--- a/core/src/main/java/org/apache/servicecomb/core/Const.java
+++ b/core/src/main/java/org/apache/servicecomb/core/Const.java
@@ -25,10 +25,14 @@ public final class Const {
 
   public static final String CSE_CONTEXT = "x-cse-context";
 
+  public static final String TRANSPORT_NAME = "x-transport-name";
+
   public static final String RESTFUL = "rest";
 
   public static final String HIGHWAY = "highway";
 
+  public static final String WEBSOCKET = "websocket";
+
   public static final String ANY_TRANSPORT = "";
 
   public static final String VERSION_RULE_LATEST = 
DefinitionConst.VERSION_RULE_LATEST;
diff --git a/core/src/main/java/org/apache/servicecomb/core/Invocation.java 
b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
index b1b48c7f3..af9679c94 100644
--- a/core/src/main/java/org/apache/servicecomb/core/Invocation.java
+++ b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
@@ -28,6 +28,7 @@ import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicLong;
 
 import com.google.common.annotations.VisibleForTesting;
+
 import org.apache.commons.lang3.StringUtils;
 import org.apache.servicecomb.core.definition.InvocationRuntimeType;
 import org.apache.servicecomb.core.definition.MicroserviceMeta;
@@ -149,6 +150,13 @@ public class Invocation extends SwaggerInvocation {
     traceIdLogger = new TraceIdLogger(this);
   }
 
+  public String getTransportName() {
+    if (endpoint == null || endpoint.getTransport() == null) {
+      return null;
+    }
+    return endpoint.getTransport().getName();
+  }
+
   public Transport getTransport() {
     if (endpoint == null) {
       throw new IllegalStateException(
@@ -288,7 +296,26 @@ public class Invocation extends SwaggerInvocation {
     return operationMeta.getOperationId();
   }
 
+  public String getProviderTransportName() {
+    final Map<String, Object> operationVendorExtensions = 
operationMeta.getSwaggerOperation().getVendorExtensions();
+    if (operationVendorExtensions != null) {
+      final String operationTransportName = (String) 
operationVendorExtensions.get(Const.TRANSPORT_NAME);
+      if (operationTransportName != null) {
+        return operationTransportName;
+      }
+    }
+    final Map<String, Object> schemaVendorExtensions = 
schemaMeta.getSwagger().getVendorExtensions();
+    if (schemaVendorExtensions == null) {
+      return null;
+    }
+    return (String) schemaVendorExtensions.get(Const.TRANSPORT_NAME);
+  }
+
   public String getConfigTransportName() {
+    final String providerTransportName = getProviderTransportName();
+    if (providerTransportName != null) {
+      return providerTransportName;
+    }
     return referenceConfig.getTransport();
   }
 
diff --git 
a/core/src/main/java/org/apache/servicecomb/core/annotation/Transport.java 
b/core/src/main/java/org/apache/servicecomb/core/annotation/Transport.java
new file mode 100644
index 000000000..aca525482
--- /dev/null
+++ b/core/src/main/java/org/apache/servicecomb/core/annotation/Transport.java
@@ -0,0 +1,47 @@
+/*
+ * 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.core.annotation;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Mark Transport protocol of REST method.
+ */
+@Inherited
+@Documented
+@Retention(RUNTIME)
+@Target({TYPE, METHOD, ANNOTATION_TYPE})
+public @interface Transport {
+  /**
+   * Transport name. Valid values:
+   * <ul>
+   *   <li>{@link org.apache.servicecomb.core.Const#RESTFUL}</li>
+   *   <li>{@link org.apache.servicecomb.core.Const#HIGHWAY}</li>
+   *   <li>{@link org.apache.servicecomb.core.Const#WEBSOCKET}</li>
+   * </ul>
+   */
+  String name();
+}
diff --git 
a/core/src/main/java/org/apache/servicecomb/core/transport/TransportClassAnnotationProcessor.java
 
b/core/src/main/java/org/apache/servicecomb/core/transport/TransportClassAnnotationProcessor.java
new file mode 100644
index 000000000..b65192a4e
--- /dev/null
+++ 
b/core/src/main/java/org/apache/servicecomb/core/transport/TransportClassAnnotationProcessor.java
@@ -0,0 +1,43 @@
+/*
+ * 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.core.transport;
+
+import java.lang.reflect.Type;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.core.Const;
+import org.apache.servicecomb.core.annotation.Transport;
+import org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor;
+import org.apache.servicecomb.swagger.generator.SwaggerGenerator;
+
+public class TransportClassAnnotationProcessor implements 
ClassAnnotationProcessor<Transport> {
+  @Override
+  public Type getProcessType() {
+    return Transport.class;
+  }
+
+  @Override
+  public void process(SwaggerGenerator swaggerGenerator, Transport transport) {
+    if (StringUtils.isEmpty(transport.name())) {
+      return;
+    }
+
+    swaggerGenerator.getSwagger()
+        .setVendorExtension(Const.TRANSPORT_NAME, transport.name());
+  }
+}
diff --git 
a/core/src/main/java/org/apache/servicecomb/core/transport/TransportMethodAnnotationProcessor.java
 
b/core/src/main/java/org/apache/servicecomb/core/transport/TransportMethodAnnotationProcessor.java
new file mode 100644
index 000000000..7d5340aee
--- /dev/null
+++ 
b/core/src/main/java/org/apache/servicecomb/core/transport/TransportMethodAnnotationProcessor.java
@@ -0,0 +1,44 @@
+/*
+ * 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.core.transport;
+
+import java.lang.reflect.Type;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.core.Const;
+import org.apache.servicecomb.core.annotation.Transport;
+import org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor;
+import org.apache.servicecomb.swagger.generator.OperationGenerator;
+import org.apache.servicecomb.swagger.generator.SwaggerGenerator;
+
+public class TransportMethodAnnotationProcessor implements 
MethodAnnotationProcessor<Transport> {
+  @Override
+  public Type getProcessType() {
+    return Transport.class;
+  }
+
+  @Override
+  public void process(SwaggerGenerator swaggerGenerator, OperationGenerator 
operationGenerator, Transport transport) {
+    if (StringUtils.isEmpty(transport.name())) {
+      return;
+    }
+
+    operationGenerator.getOperation()
+        .setVendorExtension(Const.TRANSPORT_NAME, transport.name());
+  }
+}
diff --git 
a/core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor
 
b/core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor
new file mode 100644
index 000000000..d8d096f3a
--- /dev/null
+++ 
b/core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+org.apache.servicecomb.core.transport.TransportClassAnnotationProcessor
\ No newline at end of file
diff --git 
a/core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor
 
b/core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor
new file mode 100644
index 000000000..a79270a55
--- /dev/null
+++ 
b/core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+org.apache.servicecomb.core.transport.TransportMethodAnnotationProcessor
\ No newline at end of file
diff --git 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
 
b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
index 2008445ae..f83d0b86b 100644
--- 
a/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
+++ 
b/handlers/handler-loadbalance/src/test/java/org/apache/servicecomb/loadbalance/TestLoadBalanceHandler2.java
@@ -62,6 +62,8 @@ import org.mockito.Mockito;
 
 import com.google.common.eventbus.Subscribe;
 
+import io.swagger.models.Operation;
+import io.swagger.models.Swagger;
 import mockit.Mock;
 import mockit.MockUp;
 
@@ -112,6 +114,8 @@ public class TestLoadBalanceHandler2 {
     InvocationRuntimeType invocationRuntimeType = 
Mockito.mock(InvocationRuntimeType.class);
     SchemaMeta schemaMeta = Mockito.mock(SchemaMeta.class);
     when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);
+    when(operationMeta.getSwaggerOperation()).thenReturn(new Operation());
+    when(schemaMeta.getSwagger()).thenReturn(new Swagger());
     MicroserviceMeta microserviceMeta = Mockito.mock(MicroserviceMeta.class);
     when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);
     when(schemaMeta.getMicroserviceName()).thenReturn("testMicroserviceName");
@@ -258,6 +262,8 @@ public class TestLoadBalanceHandler2 {
     InvocationRuntimeType invocationRuntimeType = 
Mockito.mock(InvocationRuntimeType.class);
     SchemaMeta schemaMeta = Mockito.mock(SchemaMeta.class);
     when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);
+    when(operationMeta.getSwaggerOperation()).thenReturn(new Operation());
+    when(schemaMeta.getSwagger()).thenReturn(new Swagger());
     MicroserviceMeta microserviceMeta = Mockito.mock(MicroserviceMeta.class);
     when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);
     when(schemaMeta.getMicroserviceName()).thenReturn("testMicroserviceName");
@@ -345,6 +351,8 @@ public class TestLoadBalanceHandler2 {
     InvocationRuntimeType invocationRuntimeType = 
Mockito.mock(InvocationRuntimeType.class);
     SchemaMeta schemaMeta = Mockito.mock(SchemaMeta.class);
     when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);
+    when(operationMeta.getSwaggerOperation()).thenReturn(new Operation());
+    when(schemaMeta.getSwagger()).thenReturn(new Swagger());
     MicroserviceMeta microserviceMeta = Mockito.mock(MicroserviceMeta.class);
     when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);
     when(schemaMeta.getMicroserviceName()).thenReturn("testMicroserviceName");
@@ -739,6 +747,8 @@ public class TestLoadBalanceHandler2 {
     InvocationRuntimeType invocationRuntimeType = 
Mockito.mock(InvocationRuntimeType.class);
     SchemaMeta schemaMeta = Mockito.mock(SchemaMeta.class);
     when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);
+    when(operationMeta.getSwaggerOperation()).thenReturn(new Operation());
+    when(schemaMeta.getSwagger()).thenReturn(new Swagger());
     MicroserviceMeta microserviceMeta = Mockito.mock(MicroserviceMeta.class);
     when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);
     when(schemaMeta.getMicroserviceName()).thenReturn("testMicroserviceName");
@@ -778,8 +788,10 @@ public class TestLoadBalanceHandler2 {
     LoadbalanceHandler handler = new LoadbalanceHandler();
     try {
       handler.handle(invocation, asyncResp);
+    } catch (IndexOutOfBoundsException e) {
+      // swallow, IndexOutOfBoundsException is expected because the handler 
chain of Invocation is not mocked
     } catch (Exception e) {
-
+      throw new IllegalStateException(e);
     }
     Assertions.assertEquals("rest://localhost:9092", 
invocation.getEndpoint().getEndpoint());
 

Reply via email to