From 34e84d452a08f4497949977075693930fee4cb9a Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 9 Apr 2024 20:57:25 -1000 Subject: [PATCH 1/3] Adds support for org.mongodb:mongodb-driver-core v5 Signed-off-by: Adrian Cole --- instrumentation/mongodb/pom.xml | 43 ++++++- .../mongodb/src/it/mongodb_v3/README.md | 2 + .../mongodb/src/it/mongodb_v3/pom.xml | 120 ++++++++++++++++++ .../brave/mongodb_v3/ITMongoDBTracing.java | 17 +++ .../java/brave/mongodb/MongoDBDriver.java | 104 +++++++++++++++ .../mongodb/TraceMongoCommandListener.java | 12 +- .../java/brave/mongodb/ITMongoDBTracing.java | 2 +- .../TraceMongoCommandListenerTest.java | 36 ++---- .../servlet/internal/ServletRuntime.java | 2 +- 9 files changed, 303 insertions(+), 35 deletions(-) create mode 100644 instrumentation/mongodb/src/it/mongodb_v3/README.md create mode 100644 instrumentation/mongodb/src/it/mongodb_v3/pom.xml create mode 100644 instrumentation/mongodb/src/it/mongodb_v3/src/test/java/brave/mongodb_v3/ITMongoDBTracing.java create mode 100644 instrumentation/mongodb/src/main/java/brave/mongodb/MongoDBDriver.java diff --git a/instrumentation/mongodb/pom.xml b/instrumentation/mongodb/pom.xml index 37fd5d43c9..070ee78abd 100644 --- a/instrumentation/mongodb/pom.xml +++ b/instrumentation/mongodb/pom.xml @@ -31,16 +31,23 @@ ${project.basedir}/../.. - 3.12.14 + 5.0.1 + 3.11.0 org.mongodb - mongodb-driver + mongodb-driver-core ${mongodb-driver.version} provided + + org.mongodb + mongodb-driver-sync + ${mongodb-driver.version} + test + ${project.groupId} brave-tests @@ -55,6 +62,38 @@ + + + + maven-invoker-plugin + + + de.qaware.maven + go-offline-maven-plugin + + + package + + resolve-dependencies + + + + + + + + org.mongodb + mongodb-driver + ${old-mongodb-driver.version} + MAIN + jar + + + + + + + release diff --git a/instrumentation/mongodb/src/it/mongodb_v3/README.md b/instrumentation/mongodb/src/it/mongodb_v3/README.md new file mode 100644 index 0000000000..007dcd3128 --- /dev/null +++ b/instrumentation/mongodb/src/it/mongodb_v3/README.md @@ -0,0 +1,2 @@ +# mongodb_v3 +This tests that MongoDBTracing can be used with mongodb <5 diff --git a/instrumentation/mongodb/src/it/mongodb_v3/pom.xml b/instrumentation/mongodb/src/it/mongodb_v3/pom.xml new file mode 100644 index 0000000000..f4604717cd --- /dev/null +++ b/instrumentation/mongodb/src/it/mongodb_v3/pom.xml @@ -0,0 +1,120 @@ + + + + 4.0.0 + + @project.groupId@ + mongodb_v3 + @project.version@ + mongodb_v3 + + + UTF-8 + UTF-8 + + 1.8 + 1.8 + + + + + org.mongodb + mongodb-driver + @old-mongodb-driver.version@ + provided + + + + @project.groupId@ + brave-instrumentation-mongodb + @project.version@ + + + + @project.groupId@ + brave-tests + @project.version@ + + + + org.junit.jupiter + junit-jupiter + @junit-jupiter.version@ + + + org.mockito + mockito-junit-jupiter + @mockito.version@ + + + + org.apache.logging.log4j + log4j-slf4j-impl + @log4j.version@ + + + org.apache.logging.log4j + log4j-core + @log4j.version@ + + + org.testcontainers + junit-jupiter + @testcontainers.version@ + + + + + @project.build.testSourceDirectory@ + + + @project.basedir@/src/test/resources + + + + + maven-compiler-plugin + @maven-compiler-plugin.version@ + + + **/IT*.java + + + + + + maven-surefire-plugin + @maven-surefire-plugin.version@ + + true + + **/IT*.java + + + false + + false + + false + + + + + diff --git a/instrumentation/mongodb/src/it/mongodb_v3/src/test/java/brave/mongodb_v3/ITMongoDBTracing.java b/instrumentation/mongodb/src/it/mongodb_v3/src/test/java/brave/mongodb_v3/ITMongoDBTracing.java new file mode 100644 index 0000000000..12b3b51b52 --- /dev/null +++ b/instrumentation/mongodb/src/it/mongodb_v3/src/test/java/brave/mongodb_v3/ITMongoDBTracing.java @@ -0,0 +1,17 @@ +/* + * Copyright 2013-2024 The OpenZipkin 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 brave.mongodb_v3; + +class ITMongoDBTracing extends brave.mongodb.ITMongoDBTracing { +} diff --git a/instrumentation/mongodb/src/main/java/brave/mongodb/MongoDBDriver.java b/instrumentation/mongodb/src/main/java/brave/mongodb/MongoDBDriver.java new file mode 100644 index 0000000000..2c88f79c42 --- /dev/null +++ b/instrumentation/mongodb/src/main/java/brave/mongodb/MongoDBDriver.java @@ -0,0 +1,104 @@ +/* + * Copyright 2013-2024 The OpenZipkin 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 brave.mongodb; + +import brave.Span; +import com.mongodb.ServerAddress; +import java.lang.reflect.Method; +import java.net.InetSocketAddress; + +import static brave.internal.Throwables.propagateIfFatal; + +/** + * Access to MongoDB version-specific features + * + *

