[JAVA-829] When using a different port for a localhost, the driver is defaulting back to port 27017 when GMongo is built with ServerAddress objects Created: 17/May/13 Updated: 28/May/13 Resolved: 28/May/13 |
|
| Status: | Closed |
| Project: | Java Driver |
| Component/s: | Connection Management |
| Affects Version/s: | 2.10.1 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Scott Roberts | Assignee: | Unassigned |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Environment: |
Windows 7, Java 7 |
||
| Attachments: |
|
| Description |
|
When connecting to a port other than 27017 on localhost, the GMongo driver will not work and default back to 27017 if using an array of ServerAddress objects. See code below. The last println prints the same as the second. It should print the same as the first. @Grab(group='org.mongodb', module='mongo-java-driver', version='2.10.1') import com.mongodb.* //tunnels to another mongo instance //my actual local //BUG - try to do connect to remote cluster (29017 is the same as connected to above) |
| Comments |
| Comment by Jeffrey Yemin [ 28/May/13 ] |
|
OK, we'll work on the log messages for this. Thanks for diagnosing. |
| Comment by Scott Roberts [ 28/May/13 ] |
|
I guess if that's how it's supposed to work. May be nice to get an error/warning at least if the seed doesn't resolve the same as the remote. It was a bit opaque to have the driver connecting to the server entries rather than the one's I gave it. |
| Comment by Jeffrey Yemin [ 28/May/13 ] |
|
OK, I see. So ok to close this? |
| Comment by Scott Roberts [ 28/May/13 ] |
|
Ok, so what's happening in the second scenario is that the server is passing back DNS names that I have added in my hosts file to point to localhost (because there is a firewall between my dev machine and the db, thus the tunnel). The names passed back reference 27017 since they don't have to do any tunnel shenanigans to talk to each other. When those names come back and resolve, they resolve to my local database. So in any testing that I do between my local machine and a firewalled remote db should be only connecting to the master, not the replica set. |
| Comment by Jeffrey Yemin [ 28/May/13 ] |
|
There is a very big difference in behavior between the constructor that takes a single ServerAddress and the one that takes a List<ServerAddress>. In the latter case, the List is treated as a seed list to the replica set, and the driver will attempt to discover the other members of the replica set, based on calls to the ismaster command for each member of the seed list. It's for this reason that the driver will use the host names as provided by the response to the ismaster command. The constructor that takes a single ServerAddress should only be used if you are either connecting to a standalone, a single mongos, or, in rare cases, a single member of a replica set. The latter is typically only done if you are doing some administrative tasks where you know exactly which server you want to connect to (e.g., to run the compact command on it). That said, I agree with your last assertion, and I'm still not sure what's going on that would cause you to see those results. We will try to reproduce, but off hand I don't see how the driver would end up connecting to localhost:27017. Does the server that you're running on have network access to tldod01, tldod02, and tldod03? Also, can you please provide application logs? The driver logs a bunch of messages about the replica set discovery process. |
| Comment by Scott Roberts [ 28/May/13 ] |
|
To a user of the driver, I don't think the expectation is that these two would (or could) provide different results. Mongo mongo = new Mongo("localhost",29017); Mongo mongo3 = new Mongo(Arrays.asList(new ServerAddress("localhost",29017))); |
| Comment by Scott Roberts [ 28/May/13 ] |
|
So are you saying this is expected? Why would I even add servers to a connection list if the driver doesn't plan on obeying them? I'd expect a list of servers to behave the same as a single server that I give to the same Mongo object. |
| Comment by Jeffrey Yemin [ 28/May/13 ] |
|
I'm not sure exactly what's going on, but this is just not going to work properly. When connecting to a replica set using the constructor that takes a List, the driver will try to connect to all members of the replica set with the DNS names that appear in db.isMaster(), regardless of the provided seed list. Tunneling is not going to work. |
| Comment by Scott Roberts [ 28/May/13 ] |
|
requested test output |
| Comment by Jeffrey Yemin [ 28/May/13 ] |
|
Please connect via the shell to both ports (mongo --port 27017, mongo --port 29017) and run db.isMaster() and rs.status(), then post all the output to this ticket. |
| Comment by Scott Roberts [ 28/May/13 ] |
|
even this simpler one breaks |
| Comment by Scott Roberts [ 28/May/13 ] |
|
This replicates the error in pure java. |
| Comment by Scott Roberts [ 28/May/13 ] |
|
Yes, I was able to replicate with a pure java program as well. See the attached code. |
| Comment by Scott Roberts [ 24/May/13 ] |
|
Gmongo is nothing more than a lightweight wrapper on the java driver. I'm out of town for the weekend, but can write some simple java code when I get back to see if I can replicate without the wrapper. It is possible that it is a gmongo issue, but given how they structure it, it would surprise me. |
| Comment by Jeffrey Yemin [ 23/May/13 ] |
|
Are you able to reproduce this using just the Java driver, without GMongo? I've never seen anything like this in the Java driver itself. |
| Comment by Scott Roberts [ 17/May/13 ] |
|
Even if you have a single in the list it connects to the wrong db. These connect to different mongo instances, but should connect to the same: mongo = new Mongo(new ServerAddress("localhost",29017)) mongo = new Mongo([new ServerAddress("localhost",29017)]) |
| Comment by Scott Roberts [ 17/May/13 ] |
|
MongoURI method seems to have same problems; this works: |
| Comment by Scott Roberts [ 17/May/13 ] |
|
To be more clear about my test setup. I have a local single node mongo instance running on 27017. I have an SSH tunnel setup on 29017, 29018, 29019 to another server. The connection to one remote works, the connection to the remote cluster connects me to my local 27017 even though I've specified other ports. |
| Comment by Scott Roberts [ 17/May/13 ] |
|
note that even if the first example is changed to a single ServerAddress it still does the same thing. //tunnels to another mongo instance //my actual local //try to do connect to remote cluster (29017 is the same as connected to above) |