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());