Originally designed by OkHttp team, derived from {@code okhttp3.internal.platform.Platform} + */ +class MongoDBDriver { + private static final MongoDBDriver MONGO_DB_DRIVER = findMongoDBDriver(); + + /** adds the remote IP and port to the span */ + void setRemoteIpAndPort(Span span, ServerAddress address) { + // default to no-op instead of crash on future drift + } + + MongoDBDriver() { + } + + public static MongoDBDriver get() { + return MONGO_DB_DRIVER; + } + + /** + * Attempt to match the driver version from two known patterns: + * + *

    + *
  1. org.mongodb:mongodb-driver - 3.x
  2. + *
  3. org.mongodb:mongodb-driver-core - 5.x
  4. + *
+ */ + private static MongoDBDriver findMongoDBDriver() { + try { + Method getHost = ServerAddress.class.getMethod("getHost"); + Method getPort = ServerAddress.class.getMethod("getPort"); + return new Driver5x(getHost, getPort); + } catch (NoSuchMethodException e) { + // not 5.x + } + try { + return new Driver3x(ServerAddress.class.getMethod("getSocketAddress")); + } catch (NoSuchMethodException e) { + // unknown version + } + + // Unknown + return new MongoDBDriver(); + } + + static final class Driver3x extends MongoDBDriver { + final Method getSocketAddress; + + Driver3x(Method getSocketAddress) { + this.getSocketAddress = getSocketAddress; + } + + @Override void setRemoteIpAndPort(Span span, ServerAddress serverAddress) { + try { + InetSocketAddress socketAddress = + (InetSocketAddress) getSocketAddress.invoke(serverAddress); + span.remoteIpAndPort(socketAddress.getAddress().getHostAddress(), socketAddress.getPort()); + } catch (Throwable t) { + propagateIfFatal(t); + } + } + } + + static final class Driver5x extends MongoDBDriver { + final Method getHost, getPort; + + Driver5x(Method getHost, Method getPort) { + this.getHost = getHost; + this.getPort = getPort; + } + + @Override void setRemoteIpAndPort(Span span, ServerAddress serverAddress) { + try { + span.remoteIpAndPort((String) getHost.invoke(serverAddress), + (int) getPort.invoke(serverAddress)); + } catch (Throwable t) { + propagateIfFatal(t); + } + } + } +} diff --git a/instrumentation/mongodb/src/main/java/brave/mongodb/TraceMongoCommandListener.java b/instrumentation/mongodb/src/main/java/brave/mongodb/TraceMongoCommandListener.java index 51e6adfc0d..a7d9b6d070 100644 --- a/instrumentation/mongodb/src/main/java/brave/mongodb/TraceMongoCommandListener.java +++ b/instrumentation/mongodb/src/main/java/brave/mongodb/TraceMongoCommandListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2023 The OpenZipkin Authors + * Copyright 2013-2024 The OpenZipkin 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 @@ -35,7 +35,7 @@ /** * A MongoDB command listener that will report via Brave how long each command takes and other * information about the commands. - * + *

* See RATIONALE.md * for implementation notes. */ @@ -87,13 +87,7 @@ final class TraceMongoCommandListener implements CommandListener { span.tag("mongodb.cluster_id", connectionId.getServerId().getClusterId().getValue()); } - try { - InetSocketAddress socketAddress = - connectionDescription.getServerAddress().getSocketAddress(); - span.remoteIpAndPort(socketAddress.getAddress().getHostAddress(), socketAddress.getPort()); - } catch (MongoSocketException ignored) { - - } + MongoDBDriver.get().setRemoteIpAndPort(span, connectionDescription.getServerAddress()); } span.start(); diff --git a/instrumentation/mongodb/src/test/java/brave/mongodb/ITMongoDBTracing.java b/instrumentation/mongodb/src/test/java/brave/mongodb/ITMongoDBTracing.java index 08759fc99a..a65d090576 100644 --- a/instrumentation/mongodb/src/test/java/brave/mongodb/ITMongoDBTracing.java +++ b/instrumentation/mongodb/src/test/java/brave/mongodb/ITMongoDBTracing.java @@ -49,7 +49,7 @@ @Tag("docker") @Testcontainers(disabledWithoutDocker = true) @Timeout(60) -class ITMongoDBTracing extends ITRemote { +public class ITMongoDBTracing extends ITRemote { // public for invoker test static final String DATABASE_NAME = "myDatabase"; static final String COLLECTION_NAME = "myCollection"; static final String INVALID_COLLECTION_NAME = "?.$"; diff --git a/instrumentation/mongodb/src/test/java/brave/mongodb/TraceMongoCommandListenerTest.java b/instrumentation/mongodb/src/test/java/brave/mongodb/TraceMongoCommandListenerTest.java index 982873377f..3a818dff56 100644 --- a/instrumentation/mongodb/src/test/java/brave/mongodb/TraceMongoCommandListenerTest.java +++ b/instrumentation/mongodb/src/test/java/brave/mongodb/TraceMongoCommandListenerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2023 The OpenZipkin Authors + * Copyright 2013-2024 The OpenZipkin 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 @@ -38,6 +38,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @@ -225,33 +227,23 @@ void verifyCommandStartedMocks() { } CommandStartedEvent createCommandStartedEvent() { - return new CommandStartedEvent( - 1, - createConnectionDescription(), - "dbName", - "insert", - LONG_COMMAND - ); + CommandStartedEvent event = mock(CommandStartedEvent.class); + lenient().when(event.getRequestId()).thenReturn(1); + lenient().when(event.getConnectionDescription()).thenReturn(createConnectionDescription()); + when(event.getDatabaseName()).thenReturn("dbName"); + lenient().when(event.getCommandName()).thenReturn("insert"); + lenient().when(event.getCommand()).thenReturn(LONG_COMMAND); + return event; } CommandSucceededEvent createCommandSucceededEvent() { - return new CommandSucceededEvent( - 1, - createConnectionDescription(), - "insert", - new BsonDocument(), - 1000 - ); + return mock(CommandSucceededEvent.class); } CommandFailedEvent createCommandFailedEvent(Throwable throwable) { - return new CommandFailedEvent( - 1, - createConnectionDescription(), - "insert", - 2000, - throwable - ); + CommandFailedEvent event = mock(CommandFailedEvent.class); + lenient().when(event.getThrowable()).thenReturn(throwable); + return event; } ConnectionDescription createConnectionDescription() { diff --git a/instrumentation/servlet/src/main/java/brave/servlet/internal/ServletRuntime.java b/instrumentation/servlet/src/main/java/brave/servlet/internal/ServletRuntime.java index 266c456d3f..009e76e3df 100644 --- a/instrumentation/servlet/src/main/java/brave/servlet/internal/ServletRuntime.java +++ b/instrumentation/servlet/src/main/java/brave/servlet/internal/ServletRuntime.java @@ -69,7 +69,7 @@ private static ServletRuntime findServletRuntime() { try { Class.forName("javax.servlet.AsyncEvent"); HttpServletRequest.class.getMethod("isAsyncStarted"); - return new Servlet3(); // intentionally doesn't not access the type prior to the above guard + return new Servlet3(); // intentionally doesn't access the type prior to the above guard } catch (NoSuchMethodException e) { // pre Servlet v3 } catch (ClassNotFoundException e) { From 018f6b697c59cf4134a8cf05f080c2fb7e838db1 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Wed, 10 Apr 2024 08:40:21 -1000 Subject: [PATCH 2/3] cleanup Signed-off-by: Adrian Cole --- instrumentation/mongodb/RATIONALE.md | 8 ++++ instrumentation/mongodb/pom.xml | 12 ++--- .../{mongodb_v3 => mongodb_floor}/README.md | 2 +- .../it/{mongodb_v3 => mongodb_floor}/pom.xml | 6 +-- .../brave/mongodb_v3/ITMongoDBTracing.java | 2 +- .../java/brave/mongodb/MongoDBDriver.java | 34 ++++++++----- .../java/brave/mongodb/ITMongoDBTracing.java | 48 +++++++++++-------- .../java/brave/mongodb/MongoDBDriverTest.java | 39 +++++++++++++++ 8 files changed, 108 insertions(+), 43 deletions(-) rename instrumentation/mongodb/src/it/{mongodb_v3 => mongodb_floor}/README.md (78%) rename instrumentation/mongodb/src/it/{mongodb_v3 => mongodb_floor}/pom.xml (96%) rename instrumentation/mongodb/src/it/{mongodb_v3 => mongodb_floor}/src/test/java/brave/mongodb_v3/ITMongoDBTracing.java (95%) create mode 100644 instrumentation/mongodb/src/test/java/brave/mongodb/MongoDBDriverTest.java diff --git a/instrumentation/mongodb/RATIONALE.md b/instrumentation/mongodb/RATIONALE.md index 9a68c39a58..85caadf777 100644 --- a/instrumentation/mongodb/RATIONALE.md +++ b/instrumentation/mongodb/RATIONALE.md @@ -1,5 +1,13 @@ # brave-instrumentation-mongodb rationale +## Floor JRE version + +MongoDB client 3.x has a floor JRE version of 1.6, while 4.x moved to 8. We +test on MongoDB client 3.x, despite it being 1.6 bytecode. This is a +maintenance compromise beginning with MongoDB 5.x. We believe this will be less +significant than more widely used libraries, such as Servlet or OkHttp, which +could be used in old environments or Android. + ## Default data policy We tried to make the default data policy similar to other instrumentation, such as MySQL, and also current practice from existing sites. Like other instrumentation, the policy is intentionally conservative, in efforts to avoid large diff --git a/instrumentation/mongodb/pom.xml b/instrumentation/mongodb/pom.xml index 070ee78abd..04811e3778 100644 --- a/instrumentation/mongodb/pom.xml +++ b/instrumentation/mongodb/pom.xml @@ -32,7 +32,7 @@ ${project.basedir}/../.. 5.0.1 - 3.11.0 + 3.11.0 @@ -84,7 +84,7 @@ org.mongodb mongodb-driver - ${old-mongodb-driver.version} + ${floor-mongodb-driver.version} MAIN jar @@ -98,10 +98,10 @@ release - - 1.6 - 1.6 - 6 + + 1.7 + 1.7 + 7 diff --git a/instrumentation/mongodb/src/it/mongodb_v3/README.md b/instrumentation/mongodb/src/it/mongodb_floor/README.md similarity index 78% rename from instrumentation/mongodb/src/it/mongodb_v3/README.md rename to instrumentation/mongodb/src/it/mongodb_floor/README.md index 007dcd3128..ba9fc9ec09 100644 --- a/instrumentation/mongodb/src/it/mongodb_v3/README.md +++ b/instrumentation/mongodb/src/it/mongodb_floor/README.md @@ -1,2 +1,2 @@ -# mongodb_v3 +# mongodb_floor This tests that MongoDBTracing can be used with mongodb <5 diff --git a/instrumentation/mongodb/src/it/mongodb_v3/pom.xml b/instrumentation/mongodb/src/it/mongodb_floor/pom.xml similarity index 96% rename from instrumentation/mongodb/src/it/mongodb_v3/pom.xml rename to instrumentation/mongodb/src/it/mongodb_floor/pom.xml index f4604717cd..2a69bd8b11 100644 --- a/instrumentation/mongodb/src/it/mongodb_v3/pom.xml +++ b/instrumentation/mongodb/src/it/mongodb_floor/pom.xml @@ -20,9 +20,9 @@ 4.0.0 @project.groupId@ - mongodb_v3 + mongodb_floor @project.version@ - mongodb_v3 + mongodb_floor UTF-8 @@ -36,7 +36,7 @@ org.mongodb mongodb-driver - @old-mongodb-driver.version@ + @floor-mongodb-driver.version@ provided diff --git a/instrumentation/mongodb/src/it/mongodb_v3/src/test/java/brave/mongodb_v3/ITMongoDBTracing.java b/instrumentation/mongodb/src/it/mongodb_floor/src/test/java/brave/mongodb_v3/ITMongoDBTracing.java similarity index 95% rename from instrumentation/mongodb/src/it/mongodb_v3/src/test/java/brave/mongodb_v3/ITMongoDBTracing.java rename to instrumentation/mongodb/src/it/mongodb_floor/src/test/java/brave/mongodb_v3/ITMongoDBTracing.java index 12b3b51b52..02e4c33fcd 100644 --- a/instrumentation/mongodb/src/it/mongodb_v3/src/test/java/brave/mongodb_v3/ITMongoDBTracing.java +++ b/instrumentation/mongodb/src/it/mongodb_floor/src/test/java/brave/mongodb_v3/ITMongoDBTracing.java @@ -11,7 +11,7 @@ * or implied. See the License for the specific language governing permissions and limitations under * the License. */ -package brave.mongodb_v3; +package brave.mongodb_floor; class ITMongoDBTracing extends brave.mongodb.ITMongoDBTracing { } diff --git a/instrumentation/mongodb/src/main/java/brave/mongodb/MongoDBDriver.java b/instrumentation/mongodb/src/main/java/brave/mongodb/MongoDBDriver.java index 2c88f79c42..0b23b69909 100644 --- a/instrumentation/mongodb/src/main/java/brave/mongodb/MongoDBDriver.java +++ b/instrumentation/mongodb/src/main/java/brave/mongodb/MongoDBDriver.java @@ -15,7 +15,9 @@ import brave.Span; import com.mongodb.ServerAddress; -import java.lang.reflect.Method; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.net.InetSocketAddress; import static brave.internal.Throwables.propagateIfFatal; @@ -49,16 +51,21 @@ public static MongoDBDriver get() { * */ private static MongoDBDriver findMongoDBDriver() { + MethodHandles.Lookup lookup = MethodHandles.lookup(); try { - Method getHost = ServerAddress.class.getMethod("getHost"); - Method getPort = ServerAddress.class.getMethod("getPort"); + MethodHandle getHost = + lookup.findVirtual(ServerAddress.class, "getHost", MethodType.methodType(String.class)); + MethodHandle getPort = + lookup.findVirtual(ServerAddress.class, "getPort", MethodType.methodType(int.class)); return new Driver5x(getHost, getPort); - } catch (NoSuchMethodException e) { + } catch (NoSuchMethodException | IllegalAccessException e) { // not 5.x } try { - return new Driver3x(ServerAddress.class.getMethod("getSocketAddress")); - } catch (NoSuchMethodException e) { + MethodHandle getSocketAddress = lookup.findVirtual(ServerAddress.class, "getSocketAddress", + MethodType.methodType(InetSocketAddress.class)); + return new Driver3x(getSocketAddress); + } catch (NoSuchMethodException | IllegalAccessException e) { // unknown version } @@ -67,16 +74,16 @@ private static MongoDBDriver findMongoDBDriver() { } static final class Driver3x extends MongoDBDriver { - final Method getSocketAddress; + final MethodHandle getSocketAddress; - Driver3x(Method getSocketAddress) { + Driver3x(MethodHandle getSocketAddress) { this.getSocketAddress = getSocketAddress; } @Override void setRemoteIpAndPort(Span span, ServerAddress serverAddress) { try { InetSocketAddress socketAddress = - (InetSocketAddress) getSocketAddress.invoke(serverAddress); + (InetSocketAddress) getSocketAddress.invokeExact(serverAddress); span.remoteIpAndPort(socketAddress.getAddress().getHostAddress(), socketAddress.getPort()); } catch (Throwable t) { propagateIfFatal(t); @@ -85,17 +92,18 @@ static final class Driver3x extends MongoDBDriver { } static final class Driver5x extends MongoDBDriver { - final Method getHost, getPort; + final MethodHandle getHost, getPort; - Driver5x(Method getHost, Method getPort) { + Driver5x(MethodHandle getHost, MethodHandle getPort) { this.getHost = getHost; this.getPort = getPort; } @Override void setRemoteIpAndPort(Span span, ServerAddress serverAddress) { try { - span.remoteIpAndPort((String) getHost.invoke(serverAddress), - (int) getPort.invoke(serverAddress)); + String host = (String) getHost.invokeExact(serverAddress); + int port = (int) getPort.invokeExact(serverAddress); + span.remoteIpAndPort(host, port); } catch (Throwable t) { propagateIfFatal(t); } diff --git a/instrumentation/mongodb/src/test/java/brave/mongodb/ITMongoDBTracing.java b/instrumentation/mongodb/src/test/java/brave/mongodb/ITMongoDBTracing.java index a65d090576..59584c224e 100644 --- a/instrumentation/mongodb/src/test/java/brave/mongodb/ITMongoDBTracing.java +++ b/instrumentation/mongodb/src/test/java/brave/mongodb/ITMongoDBTracing.java @@ -28,7 +28,7 @@ import com.mongodb.client.internal.MongoClientImpl; import com.mongodb.connection.ClusterId; import com.mongodb.event.CommandListener; -import java.lang.reflect.Field; +import java.lang.invoke.VarHandle; import org.bson.BsonDocument; import org.bson.BsonString; import org.bson.Document; @@ -41,6 +41,9 @@ import org.testcontainers.junit.jupiter.Testcontainers; import static brave.Span.Kind.CLIENT; +import static java.lang.invoke.MethodHandles.Lookup; +import static java.lang.invoke.MethodHandles.lookup; +import static java.lang.invoke.MethodHandles.privateLookupIn; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.entry; @@ -72,13 +75,13 @@ public class ITMongoDBTracing extends ITRemote { // public for invoker test } @BeforeEach void getClusterId() throws Exception { - // TODO: Figure out an easier way to get this! - Field clusterIdField = - Class.forName("com.mongodb.internal.connection.BaseCluster").getDeclaredField("clusterId"); - - clusterIdField.setAccessible(true); - ClusterId clusterId = - (ClusterId) clusterIdField.get(((MongoClientImpl) mongoClient).getCluster()); + // Object because the type changed between 3.x and 5.x + Object cluster = ((MongoClientImpl) mongoClient).getCluster(); + // Before 5.x, there is no public API to get the clusterId. + Class clazz = Class.forName("com.mongodb.internal.connection.BaseCluster"); + Lookup lookup = privateLookupIn(clazz, lookup()); + VarHandle clusterIdHandle = lookup.findVarHandle(clazz, "clusterId", ClusterId.class); + ClusterId clusterId = (ClusterId) clusterIdHandle.get(cluster); this.clusterId = clusterId.getValue(); } @@ -108,11 +111,12 @@ public class ITMongoDBTracing extends ITRemote { // public for invoker test mongoCursor.next(); // Name extracted from {"find": "myCollection"} - assertThat(testSpanHandler.takeRemoteSpan(CLIENT).name()).isEqualTo("find " + COLLECTION_NAME); + assertThat(testSpanHandler.takeRemoteSpan(CLIENT).name()) + .isEqualTo("find " + COLLECTION_NAME); // Name extracted from {"getMore": , "collection": "myCollection"} - assertThat(testSpanHandler.takeRemoteSpan(CLIENT).name()).isEqualTo( - "getMore " + COLLECTION_NAME); + assertThat(testSpanHandler.takeRemoteSpan(CLIENT).name()) + .isEqualTo("getMore " + COLLECTION_NAME); } /** @@ -143,8 +147,10 @@ public class ITMongoDBTracing extends ITRemote { // public for invoker test executeFind(COLLECTION_NAME); assertThat(testSpanHandler.takeRemoteSpan(CLIENT).tags()).containsOnly( - entry("mongodb.collection", COLLECTION_NAME), entry("mongodb.command", "find"), - entry("mongodb.cluster_id", clusterId)); + entry("mongodb.collection", COLLECTION_NAME), + entry("mongodb.command", "find"), + entry("mongodb.cluster_id", clusterId) + ); } @Test void addsTagsForLargePayloadCommand() { @@ -155,20 +161,24 @@ public class ITMongoDBTracing extends ITRemote { // public for invoker test database.getCollection("largeCollection").insertOne(largeDocument); assertThat(testSpanHandler.takeRemoteSpan(CLIENT).tags()).containsOnly( - entry("mongodb.collection", "largeCollection"), entry("mongodb.command", "insert"), - entry("mongodb.cluster_id", clusterId)); + entry("mongodb.collection", "largeCollection"), + entry("mongodb.command", "insert"), + entry("mongodb.cluster_id", clusterId) + ); } @Test void reportsServerAddress() { executeFind(COLLECTION_NAME); - assertThat(testSpanHandler.takeRemoteSpan(CLIENT).remoteServiceName()).isEqualTo( - "mongodb-" + DATABASE_NAME); + MutableSpan span = testSpanHandler.takeRemoteSpan(CLIENT); + assertThat(span.remoteServiceName()).isEqualTo("mongodb-" + DATABASE_NAME); + assertThat(span.remoteIp()).isEqualTo(mongo.host()); + assertThat(span.remotePort()).isEqualTo(mongo.port()); } @Test void setsError() { - assertThatThrownBy(() -> executeFind(INVALID_COLLECTION_NAME)).isInstanceOf( - MongoQueryException.class); + assertThatThrownBy(() -> executeFind(INVALID_COLLECTION_NAME)) + .isInstanceOf(MongoQueryException.class); // the error the interceptor receives is a MongoCommandException! testSpanHandler.takeRemoteSpanWithErrorMessage(CLIENT, ".*InvalidNamespace.*"); diff --git a/instrumentation/mongodb/src/test/java/brave/mongodb/MongoDBDriverTest.java b/instrumentation/mongodb/src/test/java/brave/mongodb/MongoDBDriverTest.java new file mode 100644 index 0000000000..2bc19a1006 --- /dev/null +++ b/instrumentation/mongodb/src/test/java/brave/mongodb/MongoDBDriverTest.java @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2024 The OpenZipkin 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 brave.mongodb; + +import brave.Span; +import com.mongodb.ServerAddress; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class MongoDBDriverTest { + @Mock ServerAddress serverAddress; + @Mock Span span; + + @Test void setRemoteIpAndPort() { + when(serverAddress.getHost()).thenReturn("127.0.0.1"); + when(serverAddress.getPort()).thenReturn(27017); + + MongoDBDriver.get().setRemoteIpAndPort(span, serverAddress); + + verify(span).remoteIpAndPort("127.0.0.1", 27017); + } +} From cec6b87caed593bf7091a73affe5cf91637523ce Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Wed, 10 Apr 2024 09:43:36 -1000 Subject: [PATCH 3/3] ip address Signed-off-by: Adrian Cole --- .../mongodb/src/test/java/brave/mongodb/MongoDBContainer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/instrumentation/mongodb/src/test/java/brave/mongodb/MongoDBContainer.java b/instrumentation/mongodb/src/test/java/brave/mongodb/MongoDBContainer.java index d5c4556f38..237f20643e 100644 --- a/instrumentation/mongodb/src/test/java/brave/mongodb/MongoDBContainer.java +++ b/instrumentation/mongodb/src/test/java/brave/mongodb/MongoDBContainer.java @@ -66,8 +66,9 @@ MongoClientSettings.Builder mongoClientSettingsBuilder() { new ServerAddress(host(), port())))); } + /** Return an IP address to ensure remote IP checks work. */ String host() { - return getHost(); + return "127.0.0.1"; } int port() {