diff --git a/.github/workflows/plugins-test.3.yaml b/.github/workflows/plugins-test.3.yaml index 8f4850a7a..e12035221 100644 --- a/.github/workflows/plugins-test.3.yaml +++ b/.github/workflows/plugins-test.3.yaml @@ -46,6 +46,7 @@ jobs: - { name: 'vertx-web-3.6plus-scenario', title: 'Vert.x Web 3.6.0-3.9.1 (14)' } - { name: 'mariadb-scenario', title: 'Mariadb 2.x (8)' } - { name: 'quasar-scenario', title: 'quasar 0.7.x (5)' } + - { name: 'baidu-brpc-scenario', title: 'baidu-brpc 2.3.7-2.5.3 (12)' } steps: - uses: actions/checkout@v2 with: diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java index 70bd828de..14775224b 100755 --- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java +++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java @@ -162,4 +162,6 @@ public class ComponentsDefine { public static final OfficialComponent QUASAR = new OfficialComponent(88, "quasar"); public static final OfficialComponent INFLUXDB_JAVA = new OfficialComponent(90, "influxdb-java"); + + public static final OfficialComponent BRPC_JAVA = new OfficialComponent(91, "brpc-java"); } diff --git a/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/pom.xml new file mode 100644 index 000000000..b37da608f --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/pom.xml @@ -0,0 +1,46 @@ + + + + + + apm-sdk-plugin + org.apache.skywalking + 8.1.0-SNAPSHOT + + 4.0.0 + jar + + baidu-brpc-plugin + baidu-brpc-plugin + + + 2.5.3 + + + + + com.baidu + brpc-java + ${brpc-java.version} + provided + + + \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/java/org/apache/skywalking/apm/plugin/baidu/brpc/ClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/java/org/apache/skywalking/apm/plugin/baidu/brpc/ClientInterceptor.java new file mode 100644 index 000000000..3c53c2653 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/java/org/apache/skywalking/apm/plugin/baidu/brpc/ClientInterceptor.java @@ -0,0 +1,86 @@ +/* + * 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.skywalking.apm.plugin.baidu.brpc; + +import com.baidu.brpc.protocol.Request; +import com.baidu.brpc.protocol.Response; +import org.apache.skywalking.apm.agent.core.context.CarrierItem; +import org.apache.skywalking.apm.agent.core.context.ContextCarrier; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import java.lang.reflect.Method; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.HashMap; + +public class ClientInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Request request = (Request) allArguments[0]; + InetSocketAddress remoteAddress = (InetSocketAddress) request.getChannel().remoteAddress(); + InetAddress address = remoteAddress.getAddress(); + + final ContextCarrier contextCarrier = new ContextCarrier(); + AbstractSpan span = ContextManager.createExitSpan(generateOperationName(request), contextCarrier, address.getHostAddress() + ":" + remoteAddress.getPort()); + CarrierItem next = contextCarrier.items(); + while (next.hasNext()) { + next = next.next(); + if (request.getKvAttachment() == null) { + request.setKvAttachment(new HashMap<>()); + } + request.getKvAttachment().put(next.getHeadKey(), next.getHeadValue()); + } + span.setComponent(ComponentsDefine.BRPC_JAVA); + SpanLayer.asRPCFramework(span); + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + Response response = (Response) allArguments[1]; + if (response != null && response.getException() != null) { + dealException(response.getException()); + } + + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + dealException(t); + } + + private void dealException(Throwable throwable) { + AbstractSpan span = ContextManager.activeSpan(); + span.errorOccurred(); + span.log(throwable); + } + + private String generateOperationName(Request request) { + StringBuilder operationName = new StringBuilder(); + operationName.append(request.getServiceName() + "." + request.getMethodName()); + return operationName.toString(); + } +} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/java/org/apache/skywalking/apm/plugin/baidu/brpc/ServerInterceptor.java b/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/java/org/apache/skywalking/apm/plugin/baidu/brpc/ServerInterceptor.java new file mode 100644 index 000000000..d6a204661 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/java/org/apache/skywalking/apm/plugin/baidu/brpc/ServerInterceptor.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.skywalking.apm.plugin.baidu.brpc; + +import com.baidu.brpc.protocol.Request; +import com.baidu.brpc.protocol.Response; +import org.apache.skywalking.apm.agent.core.context.CarrierItem; +import org.apache.skywalking.apm.agent.core.context.ContextCarrier; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import java.lang.reflect.Method; +import java.util.HashMap; + +public class ServerInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + Request request = (Request) allArguments[0]; + ContextCarrier contextCarrier = new ContextCarrier(); + CarrierItem next = contextCarrier.items(); + if (request.getKvAttachment() == null) { + request.setKvAttachment(new HashMap<>()); + } + while (next.hasNext()) { + next = next.next(); + next.setHeadValue((String) request.getKvAttachment().get(next.getHeadKey())); + } + + AbstractSpan span = ContextManager.createEntrySpan(generateOperationName(request), contextCarrier); + SpanLayer.asRPCFramework(span); + span.setComponent(ComponentsDefine.BRPC_JAVA); + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) throws Throwable { + Response response = (Response) allArguments[1]; + if (response != null && response.getException() != null) { + AbstractSpan span = ContextManager.activeSpan(); + span.log(response.getException()); + span.errorOccurred(); + } + + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + AbstractSpan activeSpan = ContextManager.activeSpan(); + activeSpan.errorOccurred(); + activeSpan.log(t); + } + + private static String generateOperationName(Request request) { + StringBuilder operationName = new StringBuilder(request.getServiceName()); + operationName.append(".").append(request.getMethodName()); + return operationName.toString(); + } +} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/java/org/apache/skywalking/apm/plugin/baidu/brpc/define/ClientInstrumentation.java b/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/java/org/apache/skywalking/apm/plugin/baidu/brpc/define/ClientInstrumentation.java new file mode 100644 index 000000000..4b6e5eea6 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/java/org/apache/skywalking/apm/plugin/baidu/brpc/define/ClientInstrumentation.java @@ -0,0 +1,68 @@ +/* + * 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.skywalking.apm.plugin.baidu.brpc.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +public class ClientInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + public static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.baidu.brpc.ClientInterceptor"; + public static final String ENHANCE_CLASS = "com.baidu.brpc.interceptor.LoadBalanceInterceptor"; + public static final String ENHANCE_METHOD = "rpcCore"; + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(ENHANCE_METHOD); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } +} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/java/org/apache/skywalking/apm/plugin/baidu/brpc/define/ServerInstrumentation.java b/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/java/org/apache/skywalking/apm/plugin/baidu/brpc/define/ServerInstrumentation.java new file mode 100644 index 000000000..94ce3ec07 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/java/org/apache/skywalking/apm/plugin/baidu/brpc/define/ServerInstrumentation.java @@ -0,0 +1,68 @@ +/* + * 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.skywalking.apm.plugin.baidu.brpc.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +public class ServerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + public static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.baidu.brpc.ServerInterceptor"; + public static final String ENHANCE_CLASS = "com.baidu.brpc.interceptor.ServerInvokeInterceptor"; + public static final String ENHANCE_METHOD = "aroundProcess"; + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(ENHANCE_METHOD); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } +} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 000000000..2c0c6eadb --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/baidu-brpc-plugin/src/main/resources/skywalking-plugin.def @@ -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. + +brpc-java=org.apache.skywalking.apm.plugin.baidu.brpc.define.ClientInstrumentation +brpc-java=org.apache.skywalking.apm.plugin.baidu.brpc.define.ServerInstrumentation diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index e6076a479..08a16f681 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -93,6 +93,7 @@ quasar-plugin mariadb-2.x-plugin influxdb-2.x-plugin + baidu-brpc-plugin pom diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md index ef231ae4c..5963d2723 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -45,6 +45,7 @@ * [Armeria](https://github.com/line/armeria) 0.63.0 -> 0.98.0 * [Apache Avro](http://avro.apache.org) 1.7.0 - 1.8.x * [Finagle](https://github.com/twitter/finagle) 6.25.0 -> 20.1.0 + * [Brpc-Java](https://github.com/baidu/brpc-java) 2.3.7 -> 2.5.3 * MQ * [RocketMQ](https://github.com/apache/rocketmq) 4.x * [Kafka](http://kafka.apache.org) 0.11.0.0 -> 1.0 diff --git a/oap-server/server-bootstrap/src/main/resources/component-libraries.yml b/oap-server/server-bootstrap/src/main/resources/component-libraries.yml index f32de5e1d..1a0ce9e1d 100755 --- a/oap-server/server-bootstrap/src/main/resources/component-libraries.yml +++ b/oap-server/server-bootstrap/src/main/resources/component-libraries.yml @@ -302,6 +302,9 @@ InfluxDB: influxdb-java: id: 90 languages: Java +brpc-java: + id: 91 + languages: Java # .NET/.NET Core components # [3000, 4000) for C#/.NET only diff --git a/test/plugin/scenarios/baidu-brpc-scenario/bin/startup.sh b/test/plugin/scenarios/baidu-brpc-scenario/bin/startup.sh new file mode 100644 index 000000000..e6b940cbe --- /dev/null +++ b/test/plugin/scenarios/baidu-brpc-scenario/bin/startup.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +# 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. + +home="$(cd "$(dirname $0)"; pwd)" + +java -jar ${agent_opts} ${home}/../libs/baidu-brpc-scenario.jar & \ No newline at end of file diff --git a/test/plugin/scenarios/baidu-brpc-scenario/config/expectedData.yaml b/test/plugin/scenarios/baidu-brpc-scenario/config/expectedData.yaml new file mode 100644 index 000000000..08278c20e --- /dev/null +++ b/test/plugin/scenarios/baidu-brpc-scenario/config/expectedData.yaml @@ -0,0 +1,66 @@ +# 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. +segmentItems: +- serviceName: baidu-brpc-scenario + segmentSize: gt 2 + segments: + - segmentId: not null + spans: + - operationName: example.EchoService.Echo + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: RPCFramework + startTime: nq 0 + endTime: nq 0 + componentId: 91 + isError: false + spanType: Entry + peer: '' + refs: + - {parentEndpoint: /baidu-brpc-scenario/case/brpc, networkAddress: '127.0.0.1:1118', + refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null, parentServiceInstance: not + null, parentService: baidu-brpc-scenario, traceId: not null} + skipAnalysis: 'false' + - segmentId: not null + spans: + - operationName: example.EchoService.Echo + operationId: 0 + parentSpanId: 0 + spanId: 1 + spanLayer: RPCFramework + startTime: nq 0 + endTime: nq 0 + componentId: 91 + isError: false + spanType: Exit + peer: 127.0.0.1:1118 + skipAnalysis: 'false' + - operationName: /baidu-brpc-scenario/case/brpc + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + tags: + - {key: url, value: 'http://localhost:8080/baidu-brpc-scenario/case/brpc'} + - {key: http.method, value: GET} + skipAnalysis: 'false' diff --git a/test/plugin/scenarios/baidu-brpc-scenario/configuration.yml b/test/plugin/scenarios/baidu-brpc-scenario/configuration.yml new file mode 100644 index 000000000..272c4617f --- /dev/null +++ b/test/plugin/scenarios/baidu-brpc-scenario/configuration.yml @@ -0,0 +1,20 @@ +# 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. + +type: jvm +entryService: http://localhost:8080/baidu-brpc-scenario/case/brpc +healthCheck: http://localhost:8080/baidu-brpc-scenario/case/healthCheck +startScript: ./bin/startup.sh diff --git a/test/plugin/scenarios/baidu-brpc-scenario/pom.xml b/test/plugin/scenarios/baidu-brpc-scenario/pom.xml new file mode 100644 index 000000000..6063462c9 --- /dev/null +++ b/test/plugin/scenarios/baidu-brpc-scenario/pom.xml @@ -0,0 +1,119 @@ + + + + 4.0.0 + + org.apache.skywalking + baidu-brpc-scenario + jar + 5.0.0 + + + UTF-8 + 1.8 + + 2.5.3 + + 2.1.6.RELEASE + baidu-brpc + + + skywalking-baidu-brpc-scenario + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + + + com.baidu + brpc-java + ${test.framework.version} + + + org.springframework.boot + spring-boot-starter-web + + + + + baidu-brpc-scenario + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + maven-compiler-plugin + + ${compiler.version} + ${compiler.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble + package + + single + + + + src/main/assembly/assembly.xml + + ./target/ + + + + + + + + + + spring-snapshots + http://repo.spring.io/snapshot + + + spring-milestones + http://repo.spring.io/milestone + + + \ No newline at end of file diff --git a/test/plugin/scenarios/baidu-brpc-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/baidu-brpc-scenario/src/main/assembly/assembly.xml new file mode 100644 index 000000000..f69d69974 --- /dev/null +++ b/test/plugin/scenarios/baidu-brpc-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/baidu-brpc-scenario.jar + ./libs + 0775 + + + diff --git a/test/plugin/scenarios/baidu-brpc-scenario/src/main/java/org/apache/skywalking/apm/testcase/baidu.brpc/BaiduBrpcApplication.java b/test/plugin/scenarios/baidu-brpc-scenario/src/main/java/org/apache/skywalking/apm/testcase/baidu.brpc/BaiduBrpcApplication.java new file mode 100644 index 000000000..3d16fff3a --- /dev/null +++ b/test/plugin/scenarios/baidu-brpc-scenario/src/main/java/org/apache/skywalking/apm/testcase/baidu.brpc/BaiduBrpcApplication.java @@ -0,0 +1,46 @@ +/* + * 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.skywalking.apm.testcase.baidu.brpc; + +import com.baidu.brpc.server.RpcServer; +import com.baidu.brpc.server.RpcServerOptions; +import org.apache.skywalking.apm.testcase.baidu.brpc.service.EchoServiceImpl; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class BaiduBrpcApplication implements InitializingBean { + + public static void main(String[] args) { + SpringApplication.run(BaiduBrpcApplication.class, args); + } + + @Override + public void afterPropertiesSet() throws Exception { + int port = 1118; + RpcServerOptions options = new RpcServerOptions(); + options.setReceiveBufferSize(64 * 1024 * 1024); + options.setSendBufferSize(64 * 1024 * 1024); + options.setKeepAliveTime(20); + final RpcServer rpcServer = new RpcServer(port, options); + rpcServer.registerService(new EchoServiceImpl()); + rpcServer.start(); + } +} diff --git a/test/plugin/scenarios/baidu-brpc-scenario/src/main/java/org/apache/skywalking/apm/testcase/baidu.brpc/controller/CaseController.java b/test/plugin/scenarios/baidu-brpc-scenario/src/main/java/org/apache/skywalking/apm/testcase/baidu.brpc/controller/CaseController.java new file mode 100644 index 000000000..9321eb79a --- /dev/null +++ b/test/plugin/scenarios/baidu-brpc-scenario/src/main/java/org/apache/skywalking/apm/testcase/baidu.brpc/controller/CaseController.java @@ -0,0 +1,75 @@ +/* + * 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.skywalking.apm.testcase.baidu.brpc.controller; + +import com.baidu.brpc.RpcContext; +import com.baidu.brpc.client.BrpcProxy; +import com.baidu.brpc.client.RpcClient; +import com.baidu.brpc.client.RpcClientOptions; +import com.baidu.brpc.client.loadbalance.LoadBalanceStrategy; +import com.baidu.brpc.exceptions.RpcException; +import com.baidu.brpc.protocol.Options; +import org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo; +import org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse; +import org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.EchoService; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/case") +public class CaseController { + + private static final String SUCCESS = "Success"; + + + @RequestMapping("/healthCheck") + @ResponseBody + public String healthCheck() { + return SUCCESS; + } + + @RequestMapping("/brpc") + @ResponseBody + public String brpc() { + RpcClientOptions clientOption = new RpcClientOptions(); + clientOption.setProtocolType(Options.ProtocolType.PROTOCOL_BAIDU_STD_VALUE); + clientOption.setWriteTimeoutMillis(1000); + clientOption.setReadTimeoutMillis(5000); + clientOption.setMaxTotalConnections(1000); + clientOption.setMinIdleConnections(10); + clientOption.setLoadBalanceType(LoadBalanceStrategy.LOAD_BALANCE_FAIR); + clientOption.setCompressType(Options.CompressType.COMPRESS_TYPE_NONE); + + String serviceUrl = "list://127.0.0.1:1118"; + Echo.EchoRequest request = Echo.EchoRequest.newBuilder() + .setMessage("helloooooooooooo") + .build(); + + RpcClient rpcClient = new RpcClient(serviceUrl, clientOption); + EchoService echoService = BrpcProxy.getProxy(rpcClient, EchoService.class); + try { + EchoResponse response = echoService.echo(request); + System.out.println(response.getMessage()); + } catch (RpcException ex) { + } + rpcClient.stop(); + return SUCCESS; + } +} diff --git a/test/plugin/scenarios/baidu-brpc-scenario/src/main/java/org/apache/skywalking/apm/testcase/baidu.brpc/interfaces/Echo.java b/test/plugin/scenarios/baidu-brpc-scenario/src/main/java/org/apache/skywalking/apm/testcase/baidu.brpc/interfaces/Echo.java new file mode 100644 index 000000000..74c35e240 --- /dev/null +++ b/test/plugin/scenarios/baidu-brpc-scenario/src/main/java/org/apache/skywalking/apm/testcase/baidu.brpc/interfaces/Echo.java @@ -0,0 +1,1040 @@ +/* + * 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. + * + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: echo.proto + +package org.apache.skywalking.apm.testcase.baidu.brpc.interfaces; + +public final class Echo { + private Echo() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + } + public interface EchoRequestOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string message = 1; + /** + * required string message = 1; + */ + boolean hasMessage(); + /** + * required string message = 1; + */ + String getMessage(); + /** + * required string message = 1; + */ + com.google.protobuf.ByteString + getMessageBytes(); + } + /** + * Protobuf type {@code example_for_cpp.EchoRequest} + */ + public static final class EchoRequest extends + com.google.protobuf.GeneratedMessage + implements EchoRequestOrBuilder { + // Use EchoRequest.newBuilder() to construct. + private EchoRequest(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private EchoRequest(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final EchoRequest defaultInstance; + public static EchoRequest getDefaultInstance() { + return defaultInstance; + } + + public EchoRequest getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private EchoRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + message_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.internal_static_example_for_cpp_EchoRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.internal_static_example_for_cpp_EchoRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest.class, org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public EchoRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new EchoRequest(input, extensionRegistry); + } + }; + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string message = 1; + public static final int MESSAGE_FIELD_NUMBER = 1; + private Object message_; + /** + * required string message = 1; + */ + public boolean hasMessage() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string message = 1; + */ + public String getMessage() { + Object ref = message_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + message_ = s; + } + return s; + } + } + /** + * required string message = 1; + */ + public com.google.protobuf.ByteString + getMessageBytes() { + Object ref = message_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + message_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + message_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasMessage()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getMessageBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getMessageBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @Override + protected Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code example_for_cpp.EchoRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.internal_static_example_for_cpp_EchoRequest_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.internal_static_example_for_cpp_EchoRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest.class, org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest.Builder.class); + } + + // Construct using org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + message_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.internal_static_example_for_cpp_EchoRequest_descriptor; + } + + public org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest getDefaultInstanceForType() { + return org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest.getDefaultInstance(); + } + + public org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest build() { + org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest buildPartial() { + org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest result = new org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.message_ = message_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest) { + return mergeFrom((org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest other) { + if (other == org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest.getDefaultInstance()) return this; + if (other.hasMessage()) { + bitField0_ |= 0x00000001; + message_ = other.message_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasMessage()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoRequest) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string message = 1; + private Object message_ = ""; + /** + * required string message = 1; + */ + public boolean hasMessage() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string message = 1; + */ + public String getMessage() { + Object ref = message_; + if (!(ref instanceof String)) { + String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + message_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * required string message = 1; + */ + public com.google.protobuf.ByteString + getMessageBytes() { + Object ref = message_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + message_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string message = 1; + */ + public Builder setMessage( + String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + message_ = value; + onChanged(); + return this; + } + /** + * required string message = 1; + */ + public Builder clearMessage() { + bitField0_ = (bitField0_ & ~0x00000001); + message_ = getDefaultInstance().getMessage(); + onChanged(); + return this; + } + /** + * required string message = 1; + */ + public Builder setMessageBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + message_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:example_for_cpp.EchoRequest) + } + + static { + defaultInstance = new EchoRequest(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:example_for_cpp.EchoRequest) + } + + public interface EchoResponseOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // required string message = 1; + /** + * required string message = 1; + */ + boolean hasMessage(); + /** + * required string message = 1; + */ + String getMessage(); + /** + * required string message = 1; + */ + com.google.protobuf.ByteString + getMessageBytes(); + } + /** + * Protobuf type {@code example_for_cpp.EchoResponse} + */ + public static final class EchoResponse extends + com.google.protobuf.GeneratedMessage + implements EchoResponseOrBuilder { + // Use EchoResponse.newBuilder() to construct. + private EchoResponse(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private EchoResponse(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final EchoResponse defaultInstance; + public static EchoResponse getDefaultInstance() { + return defaultInstance; + } + + public EchoResponse getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private EchoResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + message_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.internal_static_example_for_cpp_EchoResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.internal_static_example_for_cpp_EchoResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse.class, org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public EchoResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new EchoResponse(input, extensionRegistry); + } + }; + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // required string message = 1; + public static final int MESSAGE_FIELD_NUMBER = 1; + private Object message_; + /** + * required string message = 1; + */ + public boolean hasMessage() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string message = 1; + */ + public String getMessage() { + Object ref = message_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + message_ = s; + } + return s; + } + } + /** + * required string message = 1; + */ + public com.google.protobuf.ByteString + getMessageBytes() { + Object ref = message_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + message_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private void initFields() { + message_ = ""; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + if (!hasMessage()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getMessageBytes()); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getMessageBytes()); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @Override + protected Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code example_for_cpp.EchoResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.internal_static_example_for_cpp_EchoResponse_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.internal_static_example_for_cpp_EchoResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse.class, org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse.Builder.class); + } + + // Construct using org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + message_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.internal_static_example_for_cpp_EchoResponse_descriptor; + } + + public org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse getDefaultInstanceForType() { + return org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse.getDefaultInstance(); + } + + public org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse build() { + org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse buildPartial() { + org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse result = new org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.message_ = message_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse) { + return mergeFrom((org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse other) { + if (other == org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse.getDefaultInstance()) return this; + if (other.hasMessage()) { + bitField0_ |= 0x00000001; + message_ = other.message_; + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + if (!hasMessage()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo.EchoResponse) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // required string message = 1; + private Object message_ = ""; + /** + * required string message = 1; + */ + public boolean hasMessage() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required string message = 1; + */ + public String getMessage() { + Object ref = message_; + if (!(ref instanceof String)) { + String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + message_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * required string message = 1; + */ + public com.google.protobuf.ByteString + getMessageBytes() { + Object ref = message_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + message_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string message = 1; + */ + public Builder setMessage( + String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + message_ = value; + onChanged(); + return this; + } + /** + * required string message = 1; + */ + public Builder clearMessage() { + bitField0_ = (bitField0_ & ~0x00000001); + message_ = getDefaultInstance().getMessage(); + onChanged(); + return this; + } + /** + * required string message = 1; + */ + public Builder setMessageBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + message_ = value; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:example_for_cpp.EchoResponse) + } + + static { + defaultInstance = new EchoResponse(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:example_for_cpp.EchoResponse) + } + + private static com.google.protobuf.Descriptors.Descriptor + internal_static_example_for_cpp_EchoRequest_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_example_for_cpp_EchoRequest_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_example_for_cpp_EchoResponse_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_example_for_cpp_EchoResponse_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + String[] descriptorData = { + "\n\necho.proto\022\017example_for_cpp\"\036\n\013EchoReq" + + "uest\022\017\n\007message\030\001 \002(\t\"\037\n\014EchoResponse\022\017\n" + + "\007message\030\001 \002(\t2R\n\013EchoService\022C\n\004Echo\022\034." + + "example_for_cpp.EchoRequest\032\035.example_fo" + + "r_cpp.EchoResponseB*\n\037com.baidu.brpc.exa" + + "mple.standardB\004Echo\200\001\001" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + internal_static_example_for_cpp_EchoRequest_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_example_for_cpp_EchoRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_example_for_cpp_EchoRequest_descriptor, + new String[] { "Message", }); + internal_static_example_for_cpp_EchoResponse_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_example_for_cpp_EchoResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_example_for_cpp_EchoResponse_descriptor, + new String[] { "Message", }); + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }, assigner); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/test/plugin/scenarios/baidu-brpc-scenario/src/main/java/org/apache/skywalking/apm/testcase/baidu.brpc/interfaces/EchoService.java b/test/plugin/scenarios/baidu-brpc-scenario/src/main/java/org/apache/skywalking/apm/testcase/baidu.brpc/interfaces/EchoService.java new file mode 100755 index 000000000..69e4b8ebe --- /dev/null +++ b/test/plugin/scenarios/baidu-brpc-scenario/src/main/java/org/apache/skywalking/apm/testcase/baidu.brpc/interfaces/EchoService.java @@ -0,0 +1,30 @@ +/* + * 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.skywalking.apm.testcase.baidu.brpc.interfaces; + +import com.baidu.brpc.protocol.BrpcMeta; + +/** + * Copy from brpc-java-example + */ +public interface EchoService { + + @BrpcMeta(serviceName = "example.EchoService", methodName = "Echo") + Echo.EchoResponse echo(Echo.EchoRequest request); +} diff --git a/test/plugin/scenarios/baidu-brpc-scenario/src/main/java/org/apache/skywalking/apm/testcase/baidu.brpc/service/EchoServiceImpl.java b/test/plugin/scenarios/baidu-brpc-scenario/src/main/java/org/apache/skywalking/apm/testcase/baidu.brpc/service/EchoServiceImpl.java new file mode 100755 index 000000000..586d31e3d --- /dev/null +++ b/test/plugin/scenarios/baidu-brpc-scenario/src/main/java/org/apache/skywalking/apm/testcase/baidu.brpc/service/EchoServiceImpl.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.skywalking.apm.testcase.baidu.brpc.service; + + +import com.baidu.brpc.RpcContext; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.Echo; +import org.apache.skywalking.apm.testcase.baidu.brpc.interfaces.EchoService; + +/** + * Copy from brpc-java-example + */ +public class EchoServiceImpl implements EchoService { + + @Override + public Echo.EchoResponse echo(Echo.EchoRequest request) { + if (RpcContext.isSet()) { + RpcContext rpcContext = RpcContext.getContext(); + ByteBuf attachment = rpcContext.getRequestBinaryAttachment(); + if (attachment != null) { + rpcContext.setResponseBinaryAttachment(Unpooled.copiedBuffer(attachment)); + } + } + String message = request.getMessage(); + Echo.EchoResponse response = Echo.EchoResponse.newBuilder() + .setMessage(message).build(); + return response; + } +} diff --git a/test/plugin/scenarios/baidu-brpc-scenario/src/main/resources/application.yml b/test/plugin/scenarios/baidu-brpc-scenario/src/main/resources/application.yml new file mode 100644 index 000000000..9b30649b3 --- /dev/null +++ b/test/plugin/scenarios/baidu-brpc-scenario/src/main/resources/application.yml @@ -0,0 +1,20 @@ +# 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. + +server: + port: 8080 + servlet: + context-path: /baidu-brpc-scenario \ No newline at end of file diff --git a/test/plugin/scenarios/baidu-brpc-scenario/support-version.list b/test/plugin/scenarios/baidu-brpc-scenario/support-version.list new file mode 100644 index 000000000..da6654f63 --- /dev/null +++ b/test/plugin/scenarios/baidu-brpc-scenario/support-version.list @@ -0,0 +1,29 @@ +# 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 +# "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. + + +2.3.7 +2.4.0 +2.4.1 +2.4.2 +2.4.3 +2.4.4 +2.4.5 +2.4.6 +2.5.0 +2.5.1 +2.5.2 +2.5.3