-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added tracing support for JedisSentinelPool (#7)
- Loading branch information
Showing
3 changed files
with
298 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
177 changes: 177 additions & 0 deletions
177
...edis-jedis/src/main/java/io/opentracing/contrib/redis/jedis/TracingJedisSentinelPool.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
/* | ||
* Copyright 2017-2018 The OpenTracing Authors | ||
* | ||
* Licensed 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 io.opentracing.contrib.redis.jedis; | ||
|
||
import java.util.Set; | ||
import java.util.function.Function; | ||
|
||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig; | ||
|
||
import io.opentracing.Tracer; | ||
import io.opentracing.contrib.redis.common.RedisSpanNameProvider; | ||
import redis.clients.jedis.Jedis; | ||
import redis.clients.jedis.JedisSentinelPool; | ||
import redis.clients.jedis.Protocol; | ||
|
||
public class TracingJedisSentinelPool extends JedisSentinelPool { | ||
|
||
private final Tracer tracer; | ||
private final boolean traceWithActiveSpanOnly; | ||
private Function<String, String> spanNameProvider; | ||
|
||
public TracingJedisSentinelPool(Tracer tracer, boolean traceWithActiveSpanOnly, String masterName, Set<String> sentinels, | ||
final GenericObjectPoolConfig poolConfig) { | ||
super(masterName, sentinels, poolConfig, Protocol.DEFAULT_TIMEOUT, null, | ||
Protocol.DEFAULT_DATABASE); | ||
this.tracer = tracer; | ||
this.traceWithActiveSpanOnly = traceWithActiveSpanOnly; | ||
spanNameProvider = RedisSpanNameProvider.OPERATION_NAME; | ||
} | ||
|
||
public TracingJedisSentinelPool(Tracer tracer, boolean traceWithActiveSpanOnly, String masterName, Set<String> sentinels) { | ||
super(masterName, sentinels, new GenericObjectPoolConfig(), Protocol.DEFAULT_TIMEOUT, null, | ||
Protocol.DEFAULT_DATABASE); | ||
this.tracer = tracer; | ||
this.traceWithActiveSpanOnly = traceWithActiveSpanOnly; | ||
spanNameProvider = RedisSpanNameProvider.OPERATION_NAME; | ||
} | ||
|
||
public TracingJedisSentinelPool(Tracer tracer, boolean traceWithActiveSpanOnly, String masterName, Set<String> sentinels, String password) { | ||
super(masterName, sentinels, new GenericObjectPoolConfig(), Protocol.DEFAULT_TIMEOUT, password); | ||
this.tracer = tracer; | ||
this.traceWithActiveSpanOnly = traceWithActiveSpanOnly; | ||
spanNameProvider = RedisSpanNameProvider.OPERATION_NAME; | ||
} | ||
|
||
public TracingJedisSentinelPool(Tracer tracer, boolean traceWithActiveSpanOnly, String masterName, Set<String> sentinels, | ||
final GenericObjectPoolConfig poolConfig, int timeout, final String password) { | ||
super(masterName, sentinels, poolConfig, timeout, password, Protocol.DEFAULT_DATABASE); | ||
this.tracer = tracer; | ||
this.traceWithActiveSpanOnly = traceWithActiveSpanOnly; | ||
spanNameProvider = RedisSpanNameProvider.OPERATION_NAME; | ||
} | ||
|
||
public TracingJedisSentinelPool(Tracer tracer, boolean traceWithActiveSpanOnly, String masterName, Set<String> sentinels, | ||
final GenericObjectPoolConfig poolConfig, final int timeout) { | ||
super(masterName, sentinels, poolConfig, timeout, null, Protocol.DEFAULT_DATABASE); | ||
this.tracer = tracer; | ||
this.traceWithActiveSpanOnly = traceWithActiveSpanOnly; | ||
spanNameProvider = RedisSpanNameProvider.OPERATION_NAME; | ||
} | ||
|
||
public TracingJedisSentinelPool(Tracer tracer, boolean traceWithActiveSpanOnly, String masterName, Set<String> sentinels, | ||
final GenericObjectPoolConfig poolConfig, final String password) { | ||
super(masterName, sentinels, poolConfig, Protocol.DEFAULT_TIMEOUT, password); | ||
this.tracer = tracer; | ||
this.traceWithActiveSpanOnly = traceWithActiveSpanOnly; | ||
spanNameProvider = RedisSpanNameProvider.OPERATION_NAME; | ||
} | ||
|
||
public TracingJedisSentinelPool(Tracer tracer, boolean traceWithActiveSpanOnly, String masterName, Set<String> sentinels, | ||
final GenericObjectPoolConfig poolConfig, int timeout, final String password, | ||
final int database) { | ||
super(masterName, sentinels, poolConfig, timeout, timeout, password, database); | ||
this.tracer = tracer; | ||
this.traceWithActiveSpanOnly = traceWithActiveSpanOnly; | ||
spanNameProvider = RedisSpanNameProvider.OPERATION_NAME; | ||
} | ||
|
||
public TracingJedisSentinelPool(Tracer tracer, boolean traceWithActiveSpanOnly, String masterName, Set<String> sentinels, | ||
final GenericObjectPoolConfig poolConfig, int timeout, final String password, | ||
final int database, Function<String, String> customSpanName) { | ||
super(masterName, sentinels, poolConfig, timeout, timeout, password, database); | ||
this.tracer = tracer; | ||
this.traceWithActiveSpanOnly = traceWithActiveSpanOnly; | ||
spanNameProvider = customSpanName; | ||
} | ||
|
||
public TracingJedisSentinelPool(Tracer tracer, boolean traceWithActiveSpanOnly, String masterName, Set<String> sentinels, | ||
final GenericObjectPoolConfig poolConfig, int timeout, final String password, | ||
final int database, final String clientName) { | ||
super(masterName, sentinels, poolConfig, timeout, timeout, password, database, clientName); | ||
this.tracer = tracer; | ||
this.traceWithActiveSpanOnly = traceWithActiveSpanOnly; | ||
spanNameProvider = RedisSpanNameProvider.OPERATION_NAME; | ||
} | ||
|
||
public TracingJedisSentinelPool(Tracer tracer, boolean traceWithActiveSpanOnly, String masterName, Set<String> sentinels, | ||
final GenericObjectPoolConfig poolConfig, final int timeout, final int soTimeout, | ||
final String password, final int database) { | ||
super(masterName, sentinels, poolConfig, timeout, soTimeout, password, database, null); | ||
this.tracer = tracer; | ||
this.traceWithActiveSpanOnly = traceWithActiveSpanOnly; | ||
spanNameProvider = RedisSpanNameProvider.OPERATION_NAME; | ||
} | ||
|
||
public TracingJedisSentinelPool(Tracer tracer, boolean traceWithActiveSpanOnly, String masterName, Set<String> sentinels, | ||
final GenericObjectPoolConfig poolConfig, final int connectionTimeout, final int soTimeout, | ||
final String password, final int database, final String clientName) { | ||
super(masterName, sentinels, poolConfig, connectionTimeout, soTimeout, password, database, clientName); | ||
this.tracer = tracer; | ||
this.traceWithActiveSpanOnly = traceWithActiveSpanOnly; | ||
spanNameProvider = RedisSpanNameProvider.OPERATION_NAME; | ||
} | ||
|
||
public TracingJedisSentinelPool(Tracer tracer, boolean traceWithActiveSpanOnly, String masterName, Set<String> sentinels, | ||
final GenericObjectPoolConfig poolConfig, final int connectionTimeout, final int soTimeout, | ||
final String password, final int database, final String clientName, Function<String, String> customSpanName) { | ||
super(masterName, sentinels, poolConfig, connectionTimeout, soTimeout, password, database, clientName); | ||
this.tracer = tracer; | ||
this.traceWithActiveSpanOnly = traceWithActiveSpanOnly; | ||
spanNameProvider = customSpanName; | ||
} | ||
|
||
@Override | ||
public Jedis getResource() { | ||
Jedis resource = super.getResource(); | ||
return new TracingJedisWrapper(resource, tracer, traceWithActiveSpanOnly); | ||
} | ||
|
||
@Override | ||
public void returnBrokenResource(final Jedis resource) { | ||
super.returnBrokenResource(unwrapResource(resource)); | ||
} | ||
|
||
@Override | ||
public void returnResource(final Jedis resource) { | ||
super.returnResource(unwrapResource(resource)); | ||
} | ||
|
||
private Jedis unwrapResource(Jedis resource) { | ||
return (resource instanceof TracingJedisSentinelPool.TracingJedisWrapper) | ||
? ((TracingJedisSentinelPool.TracingJedisWrapper) resource).getWrapped() | ||
: resource; | ||
} | ||
|
||
|
||
private class TracingJedisWrapper extends TracingJedis { | ||
private final Jedis wrapped; | ||
|
||
public TracingJedisWrapper(Jedis jedis, Tracer tracer, boolean traceWithActiveSpanOnly) { | ||
super(tracer, traceWithActiveSpanOnly, spanNameProvider); | ||
this.client = jedis.getClient(); | ||
this.wrapped = jedis; | ||
} | ||
|
||
@Override | ||
public void close() { | ||
super.close(); | ||
wrapped.close(); | ||
} | ||
|
||
public Jedis getWrapped() { | ||
return wrapped; | ||
} | ||
} | ||
} |
99 changes: 99 additions & 0 deletions
99
...-jedis/src/test/java/io/opentracing/contrib/redis/jedis/TracingJedisSentinelPoolTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/* | ||
* Copyright 2017-2018 The OpenTracing Authors | ||
* | ||
* Licensed 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 io.opentracing.contrib.redis.jedis; | ||
|
||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig; | ||
import org.junit.After; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
import io.opentracing.mock.MockSpan; | ||
import io.opentracing.mock.MockTracer; | ||
import io.opentracing.util.ThreadLocalScopeManager; | ||
import redis.clients.jedis.Jedis; | ||
import redis.clients.jedis.JedisSentinelPool; | ||
import redis.clients.jedis.Protocol; | ||
import redis.embedded.RedisSentinel; | ||
import redis.embedded.RedisServer; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
|
||
public class TracingJedisSentinelPoolTest { | ||
|
||
private MockTracer mockTracer = new MockTracer(new ThreadLocalScopeManager(), MockTracer.Propagator.TEXT_MAP); | ||
|
||
private RedisServer redisServer; | ||
|
||
private RedisSentinel redisSentinel; | ||
|
||
private static final String MASTER_NAME = "mymaster"; | ||
|
||
private Set<String> sentinels = new HashSet<String>() {{ | ||
add("127.0.0.1:" + (Protocol.DEFAULT_PORT + 1)); | ||
}}; | ||
|
||
@Before | ||
public void before() { | ||
mockTracer.reset(); | ||
|
||
redisServer = RedisServer.builder().build(); | ||
redisServer.start(); | ||
redisSentinel = RedisSentinel.builder().port(Protocol.DEFAULT_PORT + 1).build(); | ||
redisSentinel.start(); | ||
} | ||
|
||
@After | ||
public void after() { | ||
if (redisSentinel != null) { | ||
redisSentinel.stop(); | ||
} | ||
if (redisServer != null) { | ||
redisServer.stop(); | ||
} | ||
} | ||
|
||
@Test | ||
public void testSentinelPoolReturnsTracedJedis() { | ||
JedisSentinelPool pool = new TracingJedisSentinelPool(mockTracer, false, MASTER_NAME, sentinels, new GenericObjectPoolConfig()); | ||
Jedis jedis = pool.getResource(); | ||
assertEquals("OK", jedis.set("key", "value")); | ||
assertEquals("value", jedis.get("key")); | ||
|
||
jedis.close(); | ||
|
||
List<MockSpan> spans = mockTracer.finishedSpans(); | ||
assertEquals(2, spans.size()); | ||
} | ||
|
||
@Test | ||
public void testClosingTracedJedisClosesUnderlyingJedis() { | ||
JedisSentinelPool pool = new TracingJedisSentinelPool(mockTracer, false, MASTER_NAME, sentinels, new GenericObjectPoolConfig()); | ||
Jedis resource = pool.getResource(); | ||
assertEquals(1, pool.getNumActive()); | ||
|
||
resource.close(); | ||
assertEquals(0, pool.getNumActive()); | ||
assertEquals(1, pool.getNumIdle()); | ||
|
||
// ensure that resource is reused | ||
Jedis nextResource = pool.getResource(); | ||
assertEquals(1, pool.getNumActive()); | ||
assertEquals(0, pool.getNumIdle()); | ||
nextResource.close(); | ||
} | ||
} |