diff --git a/.github/workflows/plugins-test.3.yaml b/.github/workflows/plugins-test.3.yaml index 3df8132c681832ac1c57284578b69c3005b748a9..2b262ea04b6c5b0d17181b8e0c395e50ac4a5df4 100644 --- a/.github/workflows/plugins-test.3.yaml +++ b/.github/workflows/plugins-test.3.yaml @@ -52,6 +52,7 @@ jobs: - { name: 'graphql-8.x-scenario', title: 'graphql-8.x 8.0 (1)' } - { name: 'graphql-9.x-scenario', title: 'graphql-9.x 9.0-11.0 (3)' } - { name: 'graphql-12.x-scenario', title: 'graphql-12.x 12.0-15.0 (4)' } + - { name: 'hbase-scenario', title: 'hbase-scenario (5)' } 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 d31a16d9433b12d2836f3c289884263584f93608..d46a61c84a748b36dbf1b35411e5a1ccbc775aec 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 @@ -168,4 +168,6 @@ public class ComponentsDefine { public static final OfficialComponent GRAPHQL = new OfficialComponent(92, "GraphQL"); public static final OfficialComponent SPRING_ANNOTATION = new OfficialComponent(93, "spring-annotation"); + + public static final OfficialComponent HBASE = new OfficialComponent(94, "HBase"); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/InstanceConstructorInterceptor.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/InstanceConstructorInterceptor.java index 012eccc14875d3afaf25bc4699694184e83dd58d..81815d95ea5d8e52dc0eef0f2b2f35c63bae40ee 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/InstanceConstructorInterceptor.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/interceptor/enhance/InstanceConstructorInterceptor.java @@ -27,5 +27,5 @@ public interface InstanceConstructorInterceptor { /** * Called after the origin constructor invocation. */ - void onConstruct(EnhancedInstance objInst, Object[] allArguments); + void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws Throwable; } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/CollectionUtil.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/CollectionUtil.java index 7556fc3c3f11ac6ec6f9caeac573a0ab98b22493..6a524c2ea6e9a901b33a546c252b3333956b1517 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/CollectionUtil.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/CollectionUtil.java @@ -19,6 +19,7 @@ package org.apache.skywalking.apm.agent.core.util; import java.util.Arrays; +import java.util.Collection; import java.util.Map; import java.util.stream.Collectors; @@ -35,4 +36,9 @@ public final class CollectionUtil { .map(entry -> entry.getKey() + "=" + Arrays.toString(entry.getValue())) .collect(Collectors.joining("\n")); } + + @SuppressWarnings("rawtypes") + public static boolean isEmpty(Collection collection) { + return collection == null || collection.isEmpty(); + } } diff --git a/apm-sniffer/apm-sdk-plugin/hbase-1.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/hbase-1.x-plugin/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..2ea41b74f738abeddb5ab2bce1b3a5d6da353576 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hbase-1.x-plugin/pom.xml @@ -0,0 +1,47 @@ + + + + + 4.0.0 + + + org.apache.skywalking + apm-sdk-plugin + 8.2.0-SNAPSHOT + + + apm-hbase-1.x-plugin + jar + hbase-1.x-plugin + + + 1.4.9 + + + + + org.apache.hbase + hbase-client + ${hbase-client.version} + provided + + + \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/hbase-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hbase/HTableInterceptor.java b/apm-sniffer/apm-sdk-plugin/hbase-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hbase/HTableInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..363caa410d649de4d2bcac3208418ac56f558124 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hbase-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hbase/HTableInterceptor.java @@ -0,0 +1,122 @@ +/* + * 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.hbase; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.client.ClusterConnection; +import org.apache.hadoop.hbase.client.HTable; +import org.apache.hadoop.hbase.client.OperationWithAttributes; +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.tag.Tags; +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.InstanceConstructorInterceptor; +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.agent.core.util.CollectionUtil; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +public class HTableInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { + + private static final String PREFIX_OPERATION_NAME = "/HTable/"; + private static final String HBASE_DB_TYPE = "hbase"; + + @Override + @SuppressWarnings("unchecked, rawtypes") + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + boolean canTracingServer = false; + List operations = null; + OperationWithAttributes operation = null; + if (allArguments != null && allArguments.length > 0) { + if (allArguments[0] instanceof List) { + List list = (List) allArguments[0]; + if (!CollectionUtil.isEmpty(list) && list.get(0) instanceof OperationWithAttributes) { + operations = list; + canTracingServer = true; + } + } else if (allArguments[0] instanceof OperationWithAttributes) { + operation = (OperationWithAttributes) allArguments[0]; + canTracingServer = true; + } + } + AbstractSpan span; + if (canTracingServer) { + ContextCarrier contextCarrier = new ContextCarrier(); + span = ContextManager.createExitSpan(PREFIX_OPERATION_NAME + method.getName(), + contextCarrier, (String) objInst.getSkyWalkingDynamicField()); + CarrierItem next = contextCarrier.items(); + while (next.hasNext()) { + next = next.next(); + if (operation != null) { + operation.setAttribute(next.getHeadKey(), next.getHeadValue().getBytes()); + } else { + for (OperationWithAttributes o : operations) { + o.setAttribute(next.getHeadKey(), next.getHeadValue().getBytes()); + } + } + } + } else { + span = ContextManager.createExitSpan(PREFIX_OPERATION_NAME + method.getName(), + (String) objInst.getSkyWalkingDynamicField()); + } + span.setComponent(ComponentsDefine.HBASE); + Tags.DB_TYPE.set(span, HBASE_DB_TYPE); + Tags.DB_INSTANCE.set(span, ((HTable) objInst).getName().getNameAsString()); + SpanLayer.asDB(span); + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) throws Throwable { + ContextManager.stopSpan(); + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + AbstractSpan span = ContextManager.activeSpan(); + span.errorOccurred(); + span.log(t); + } + + @Override + @SuppressWarnings("rawtypes") + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws Throwable { + Configuration connection = ((ClusterConnection) allArguments[1]).getConfiguration(); + Field field = connection.getClass().getDeclaredField("overlay"); + field.setAccessible(true); + Properties properties = (Properties) field.get(connection); + for (Map.Entry entry : properties.entrySet()) { + if ("hbase.zookeeper.quorum".equals(entry.getKey())) { + objInst.setSkyWalkingDynamicField(entry.getValue().toString()); + } + } + } +} diff --git a/apm-sniffer/apm-sdk-plugin/hbase-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hbase/define/HTableInstrumentation.java b/apm-sniffer/apm-sdk-plugin/hbase-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hbase/define/HTableInstrumentation.java new file mode 100644 index 0000000000000000000000000000000000000000..af73efc9ac6f8ff9030c5c5f19fc4192664bc52b --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hbase-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/hbase/define/HTableInstrumentation.java @@ -0,0 +1,101 @@ +/* + * 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. + * + */ +/* + * 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.hbase.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.isPublic; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; +import static net.bytebuddy.matcher.ElementMatchers.takesArguments; + +public class HTableInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "org.apache.hadoop.hbase.client.HTable"; + private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.hbase.HTableInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[]{ + new ConstructorInterceptPoint() { + @Override + public ElementMatcher getConstructorMatcher() { + return takesArguments(6); + } + + @Override + public String getConstructorInterceptor() { + return INTERCEPT_CLASS; + } + } + }; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("delete").or(named("put")).or(isPublic().and(named("get"))) + .or(named("getScanner").and(takesArguments(1)) + .and(takesArgument(0, named("org.apache.hadoop.hbase.client.Scan")))); + } + + @Override() + public String getMethodsInterceptor() { + return INTERCEPT_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/hbase-1.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/hbase-1.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 0000000000000000000000000000000000000000..aad5b0238c0a6190bdd75bd49d7e1a0538493942 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/hbase-1.x-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1,17 @@ +# 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. + +hbase-1.x=org.apache.skywalking.apm.plugin.hbase.define.HTableInstrumentation \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index d481a234a5e2e4d466b8a84f8449ca30e57ed147..4d72b1a19a57b28724b5f42e7f8725ae8d706200 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -94,6 +94,7 @@ mariadb-2.x-plugin influxdb-2.x-plugin baidu-brpc-plugin + hbase-1.x-plugin graphql-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 31ebeb9f92eb70d5584bbdb19cfbe2785d6caa5a..38dded247d8ea007470f5638c2c625851649f704 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -70,6 +70,8 @@ * [SolrJ](https://github.com/apache/lucene-solr/tree/master/solr/solrj) 7.x * [Cassandra](https://github.com/apache/cassandra) 3.x * [cassandra-java-driver](https://github.com/datastax/java-driver) 3.7.0-3.7.2 + * HBase + * [hbase-client](https://github.com/apache/hbase) HTable 1.x * Service Discovery * [Netflix Eureka](https://github.com/Netflix/eureka) * Distributed Coordination 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 43cf3347f7c56c5c54bf79ec142d5b45ea8bc505..e8cd83f749eea19879c0d5b73e6d92c4ab07c62e 100755 --- a/oap-server/server-bootstrap/src/main/resources/component-libraries.yml +++ b/oap-server/server-bootstrap/src/main/resources/component-libraries.yml @@ -311,6 +311,9 @@ GraphQL: spring-annotation: id: 93 languages: Java +HBase: + id: 94 + languages: Java # .NET/.NET Core components # [3000, 4000) for C#/.NET only diff --git a/test/plugin/scenarios/hbase-scenario/bin/startup.sh b/test/plugin/scenarios/hbase-scenario/bin/startup.sh new file mode 100644 index 0000000000000000000000000000000000000000..edcca46cf9fab8e04ba2f2b73d0bb3f978ad4a54 --- /dev/null +++ b/test/plugin/scenarios/hbase-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 -Dhbase.host=${HBASE_SERVERS} -jar ${agent_opts} ${home}/../libs/hbase-scenario.jar & \ No newline at end of file diff --git a/test/plugin/scenarios/hbase-scenario/config/expectedData.yaml b/test/plugin/scenarios/hbase-scenario/config/expectedData.yaml new file mode 100644 index 0000000000000000000000000000000000000000..12dcd186eab556783c4037c52591dfdaacad9a56 --- /dev/null +++ b/test/plugin/scenarios/hbase-scenario/config/expectedData.yaml @@ -0,0 +1,96 @@ +# 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: hbase-scenario + segmentSize: nq 0 + segments: + - segmentId: not null + spans: + - operationName: /HTable/put + operationId: 0 + parentSpanId: 0 + spanId: 1 + spanLayer: Database + startTime: not null + endTime: not null + componentId: 94 + isError: false + spanType: Exit + peer: hbase-server + skipAnalysis: false + tags: + - {key: db.type, value: hbase} + - {key: db.instance, value: test_table} + - operationName: /HTable/getScanner + operationId: 0 + parentSpanId: 0 + spanId: 2 + spanLayer: Database + startTime: not null + endTime: not null + componentId: 94 + isError: false + spanType: Exit + peer: hbase-server + skipAnalysis: false + tags: + - {key: db.type, value: hbase} + - {key: db.instance, value: test_table} + - operationName: /HTable/get + operationId: 0 + parentSpanId: 0 + spanId: 3 + spanLayer: Database + startTime: not null + endTime: not null + componentId: 94 + isError: false + spanType: Exit + peer: hbase-server + skipAnalysis: false + tags: + - {key: db.type, value: hbase} + - {key: db.instance, value: test_table} + - operationName: /HTable/delete + operationId: 0 + parentSpanId: 0 + spanId: 4 + spanLayer: Database + startTime: not null + endTime: not null + componentId: 94 + isError: false + spanType: Exit + peer: hbase-server + skipAnalysis: false + tags: + - {key: db.type, value: hbase} + - {key: db.instance, value: test_table} + - operationName: /hbase-scenario/case/hbase-case + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: not null + endTime: not null + componentId: 1 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/hbase-scenario/case/hbase-case'} + - {key: http.method, value: GET} diff --git a/test/plugin/scenarios/hbase-scenario/configuration.yml b/test/plugin/scenarios/hbase-scenario/configuration.yml new file mode 100644 index 0000000000000000000000000000000000000000..952b5c9b894b1de504f7270e103cd1df2122bd59 --- /dev/null +++ b/test/plugin/scenarios/hbase-scenario/configuration.yml @@ -0,0 +1,31 @@ +# 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/hbase-scenario/case/hbase-case +healthCheck: http://localhost:8080/hbase-scenario/case/healthCheck +startScript: ./bin/startup.sh +environment: + - HBASE_SERVERS=hbase-server +depends_on: + - hbase-server +dependencies: + hbase-server: + image: harisekhon/hbase:1.4 + hostname: hbase-server + expose: + - "2181" + - "16020" \ No newline at end of file diff --git a/test/plugin/scenarios/hbase-scenario/pom.xml b/test/plugin/scenarios/hbase-scenario/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..bcdae2498ec0aaf5e5270518d4e9ba605c4f71db --- /dev/null +++ b/test/plugin/scenarios/hbase-scenario/pom.xml @@ -0,0 +1,136 @@ + + + + 4.0.0 + + org.apache.skywalking + hbase-scenario + 5.0.0 + + + UTF-8 + 1.4.9 + ${test.framework.version} + 2.6.2 + 4.3.8.RELEASE + 1.5.2.RELEASE + + + skywalking-hbase-scenario + + + + org.apache.hbase + hbase-client + ${test.framework.version} + + + org.slf4j + * + + + log4j + * + + + + + + org.springframework.boot + spring-boot-starter + ${spring-boot-version} + + + org.apache.logging.log4j + log4j-api + ${log4j.version} + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + + + org.apache.logging.log4j + log4j-slf4j-impl + ${log4j.version} + + + org.apache.logging.log4j + log4j-jcl + ${log4j.version} + + + org.springframework.boot + spring-boot-starter-tomcat + ${spring-boot-version} + + + org.springframework.boot + spring-boot-starter-web + ${spring-boot-version} + + + + + hbase-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/ + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/hbase-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/hbase-scenario/src/main/assembly/assembly.xml new file mode 100644 index 0000000000000000000000000000000000000000..200cb1c44cd2a186ea3e80589c07dcfdba167e03 --- /dev/null +++ b/test/plugin/scenarios/hbase-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/hbase-scenario.jar + ./libs + 0775 + + + diff --git a/test/plugin/scenarios/hbase-scenario/src/main/java/org/apache/skywalking/apm/testcase/hbase/Application.java b/test/plugin/scenarios/hbase-scenario/src/main/java/org/apache/skywalking/apm/testcase/hbase/Application.java new file mode 100644 index 0000000000000000000000000000000000000000..e7cc5e42c33ce5d1112f402078b20138b2270b31 --- /dev/null +++ b/test/plugin/scenarios/hbase-scenario/src/main/java/org/apache/skywalking/apm/testcase/hbase/Application.java @@ -0,0 +1,34 @@ +/* + * 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.hbase; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + try { + SpringApplication.run(Application.class, args); + } catch (Exception e) { + // Never do this + } + } +} diff --git a/test/plugin/scenarios/hbase-scenario/src/main/java/org/apache/skywalking/apm/testcase/hbase/controller/HBaseController.java b/test/plugin/scenarios/hbase-scenario/src/main/java/org/apache/skywalking/apm/testcase/hbase/controller/HBaseController.java new file mode 100644 index 0000000000000000000000000000000000000000..a14072ef3f10b6de78f67595ca41c09e0117e0c6 --- /dev/null +++ b/test/plugin/scenarios/hbase-scenario/src/main/java/org/apache/skywalking/apm/testcase/hbase/controller/HBaseController.java @@ -0,0 +1,106 @@ +/* + * 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.hbase.controller; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.*; +import org.apache.hadoop.hbase.client.*; +import org.apache.hadoop.hbase.filter.PrefixFilter; +import org.apache.hadoop.hbase.util.Bytes; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.annotation.PostConstruct; +import java.io.IOException; + +@Controller +@RequestMapping("/case") +@PropertySource("classpath:application.properties") +public class HBaseController { + + @Value("${hbase.servers:localhost}") + private String address; + + private Table table; + + @PostConstruct + public void init() { + Configuration config = HBaseConfiguration.create(); + config.set("hbase.zookeeper.quorum", address); + config.set("hbase.zookeeper.property.clientPort", "2181"); + config.set("hbase.client.ipc.pool.type", "RoundRobin"); + config.set("hbase.client.ipc.pool.size", "5"); + try { + Admin admin = ConnectionFactory.createConnection(config).getAdmin(); + if (!admin.tableExists(TableName.valueOf("test_table"))) { + HTableDescriptor tableDescriptor = new HTableDescriptor(TableName.valueOf("test_table")); + HColumnDescriptor columnDescriptor = new HColumnDescriptor("family1"); + tableDescriptor.addFamily(columnDescriptor); + admin.createTable(tableDescriptor); + } + table = admin.getConnection().getTable(TableName.valueOf("test_table")); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @RequestMapping("/hbase-case") + @ResponseBody + public String hbaseCase() { + try { + Put put = new Put("rowkey1".getBytes()); + put.addColumn("family1".getBytes(), "qualifier1".getBytes(), "value1".getBytes()); + table.put(put); + Scan s = new Scan(); + s.setFilter(new PrefixFilter(("rowkey").getBytes())); + s.setCaching(100); + ResultScanner results = table.getScanner(s); + for (Result result : results) { + if (result != null && !result.isEmpty()) { + for (Cell cell : result.rawCells()) { + String family = Bytes.toString(CellUtil.cloneFamily(cell)); + String colName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()); + String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()); + System.out.println("family: " + family + " colName:" + colName + " value:" + value); + } + } + } + Result result = table.get(new Get("rowkey1".getBytes())); + for (Cell cell : result.rawCells()) { + String family = Bytes.toString(CellUtil.cloneFamily(cell)); + String colName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()); + String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()); + System.out.println("family: " + family + " colName:" + colName + " value:" + value); + } + table.delete(new Delete("rowkey1".getBytes())); + } catch (Exception e) { + e.printStackTrace(); + } + return "Success"; + } + + @RequestMapping("/healthCheck") + @ResponseBody + public String healthCheck() { + return "healthCheck"; + } +} diff --git a/test/plugin/scenarios/hbase-scenario/src/main/resources/application.properties b/test/plugin/scenarios/hbase-scenario/src/main/resources/application.properties new file mode 100644 index 0000000000000000000000000000000000000000..91780ba35aa1c27d30546ad014049488f999a3d6 --- /dev/null +++ b/test/plugin/scenarios/hbase-scenario/src/main/resources/application.properties @@ -0,0 +1,19 @@ +# +# 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 +server.contextPath=/hbase-scenario diff --git a/test/plugin/scenarios/hbase-scenario/src/main/resources/log4j2.xml b/test/plugin/scenarios/hbase-scenario/src/main/resources/log4j2.xml new file mode 100644 index 0000000000000000000000000000000000000000..9849ed5a8abd116a9000e64cc18f05e583f21c98 --- /dev/null +++ b/test/plugin/scenarios/hbase-scenario/src/main/resources/log4j2.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/hbase-scenario/support-version.list b/test/plugin/scenarios/hbase-scenario/support-version.list new file mode 100644 index 0000000000000000000000000000000000000000..39a962d68d08554157c7fa2c8c8ebcef16b2ef04 --- /dev/null +++ b/test/plugin/scenarios/hbase-scenario/support-version.list @@ -0,0 +1,21 @@ +# 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. + +1.2.1 +1.2.6 +1.3.1 +1.4.0 +1.4.9 \ No newline at end of file