Menu

Unable to bind to InMemoryDirectoryServer instance

2015-11-02
2015-11-03
  • Jeetendra Kukreja

    Hi I am using the following setup to set up the InMemoryDirectoryServer for component testing. However the bind call from my connection client to the test server does not succeed (timesout).

    I'm a newbie in this space so I'm probably missing something. All the documentation I have found so far talks about getting a connection to the server using the server object itself (see the code commented in the test server main) and that seems to work fine.

    Any guidance/pointers would be helpful. I really want to avoid having to set up a dedicated LDAP server instance for testing and use this neat InMemoryDirectoryServer

    // test server
    public class Main {
    public static void main(String[] args) throws Exception
    {
    InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=example,dc=com");
    config.setSchema(null);
    config.addAdditionalBindCredentials("uid=admin,ou=system,dc=example,dc=com", "secret");
    config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("default", 10390));
    InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
    ds.importFromLDIF(true, "/Users/jkukrejamac1/Desktop/test.ldif");
    ds.startListening();

    // LDAPConnection conn = ds.getConnection();
    // BindResult br = conn.bind("uid=admin,ou=system,dc=example,dc=com", "secret");
    // System.out.println(br.getResultCode());
    // conn.close();
    //
    // ds.shutDown(true);
    }
    }

    // test client
    public class Main {
    public static void main(String[] args) throws Exception
    {
    System.out.println("playground 1");
    LDAPConnection conn = new LDAPConnection("10.1.10.186", 10390);
    BindResult br = conn.bind("uid=admin,ou=system,dc=example,dc=com", "secret");
    System.out.println(br.getResultCode());
    }
    }

    // test.ldif
    dn: dc=example,dc=com
    objectclass: top
    objectclass: domain
    dc: example

    dn: ou=system,dc=example,dc=com
    objectClass: extensibleObject
    objectClass: organizationalUnit
    objectClass: top
    ou: system

    dn: ou=groups,ou=system,dc=example,dc=com
    objectClass: organizationalUnit
    objectClass: top
    ou: groups

    dn: ou=users,ou=system,dc=example,dc=com
    objectClass: organizationalUnit
    objectClass: top
    ou: users

    dn: uid=admin,ou=system,dc=example,dc=com
    objectClass: inetOrgPerson
    objectClass: organizationalPerson
    objectClass: person
    objectClass: top
    cn: system administrator
    sn: administrator
    displayName: Directory Superuser
    uid: admin
    userPassword:: c2VjcmV0

    dn: uid=user1+mail=user1@mail.com+cn=test1+sn=user1,ou=users,ou=system,dc=example,dc=com
    objectClass: top
    objectClass: inetOrgPerson
    objectClass: person
    objectClass: organizationalPerson
    cn: test1
    sn: user1
    mail: user1@mail.com
    uid: user1
    userPassword:: e3NoYX1XNnBoNU1tNVB6OEdnaVVMYlBnekczN21qOWc9

    dn: cn=group1,ou=groups,ou=system,dc=example,dc=com
    objectClass: top
    objectClass: groupOfNames
    cn: group1
    member: uid=user1+mail=user1@mail.com+cn=test1+sn=user1,ou=users,ou=system,dc=example,dc=com

     
  • Neil Wilson

    Neil Wilson - 2015-11-02

    Looking at your code, I don't immediately see any problem. You don't really need to specify the additional bind credentials in the InMemoryDirectoryServerConfig if that entry already exists in the data set that you're using, but that shouldn't cause a problem (although if the passwords differ, then you'll probably end up having to use the password for the entry specifeid in the data rather than the additional bind credentials). It definitely shouldn't cause a hang. I've tested your code on my system (only changing the IP address in the client code) and it works for me just fine.

    The client code you're using has two potential places that it could hang: on trying to establish the connection, and on trying to process the bind. It might not be a bad idea to put a print statement in the client code after creating the connection to see if you get to that point. It's entirely possible that the hang could be happening in the attempt to connect rather than in the attempt to bind. Since you're trying to connect over a network address rather than over a loopback interface, is it possible that a firewall setting is preventing the packets from getting through? Does it work if you run the client and server on the same machine but use "127.0.0.1" instead of "10.1.10.186"?

    Ultimately, the best way to debug the problem is to run both the client and server from the command line and whenever the client seems to be hung, use Control+\ (or the jstack utility) to get a full thread dump from both the client and the server. This will make it possible to see exactly what each is trying to do, so we can see where the hang occurs. If the hang occurs on the connection attempt, then we should see the client trying to create a Socket. If it occurs on the bind attempt, then we should see the client waiting for the bind response, and the server stack trace will help us see whether it's in the middle of processing the bind (but somehow hung up in doing so) or not (indicating that it either didn't get the bind request or has already processed it).

    Another thing that you can do to try to diagnose the behavior is to enable debugging in the client and server by calling com.unboundid.util.Debug.setEnabled(true) at the beginning of the main method before doing anything else. This will cause the LDAP SDK to use the Java logging framework (which will dump to standard error by default, so you should see it in the console if you're running from the command line) to write debug messages about what it's doing. If you don't see anything at the default level, then you might also want to add Debug.getLogger().setLevel(Level.FINEST) to make sure you get everything.

     
  • Jeetendra Kukreja

    Thanks Neil. Good to know that the code works on your end. I've verified that the connection seems to happen correctly.

    I enabled the debug logging and changed the host to 127.0.0.1 Below is what I see. I am running this on a Mac. Any gotcha's related to that?

    Below are the log entries from the server after the LDIF read records. Do u know what the 2 connections are on the server side after I start listenting?

    Nov 03, 2015 10:27:55 AM com.unboundid.util.Debug debugConnect
    INFO: level="INFO" threadID=1 threadName="main" revision=20488 connectedTo="127.0.0.1:10390" connectionID=0
    Nov 03, 2015 10:27:56 AM com.unboundid.util.Debug debug
    INFO: level="INFO" threadID=1 threadName="main" revision=20488 message="Setting SO_TIMEOUT to connect timeout of 60000ms in LDAPConnectionReader constructor"
    Nov 03, 2015 10:27:56 AM com.unboundid.util.Debug debugConnect
    INFO: level="INFO" threadID=1 threadName="main" revision=20488 connectedTo="127.0.0.1:10390" connectionID=1
    Nov 03, 2015 10:27:56 AM com.unboundid.util.Debug debug
    INFO: level="INFO" threadID=1 threadName="main" revision=20488 message="Setting SO_TIMEOUT to connect timeout of 60000ms in LDAPConnectionReader constructor"

    Below are the log entries from the client which shows the connection was successful but the bind timedout

    Nov 03, 2015 10:33:25 AM com.unboundid.util.Debug debugConnect
    INFO: level="INFO" threadID=1 threadName="main" revision=20488 connectedTo="127.0.0.1:10390" connectionID=0
    Nov 03, 2015 10:33:25 AM com.unboundid.util.Debug debug
    INFO: level="INFO" threadID=1 threadName="main" revision=20488 message="Setting SO_TIMEOUT to connect timeout of 60000ms in LDAPConnectionReader constructor"
    Nov 03, 2015 10:33:25 AM com.unboundid.util.Debug debugLDAPRequest
    INFO: level="INFO" threadID=1 threadName="main" revision=20488 sendingLDAPRequest="SimpleBindRequest(dn='uid=admin,ou=system,dc=example,dc=com')"
    Nov 03, 2015 10:33:25 AM com.unboundid.util.Debug debugASN1Write
    INFO: level="INFO" threadID=1 threadName="main" revision=20488 writingASN1Element="3037020101603202010304257569643d61646d696e2c6f753d73797374656d2c64633d6578616d706c652c64633d636f6d8006736563726574"
    Disconnected from the target VM, address: '127.0.0.1:52257', transport: 'socket'
    Exception in thread "main" LDAPException(resultCode=85 (timeout), errorMessage='A client-side timeout was encountered while waiting 300008ms for a response to simple bind request with message ID 1 for user 'uid=admin,ou=system,dc=example,dc=com' from server 127.0.0.1:10390.')
    at com.unboundid.ldap.sdk.SimpleBindRequest.handleResponse(SimpleBindRequest.java:688)
    at com.unboundid.ldap.sdk.SimpleBindRequest.process(SimpleBindRequest.java:570)
    at com.unboundid.ldap.sdk.LDAPConnection.bind(LDAPConnection.java:2151)
    at com.unboundid.ldap.sdk.LDAPConnection.bind(LDAPConnection.java:2096)
    at com.company.Main.main(Main.java:20)

     

    Last edit: Jeetendra Kukreja 2015-11-03
  • Jeetendra Kukreja

    So I figured out my issue. It was a user error on my part of not realizing that the InMemoryDirectoryServer is running in the same thread as the rest of the server code below it. I had breakpoints in my code below the start listening portion of the server and those were blcoking my server from actually doing anything else. I've solved this by starting the server on a separate thread now. Thanks for the debug info since that helped me narrow it down.

     
  • Neil Wilson

    Neil Wilson - 2015-11-03

    I'm glad you were able to figure it out. I didn't see anything wrong with the code, nor anything helpful in the debug output, and I probably wouldn't have thought of breakpoints as a potential cause.

     

Log in to post a comment.