From 97e80d6de142b5751e0b3a10384acf6f010b3e8a Mon Sep 17 00:00:00 2001 From: "pg.yang" Date: Thu, 28 Mar 2024 12:56:41 +0800 Subject: [PATCH 1/7] jedis 4 cluster, sharding --- .../v4/AbstractConnectionInterceptor.java | 8 +- .../v4/ConnectionConstructorInterceptor.java | 4 +- .../jedis/v4/ConnectionInformation.java | 26 ++++ ...nectionProviderConstructorInterceptor.java | 44 +++++++ ...ctionProviderGetConnectionInterceptor.java | 60 ++++++++++ .../jedis/v4/JedisMethodInterceptor.java | 8 +- .../ConnectionProviderInstrumentation.java | 81 +++++++++++++ .../src/main/resources/skywalking-plugin.def | 3 +- .../config/expectedData.yaml | 113 +++++++++++++++++- .../jedis-4.x-scenario/configuration.yml | 19 +++ .../scenarios/jedis-4.x-scenario/pom.xml | 2 +- .../jedis/controller/CaseController.java | 34 +++++- .../jedis/controller/ClusterExecutor.java | 25 ++++ .../jedis/controller/ShardingExecutor.java | 24 ++++ .../jedis-4.x-scenario/support-version.list | 4 +- 15 files changed, 446 insertions(+), 9 deletions(-) create mode 100644 apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionInformation.java create mode 100644 apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderConstructorInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderGetConnectionInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/define/ConnectionProviderInstrumentation.java create mode 100644 test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ClusterExecutor.java create mode 100644 test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ShardingExecutor.java diff --git a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/AbstractConnectionInterceptor.java b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/AbstractConnectionInterceptor.java index 79f2f15858..a1a8a16225 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/AbstractConnectionInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/AbstractConnectionInterceptor.java @@ -18,6 +18,7 @@ package org.apache.skywalking.apm.plugin.jedis.v4; import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.tag.StringTag; 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; @@ -39,6 +40,8 @@ public abstract class AbstractConnectionInterceptor implements InstanceMethodsAr private static final String CACHE_TYPE = "Redis"; + private static final StringTag TAG_ARGS = new StringTag("actual_target"); + @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { Iterator iterator = getCommands(allArguments); @@ -49,12 +52,15 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr // Use lowercase to make config compatible with jedis-2.x-3.x plugin // Refer to `plugin.jedis.operation_mapping_read`, `plugin.jedis.operation_mapping_write` config item in agent.config String cmd = protocolCommand == null ? UNKNOWN : protocolCommand.toLowerCase(); - String peer = String.valueOf(objInst.getSkyWalkingDynamicField()); + ConnectionInformation connectionData = (ConnectionInformation) objInst.getSkyWalkingDynamicField(); + // Use cluster information to adapt Virtual Cache if exists, otherwise use real server host + String peer = StringUtil.isBlank(connectionData.getClusterNodes()) ? connectionData.getActualTarget() : connectionData.getClusterNodes(); AbstractSpan span = ContextManager.createExitSpan("Jedis/" + cmd, peer); span.setComponent(ComponentsDefine.JEDIS); readKeyIfNecessary(iterator).ifPresent(key -> Tags.CACHE_KEY.set(span, key)); Tags.CACHE_CMD.set(span, cmd); Tags.CACHE_TYPE.set(span, CACHE_TYPE); + TAG_ARGS.set(span, connectionData.getActualTarget()); parseOperation(cmd).ifPresent(op -> Tags.CACHE_OP.set(span, op)); SpanLayer.asCache(span); } diff --git a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionConstructorInterceptor.java index 825042613d..550db0072d 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionConstructorInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionConstructorInterceptor.java @@ -26,6 +26,8 @@ public class ConnectionConstructorInterceptor implements InstanceConstructorInte @Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws Throwable { HostAndPort hostAndPort = ((DefaultJedisSocketFactory) allArguments[0]).getHostAndPort(); - objInst.setSkyWalkingDynamicField(hostAndPort.getHost() + ":" + hostAndPort.getPort()); + ConnectionInformation connectionData = new ConnectionInformation(); + connectionData.setActualTarget(hostAndPort.toString()); + objInst.setSkyWalkingDynamicField(connectionData); } } diff --git a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionInformation.java b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionInformation.java new file mode 100644 index 0000000000..002deff4fc --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionInformation.java @@ -0,0 +1,26 @@ +/* + * 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.jedis.v4; + +import lombok.Data; + +@Data +public class ConnectionInformation { + private String clusterNodes; + private String actualTarget; +} diff --git a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderConstructorInterceptor.java new file mode 100644 index 0000000000..a53dfcce76 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderConstructorInterceptor.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.skywalking.apm.plugin.jedis.v4; + +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; +import redis.clients.jedis.HostAndPort; + +public class ConnectionProviderConstructorInterceptor implements InstanceConstructorInterceptor { + @Override + public void onConstruct(final EnhancedInstance objInst, final Object[] allArguments) throws Throwable { + if (objInst.getSkyWalkingDynamicField() != null) { + return; + } + Object arg = allArguments[0]; + if (arg instanceof Iterable) { + Iterable iterable = (Iterable) arg; + StringBuilder sb = new StringBuilder(); + for (Object o : iterable) { + sb.append(o.toString()).append(","); + } + objInst.setSkyWalkingDynamicField(sb.delete(sb.length() - 1, sb.length()).toString()); + } + if (arg instanceof HostAndPort) { + objInst.setSkyWalkingDynamicField(arg.toString()); + } + } + +} diff --git a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderGetConnectionInterceptor.java b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderGetConnectionInterceptor.java new file mode 100644 index 0000000000..12409de61d --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderGetConnectionInterceptor.java @@ -0,0 +1,60 @@ +/* + * 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.jedis.v4; + +import java.lang.reflect.Method; +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; + +public class ConnectionProviderGetConnectionInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(final EnhancedInstance objInst, + final Method method, + final Object[] allArguments, + final Class[] argumentsTypes, + final MethodInterceptResult result) throws Throwable { + + } + + @Override + public Object afterMethod(final EnhancedInstance objInst, + final Method method, + final Object[] allArguments, + final Class[] argumentsTypes, + final Object ret) throws Throwable { + if (ret instanceof EnhancedInstance) { + EnhancedInstance connection = (EnhancedInstance) ret; + if (connection.getSkyWalkingDynamicField() != null + && connection.getSkyWalkingDynamicField() instanceof ConnectionInformation) { + ((ConnectionInformation) connection.getSkyWalkingDynamicField()).setClusterNodes( + (String) objInst.getSkyWalkingDynamicField()); + } + } + return ret; + } + + @Override + public void handleMethodException(final EnhancedInstance objInst, + final Method method, + final Object[] allArguments, + final Class[] argumentsTypes, + final Throwable t) { + + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/JedisMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/JedisMethodInterceptor.java index 26175616e0..dcf181b3e5 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/JedisMethodInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/JedisMethodInterceptor.java @@ -18,6 +18,7 @@ package org.apache.skywalking.apm.plugin.jedis.v4; import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.tag.StringTag; 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; @@ -27,18 +28,23 @@ import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; import java.lang.reflect.Method; +import org.apache.skywalking.apm.util.StringUtil; public class JedisMethodInterceptor implements InstanceMethodsAroundInterceptor { + private static final StringTag TAG_ARGS = new StringTag("actual_target"); @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { - String peer = String.valueOf(objInst.getSkyWalkingDynamicField()); + final ConnectionInformation connectionData = (ConnectionInformation) objInst.getSkyWalkingDynamicField(); + // Use cluster information to adapt Virtual Cache if exists, otherwise use real server host + String peer = StringUtil.isBlank(connectionData.getClusterNodes()) ? connectionData.getActualTarget() : connectionData.getClusterNodes(); AbstractSpan span = ContextManager.createExitSpan("Jedis/" + method.getName(), peer); span.setComponent(ComponentsDefine.JEDIS); SpanLayer.asCache(span); Tags.CACHE_TYPE.set(span, "Redis"); Tags.CACHE_CMD.set(span, "BATCH_EXECUTE"); + TAG_ARGS.set(span, connectionData.getActualTarget()); } @Override diff --git a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/define/ConnectionProviderInstrumentation.java b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/define/ConnectionProviderInstrumentation.java new file mode 100644 index 0000000000..e37e3c119f --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/define/ConnectionProviderInstrumentation.java @@ -0,0 +1,81 @@ +/* + * 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.jedis.v4.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import net.bytebuddy.matcher.ElementMatchers; +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.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.hasSuperType; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.apache.skywalking.apm.agent.core.plugin.match.HierarchyMatch.byHierarchyMatch; + +public class ConnectionProviderInstrumentation extends AbstractWitnessInstrumentation { + + private static final String ENHANCE_INTERFACE = "redis.clients.jedis.providers.ConnectionProvider"; + private static final String CONNECTION_PROVIDER_CONSTRUCTION_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jedis.v4.ConnectionProviderConstructorInterceptor"; + private static final String CONNECTION_PROVIDER_GET_CONNECTION_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jedis.v4.ConnectionProviderGetConnectionInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return byHierarchyMatch(ENHANCE_INTERFACE); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[]{ + new ConstructorInterceptPoint() { + @Override + public ElementMatcher getConstructorMatcher() { + return ElementMatchers.takesArgument(0, named("redis.clients.jedis.HostAndPort")) + .or(ElementMatchers.takesArgument(0, hasSuperType(named("java.lang.Iterable")))); + } + + @Override + public String getConstructorInterceptor() { + return CONNECTION_PROVIDER_CONSTRUCTION_INTERCEPT_CLASS; + } + } + }; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("getConnection"); + } + + @Override + public String getMethodsInterceptor() { + return CONNECTION_PROVIDER_GET_CONNECTION_INTERCEPT_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/resources/skywalking-plugin.def index a226a135b5..ae23cce498 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/resources/skywalking-plugin.def +++ b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/resources/skywalking-plugin.def @@ -16,4 +16,5 @@ jedis-4.x=org.apache.skywalking.apm.plugin.jedis.v4.define.ConnectionInstrumentation jedis-4.x=org.apache.skywalking.apm.plugin.jedis.v4.define.PipelineInstrumentation -jedis-4.x=org.apache.skywalking.apm.plugin.jedis.v4.define.TransactionConstructorInstrumentation \ No newline at end of file +jedis-4.x=org.apache.skywalking.apm.plugin.jedis.v4.define.TransactionConstructorInstrumentation +jedis-4.x=org.apache.skywalking.apm.plugin.jedis.v4.define.ConnectionProviderInstrumentation diff --git a/test/plugin/scenarios/jedis-4.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/jedis-4.x-scenario/config/expectedData.yaml index 6be161a8b8..14e3547916 100644 --- a/test/plugin/scenarios/jedis-4.x-scenario/config/expectedData.yaml +++ b/test/plugin/scenarios/jedis-4.x-scenario/config/expectedData.yaml @@ -36,6 +36,7 @@ segmentItems: - {key: cache.key, value: a} - {key: cache.cmd, value: set} - {key: cache.type, value: Redis} + - {key: actual_target, value: 'redis-server:6379'} - {key: cache.op, value: write} - operationName: Jedis/get operationId: 0 @@ -53,6 +54,7 @@ segmentItems: - {key: cache.key, value: a} - {key: cache.cmd, value: get} - {key: cache.type, value: Redis} + - {key: actual_target, value: 'redis-server:6379'} - {key: cache.op, value: read} - operationName: Jedis/del operationId: 0 @@ -70,6 +72,7 @@ segmentItems: - {key: cache.key, value: a} - {key: cache.cmd, value: del} - {key: cache.type, value: Redis} + - {key: actual_target, value: 'redis-server:6379'} - {key: cache.op, value: write} - operationName: Jedis/syncAndReturnAll operationId: 0 @@ -86,6 +89,7 @@ segmentItems: tags: - {key: cache.type, value: Redis} - {key: cache.cmd, value: BATCH_EXECUTE} + - {key: actual_target, value: 'redis-server:6379'} - operationName: Jedis/exec operationId: 0 parentSpanId: 0 @@ -101,6 +105,7 @@ segmentItems: tags: - {key: cache.type, value: Redis} - {key: cache.cmd, value: BATCH_EXECUTE} + - {key: actual_target, value: 'redis-server:6379'} - operationName: Jedis/discard operationId: 0 parentSpanId: 0 @@ -116,6 +121,7 @@ segmentItems: tags: - {key: cache.type, value: Redis} - {key: cache.cmd, value: BATCH_EXECUTE} + - {key: actual_target, value: 'redis-server:6379'} - operationName: Jedis/xadd operationId: 0 parentSpanId: 0 @@ -132,6 +138,7 @@ segmentItems: - {key: cache.key, value: abc} - {key: cache.cmd, value: xadd} - {key: cache.type, value: Redis} + - {key: actual_target, value: 'redis-server:6379'} - {key: cache.op, value: write} - operationName: Jedis/xread operationId: 0 @@ -148,6 +155,7 @@ segmentItems: tags: - {key: cache.cmd, value: xread} - {key: cache.type, value: Redis} + - {key: actual_target, value: 'redis-server:6379'} - {key: cache.op, value: read} - operationName: Jedis/xdel operationId: 0 @@ -165,6 +173,109 @@ segmentItems: - {key: cache.key, value: abc} - {key: cache.cmd, value: xdel} - {key: cache.type, value: Redis} + - {key: actual_target, value: 'redis-server:6379'} + - {key: cache.op, value: write} + - operationName: Jedis/set + parentSpanId: 0 + spanId: 10 + spanLayer: Cache + startTime: gt 0 + endTime: gt 0 + componentId: 30 + isError: false + spanType: Exit + peer: redis-server:6379,redis-server:6379 + skipAnalysis: false + tags: + - {key: cache.key, value: x} + - {key: cache.cmd, value: set} + - {key: cache.type, value: Redis} + - {key: actual_target, value: 'redis-server:6379'} + - {key: cache.op, value: write} + - operationName: Jedis/get + parentSpanId: 0 + spanId: 11 + spanLayer: Cache + startTime: gt 0 + endTime: gt 0 + componentId: 30 + isError: false + spanType: Exit + peer: redis-server:6379,redis-server:6379 + skipAnalysis: false + tags: + - {key: cache.key, value: x} + - {key: cache.cmd, value: get} + - {key: cache.type, value: Redis} + - {key: actual_target, value: 'redis-server:6379'} + - {key: cache.op, value: read} + - operationName: Jedis/del + parentSpanId: 0 + spanId: 12 + spanLayer: Cache + startTime: gt 0 + endTime: gt 0 + componentId: 30 + isError: false + spanType: Exit + peer: redis-server:6379,redis-server:6379 + skipAnalysis: false + tags: + - {key: cache.key, value: x} + - {key: cache.cmd, value: del} + - {key: cache.type, value: Redis} + - {key: actual_target, value: 'redis-server:6379'} + - {key: cache.op, value: write} + - operationName: Jedis/set + parentSpanId: 0 + spanId: 13 + spanLayer: Cache + startTime: gt 0 + endTime: gt 0 + componentId: 30 + isError: false + spanType: Exit + peer: redis-cluster-m3:6379,redis-cluster-m2:6379,redis-cluster-m1:6379 + skipAnalysis: false + tags: + - {key: cache.key, value: x} + - {key: cache.cmd, value: set} + - {key: cache.type, value: Redis} + - {key: actual_target, value: not blank } + - {key: cache.op, value: write} + - operationName: Jedis/get + parentSpanId: 0 + spanId: 14 + spanLayer: Cache + startTime: gt 0 + endTime: gt 0 + componentId: 30 + isError: false + spanType: Exit + peer: redis-cluster-m3:6379,redis-cluster-m2:6379,redis-cluster-m1:6379 + skipAnalysis: false + tags: + - {key: cache.key, value: x} + - {key: cache.cmd, value: get} + - {key: cache.type, value: Redis} + - {key: actual_target, value: not blank} + - {key: cache.op, value: read} + - operationName: Jedis/del + parentSpanId: 0 + spanId: 15 + spanLayer: Cache + startTime: gt 0 + endTime: gt 0 + componentId: 30 + isError: false + spanType: Exit + peer: redis-cluster-m3:6379,redis-cluster-m2:6379,redis-cluster-m1:6379 + skipAnalysis: false + tags: + - {key: cache.key, value: x} + - {key: cache.cmd, value: del} + - {key: cache.type, value: Redis} + - {key: actual_target, value: not blank } - {key: cache.op, value: write} - operationName: GET:/jedis-scenario/case/jedis-scenario operationId: 0 @@ -181,4 +292,4 @@ segmentItems: tags: - {key: url, value: 'http://localhost:8080/jedis-scenario/case/jedis-scenario'} - {key: http.method, value: GET} - - {key: http.status_code, value: '200'} \ No newline at end of file + - {key: http.status_code, value: '200'} diff --git a/test/plugin/scenarios/jedis-4.x-scenario/configuration.yml b/test/plugin/scenarios/jedis-4.x-scenario/configuration.yml index 79dfda5c0b..e340adec0d 100644 --- a/test/plugin/scenarios/jedis-4.x-scenario/configuration.yml +++ b/test/plugin/scenarios/jedis-4.x-scenario/configuration.yml @@ -21,8 +21,27 @@ startScript: ./bin/startup.sh environment: - REDIS_HOST=redis-server - REDIS_PORT=6379 + - REDIS_CLUSTER_M1_HOST=redis-cluster-m1 + - REDIS_CLUSTER_M1_PORT=6379 + - REDIS_CLUSTER_M2_HOST=redis-cluster-m2 + - REDIS_CLUSTER_M2_PORT=6379 + - REDIS_CLUSTER_M3_HOST=redis-cluster-m3 + - REDIS_CLUSTER_M3_PORT=6379 + dependencies: redis-server: image: redis:7.0.4 hostname: redis-server + redis-cluster-m1: + image: redis:7.2.4 + hostname: redis-cluster-m1 + command: sh -c " printf '%s\\n' 'port 6379'>> /etc/redis.conf && printf '%s\\n' 'cluster-enabled yes'>> /etc/redis.conf && printf '%s\\n' 'cluster-config-file nodes.conf'>> /etc/redis.conf && printf '%s\\n' 'nohup redis-server /etc/redis.conf>>/tmp/redis.log &' >> /tmp/start-redis.sh && printf '%s\\n' 'while true; do printf yes | redis-cli --cluster create redis-cluster-m1:6379 redis-cluster-m2:6379 redis-cluster-m3:6379 --cluster-replicas 0 && break; done ' >> /tmp/start-redis.sh && printf '%s\\n' 'tail -f /tmp/redis.log' >> /tmp/start-redis.sh && sh /tmp/start-redis.sh" + redis-cluster-m2: + image: redis:7.2.4 + hostname: redis-cluster-m2 + command: sh -c " printf '%s\\n' 'port 6379'>> /etc/redis.conf && printf '%s\\n' 'cluster-enabled yes'>> /etc/redis.conf && printf '%s\\n' 'cluster-config-file nodes.conf'>> /etc/redis.conf && printf '%s\\n' 'nohup redis-server /etc/redis.conf>>/tmp/redis.log &' >> /tmp/start-redis.sh && printf '%s\\n' 'while true; do printf yes | redis-cli --cluster create redis-cluster-m1:6379 redis-cluster-m2:6379 redis-cluster-m3:6379 --cluster-replicas 0 && break; done ' >> /tmp/start-redis.sh && printf '%s\\n' 'tail -f /tmp/redis.log' >> /tmp/start-redis.sh && sh /tmp/start-redis.sh" + redis-cluster-m3: + image: redis:7.2.4 + hostname: redis-cluster-m3 + command: sh -c " printf '%s\\n' 'port 6379'>> /etc/redis.conf && printf '%s\\n' 'cluster-enabled yes'>> /etc/redis.conf && printf '%s\\n' 'cluster-config-file nodes.conf'>> /etc/redis.conf && printf '%s\\n' 'nohup redis-server /etc/redis.conf>>/tmp/redis.log &' >> /tmp/start-redis.sh && printf '%s\\n' 'while true; do printf yes | redis-cli --cluster create redis-cluster-m1:6379 redis-cluster-m2:6379 redis-cluster-m3:6379 --cluster-replicas 0 && break; done ' >> /tmp/start-redis.sh && printf '%s\\n' 'tail -f /tmp/redis.log' >> /tmp/start-redis.sh && sh /tmp/start-redis.sh" diff --git a/test/plugin/scenarios/jedis-4.x-scenario/pom.xml b/test/plugin/scenarios/jedis-4.x-scenario/pom.xml index b82bf254f7..d627b12c26 100644 --- a/test/plugin/scenarios/jedis-4.x-scenario/pom.xml +++ b/test/plugin/scenarios/jedis-4.x-scenario/pom.xml @@ -51,7 +51,7 @@ redis.clients jedis - ${test.framework.version} + 4.0.1 org.springframework.boot diff --git a/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/CaseController.java b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/CaseController.java index a7f570960a..fbc775e9f8 100644 --- a/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/CaseController.java +++ b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/CaseController.java @@ -18,10 +18,15 @@ package org.apache.skywalking.apm.testcase.jedis.controller; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; +import redis.clients.jedis.HostAndPort; +import redis.clients.jedis.exceptions.JedisClusterOperationException; @RestController @RequestMapping("/case") @@ -35,6 +40,21 @@ public class CaseController { @Value("${redis.port:6379}") private Integer redisPort; + @Value("${redis.cluster.m1.host:127.0.0.1}") + private String redisClusterM1Host; + @Value("${redis.cluster.m1.port:6379}") + private Integer redisClusterM1Port; + + @Value("${redis.cluster.m2.host:127.0.0.1}") + private String redisClusterM2Host; + @Value("${redis.cluster.m2.port:6379}") + private Integer redisClusterM2Port; + + @Value("${redis.cluster.m3.host:127.0.0.1}") + private String redisClusterM3Host; + @Value("${redis.cluster.m3.port:6379}") + private Integer redisClusterM3Port; + @RequestMapping("/jedis-scenario") @ResponseBody public String testcase() throws Exception { @@ -43,7 +63,6 @@ public String testcase() throws Exception { command.get("a"); command.del("a"); } - try (RedisPipelineCommandExecutor command = new RedisPipelineCommandExecutor(redisHost, redisPort)) { command.pipelineExecute(); } @@ -55,7 +74,18 @@ public String testcase() throws Exception { try (RedisStreamCommandExecutor executor = new RedisStreamCommandExecutor(redisHost, redisPort)) { executor.exec(); } - + try (ShardingExecutor shardingExecutor = new ShardingExecutor( + Arrays.asList(new HostAndPort(redisHost, redisPort), new HostAndPort(redisHost, redisPort)))) { + shardingExecutor.exec(); + } + try (ClusterExecutor clusterExecutor = new ClusterExecutor(new HashSet<>( + Arrays.asList( + new HostAndPort(redisClusterM1Host, redisClusterM1Port), + new HostAndPort(redisClusterM2Host, redisClusterM2Port), + new HostAndPort(redisClusterM3Host, redisClusterM3Port) + )))) { + clusterExecutor.exec(); + } return SUCCESS; } diff --git a/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ClusterExecutor.java b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ClusterExecutor.java new file mode 100644 index 0000000000..a2678966ef --- /dev/null +++ b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ClusterExecutor.java @@ -0,0 +1,25 @@ +package org.apache.skywalking.apm.testcase.jedis.controller; + +import java.util.Set; +import redis.clients.jedis.HostAndPort; +import redis.clients.jedis.JedisCluster; +import redis.clients.jedis.JedisPoolConfig; + +public class ClusterExecutor implements AutoCloseable { + + private final JedisCluster jedisCluster; + + public ClusterExecutor(Set jedisClusterNodes) { + this.jedisCluster = new JedisCluster(jedisClusterNodes); + } + + public void exec() { + jedisCluster.set("x", "1"); + jedisCluster.get("x"); + jedisCluster.del("x"); + } + + public void close() { + this.jedisCluster.close(); + } +} diff --git a/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ShardingExecutor.java b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ShardingExecutor.java new file mode 100644 index 0000000000..1ab1981b1c --- /dev/null +++ b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ShardingExecutor.java @@ -0,0 +1,24 @@ +package org.apache.skywalking.apm.testcase.jedis.controller; + +import java.util.List; +import redis.clients.jedis.HostAndPort; +import redis.clients.jedis.JedisSharding; + +public class ShardingExecutor implements AutoCloseable { + private JedisSharding jedisSharding; + + public ShardingExecutor(List hostAndPorts) { + this.jedisSharding = new JedisSharding(hostAndPorts); + } + + public void exec() { + jedisSharding.set("x", "1"); + jedisSharding.get("x"); + jedisSharding.del("x"); + } + + public void close() { + jedisSharding.close(); + } + +} diff --git a/test/plugin/scenarios/jedis-4.x-scenario/support-version.list b/test/plugin/scenarios/jedis-4.x-scenario/support-version.list index 209481d5b8..31258966c3 100644 --- a/test/plugin/scenarios/jedis-4.x-scenario/support-version.list +++ b/test/plugin/scenarios/jedis-4.x-scenario/support-version.list @@ -14,6 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +4.4.6 +4.3.2 4.2.3 4.1.1 -4.0.1 \ No newline at end of file +4.0.1 From aefb4dcdd0406c5ce623dcc9a1008f446218eabe Mon Sep 17 00:00:00 2001 From: "pg.yang" Date: Sat, 30 Mar 2024 21:30:34 +0800 Subject: [PATCH 2/7] Update test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ClusterExecutor.java Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../jedis/controller/ClusterExecutor.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ClusterExecutor.java b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ClusterExecutor.java index a2678966ef..a2d3aa4c82 100644 --- a/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ClusterExecutor.java +++ b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ClusterExecutor.java @@ -1,3 +1,22 @@ +/* + * 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.jedis.controller; import java.util.Set; From 870d69e23111560460b113d1d133132eff7d863a Mon Sep 17 00:00:00 2001 From: "pg.yang" Date: Sat, 30 Mar 2024 21:32:29 +0800 Subject: [PATCH 3/7] Update test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ShardingExecutor.java Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../jedis/controller/ShardingExecutor.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ShardingExecutor.java b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ShardingExecutor.java index 1ab1981b1c..dc7835c82c 100644 --- a/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ShardingExecutor.java +++ b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ShardingExecutor.java @@ -1,3 +1,22 @@ +/* + * 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.jedis.controller; import java.util.List; From 6cadea21075a329e87d9b7717ea4e86e02addb49 Mon Sep 17 00:00:00 2001 From: "pg.yang" Date: Sat, 30 Mar 2024 21:40:27 +0800 Subject: [PATCH 4/7] fomat code --- CHANGES.md | 1 + .../scenarios/jedis-4.x-scenario/pom.xml | 2 +- .../jedis/controller/CaseController.java | 2 -- .../jedis/controller/ClusterExecutor.java | 28 +++++++++---------- .../jedis/controller/ShardingExecutor.java | 27 +++++++++--------- 5 files changed, 28 insertions(+), 32 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5627ea6ad0..de3c72abe6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,6 +19,7 @@ Release Notes. * Fix a bug in Spring Cloud Gateway if HttpClientFinalizer#send does not invoke, the span created at NettyRoutingFilterInterceptor can not stop. * Fix not tracing in HttpClient v5 when HttpHost(arg[0]) is null but `RoutingSupport#determineHost` works. * Support across thread tracing for SOFA-RPC. +* Update Jedis 4.x plugin to support Sharding/Cluster model #### Documentation * Update docs to describe `expired-plugins`. diff --git a/test/plugin/scenarios/jedis-4.x-scenario/pom.xml b/test/plugin/scenarios/jedis-4.x-scenario/pom.xml index d627b12c26..b82bf254f7 100644 --- a/test/plugin/scenarios/jedis-4.x-scenario/pom.xml +++ b/test/plugin/scenarios/jedis-4.x-scenario/pom.xml @@ -51,7 +51,7 @@ redis.clients jedis - 4.0.1 + ${test.framework.version} org.springframework.boot diff --git a/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/CaseController.java b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/CaseController.java index fbc775e9f8..fd7999060a 100644 --- a/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/CaseController.java +++ b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/CaseController.java @@ -19,14 +19,12 @@ package org.apache.skywalking.apm.testcase.jedis.controller; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import redis.clients.jedis.HostAndPort; -import redis.clients.jedis.exceptions.JedisClusterOperationException; @RestController @RequestMapping("/case") diff --git a/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ClusterExecutor.java b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ClusterExecutor.java index a2d3aa4c82..8e9293e04e 100644 --- a/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ClusterExecutor.java +++ b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ClusterExecutor.java @@ -1,28 +1,26 @@ /* - * 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 + * 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 + * 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. + * 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.jedis.controller; import java.util.Set; import redis.clients.jedis.HostAndPort; import redis.clients.jedis.JedisCluster; -import redis.clients.jedis.JedisPoolConfig; public class ClusterExecutor implements AutoCloseable { diff --git a/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ShardingExecutor.java b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ShardingExecutor.java index dc7835c82c..482d942837 100644 --- a/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ShardingExecutor.java +++ b/test/plugin/scenarios/jedis-4.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/jedis/controller/ShardingExecutor.java @@ -1,22 +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 + * 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 + * 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. + * 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.jedis.controller; import java.util.List; From e13ff7297f0cf546236425f7c3c10b6472c11eb1 Mon Sep 17 00:00:00 2001 From: "pg.yang" Date: Sun, 31 Mar 2024 10:22:07 +0800 Subject: [PATCH 5/7] Update CHANGES.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 吴晟 Wu Sheng --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index de3c72abe6..eef33563e1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,7 +19,7 @@ Release Notes. * Fix a bug in Spring Cloud Gateway if HttpClientFinalizer#send does not invoke, the span created at NettyRoutingFilterInterceptor can not stop. * Fix not tracing in HttpClient v5 when HttpHost(arg[0]) is null but `RoutingSupport#determineHost` works. * Support across thread tracing for SOFA-RPC. -* Update Jedis 4.x plugin to support Sharding/Cluster model +* Update Jedis 4.x plugin to support Sharding and Cluster models. #### Documentation * Update docs to describe `expired-plugins`. From 2d095dd90e42b81ffa11816cd153f245105c9a12 Mon Sep 17 00:00:00 2001 From: "pg.yang" Date: Sun, 31 Mar 2024 10:27:32 +0800 Subject: [PATCH 6/7] update ConnectionProviderConstructorInterceptor to avoid empty Iterable --- .../jedis/v4/ConnectionProviderConstructorInterceptor.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderConstructorInterceptor.java index a53dfcce76..f46911f08e 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderConstructorInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderConstructorInterceptor.java @@ -34,7 +34,9 @@ public void onConstruct(final EnhancedInstance objInst, final Object[] allArgume for (Object o : iterable) { sb.append(o.toString()).append(","); } - objInst.setSkyWalkingDynamicField(sb.delete(sb.length() - 1, sb.length()).toString()); + if (sb.length() > 0) { + objInst.setSkyWalkingDynamicField(sb.delete(sb.length() - 1, sb.length()).toString()); + } } if (arg instanceof HostAndPort) { objInst.setSkyWalkingDynamicField(arg.toString()); From 6cb8542029108fcdb1806250a49c328418cfcb8f Mon Sep 17 00:00:00 2001 From: "pg.yang" Date: Sun, 31 Mar 2024 12:23:23 +0800 Subject: [PATCH 7/7] use Collection to instead of Iterable --- .../ConnectionProviderConstructorInterceptor.java | 15 ++++++--------- .../define/ConnectionProviderInstrumentation.java | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderConstructorInterceptor.java index f46911f08e..21939a62e9 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderConstructorInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/ConnectionProviderConstructorInterceptor.java @@ -17,8 +17,10 @@ package org.apache.skywalking.apm.plugin.jedis.v4; +import java.util.Collection; 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.util.StringUtil; import redis.clients.jedis.HostAndPort; public class ConnectionProviderConstructorInterceptor implements InstanceConstructorInterceptor { @@ -28,15 +30,10 @@ public void onConstruct(final EnhancedInstance objInst, final Object[] allArgume return; } Object arg = allArguments[0]; - if (arg instanceof Iterable) { - Iterable iterable = (Iterable) arg; - StringBuilder sb = new StringBuilder(); - for (Object o : iterable) { - sb.append(o.toString()).append(","); - } - if (sb.length() > 0) { - objInst.setSkyWalkingDynamicField(sb.delete(sb.length() - 1, sb.length()).toString()); - } + if (arg instanceof Collection) { + Collection collection = (Collection) arg; + final String[] array = collection.stream().map(Object::toString).toArray(String[]::new); + objInst.setSkyWalkingDynamicField(StringUtil.join(',', array)); } if (arg instanceof HostAndPort) { objInst.setSkyWalkingDynamicField(arg.toString()); diff --git a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/define/ConnectionProviderInstrumentation.java b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/define/ConnectionProviderInstrumentation.java index e37e3c119f..d376fb3d6a 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/define/ConnectionProviderInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-plugins/jedis-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v4/define/ConnectionProviderInstrumentation.java @@ -46,7 +46,7 @@ public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { @Override public ElementMatcher getConstructorMatcher() { return ElementMatchers.takesArgument(0, named("redis.clients.jedis.HostAndPort")) - .or(ElementMatchers.takesArgument(0, hasSuperType(named("java.lang.Iterable")))); + .or(ElementMatchers.takesArgument(0, hasSuperType(named("java.util.Collection")))); } @Override