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();
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
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.
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
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.
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.