[JAVA-3873] MongoClient - how to get the list of the servers? Created: 28/Oct/20  Updated: 27/Oct/23  Resolved: 24/Nov/20

Status: Closed
Project: Java Driver
Component/s: API, Monitoring
Affects Version/s: 4.0.5
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: Emanuele Massara Assignee: Jeffrey Yemin
Resolution: Gone away Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I am trying to upgrade some opentracing libraries to use the drivers 4.0.x, in particular this project (https://github.com/opentracing-contrib/java-mongo-driver and this project (https://github.com/opentracing-contrib/java-spring-cloud).

They stopped working because they are based on this code:

if (bean instanceof MongoClient && !(bean instanceof TracingMongoClient)) {
  final MongoClient client = (MongoClient) bean;
 
  final TracingCommandListener commandListener = new TracingCommandListener.Builder(tracer).build();
 
  return new TracingMongoClient(commandListener, client.getServerAddressList(), 
                                                         client.getCredential(), 
                                                         client.getMongoClientOptions());
 }

 
But in the version 4.0.5 the method `client.getServerAddressList()` is not available anymore.

If I have the client, how am I supposed now to retrieve the list of the addresses?

The final goal is being able to have a (new?) MongoClient with a command listener, starting from a "naked" MongoClient. Is there any other way of doing that?



 Comments   
Comment by Jeffrey Yemin [ 24/Nov/20 ]

e.massara@faceit.com

Let me know if you want to pick this conversation up again.

Comment by Backlog - Core Eng Program Management Team [ 24/Nov/20 ]

There hasn't been any recent activity on this ticket, so we're resolving it. Thanks for reaching out! Please feel free to comment on this if you're able to provide more information.

Comment by Jeffrey Yemin [ 09/Nov/20 ]

Update: I looked at Open Telemetry, and it does seem that it's using byte code instrumentation to add the CommandListener, so this shouldn't be an issue going forward.

Comment by Jeffrey Yemin [ 08/Nov/20 ]

Thanks. I'm not clear though the context for the code snippet in that issue. In the method:

public MongoClient mongoClient() {
        MongoClient mc;
 
        if (tracingEnabled) {
            TracingCommandListener commandListener = new TracingCommandListener.Builder(tracer).build();
 
            mc = new TracingMongoClient(commandListener, mongoDbUri, applicationName);
        } else {
            MongoClientSettings settings = MongoClientSettings.builder().applyConnectionString(new ConnectionString(mongoDbUri)).applicationName(applicationName)
                    .readPreference(primaryPreferred()).build();
            mc = create(settings);
        }
 
        logger.info("MongoDb Url for Primary will be {}", getAllAddresses(mc));
        return mc;
    }
}

where is mongoDbUri defined and how is it initialized? I'd like to understand why you'd have access to the URI but not the MongoClientSettings. After all, applications are not even required to use a URI, and there are many configuration options that are not configurable via the URI. So I'm not sure how this solution works in the general case.

If you could arrange to get access to the MongoClientSettings, as would seem to be required anyway, then adding a tracing listener would be simple to accomplish.

I also wanted to note how other vendors (e.g. AppDynamics and Data Dog) are handling this: they use byte code instrumentation to change the behavior of the MongoClients factory methods in order to add any listeners they need. Would this be an option for Open Tracing or Open Telemetry?

Another option we could consider is to support adding listeners to already-constructed MongoClient instances. I'd prefer not to do that as currently MongoClient instances are immutable, but adding and removing listeners after construction is a fairly common pattern in software design, so it's not unreasonable.

Comment by Emanuele Massara [ 02/Nov/20 ]

Hi Jeffrey, this is the link of an issue I've opened on the opentracing java driver, mainly to keep track of this and hoping to help anyone trying to do the same thing.

 

https://github.com/opentracing-contrib/java-mongo-driver/issues/21

 

It contains the code we are currently using to make it work. It's not elegant but we have tracing back and we consider it as a temporary solution until we implement OpenTelemetry.

Comment by Jeffrey Yemin [ 30/Oct/20 ]

Hi e.massara@faceit.com

Can you send me a link to your workaround so that I can take a closer look at it?

Thanks,
Jeff

Comment by Emanuele Massara [ 30/Oct/20 ]

Thanks Jeffrey.

Our workaround for now is not to use the Spring library, to have our version of the opentracing java driver library, and to instantiate directly our TracingMongoClient instead of a MongoClient.

Our object then creates a MongoClient with the command listener and wraps entirely the MongoClient.

It's not a very Spring way to do it, but it gets the job done.

The ideal solution in my opinion would be to be able to add a listener to the existing MongoClient, dropping the Bean post processor from https://github.com/opentracing-contrib/java-spring-cloud/tree/master/instrument-starters/opentracing-spring-cloud-mongo-starter and avoiding the need of re-creating the MongoClient.

Comment by Jeffrey Yemin [ 29/Oct/20 ]

Hi e.massara@faceit.com

Thanks for letting us know about this problem. We're thinking about it, and will respond soon with suggestions.

Generated at Thu Feb 08 09:00:39 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.