The UnboundID LDAP SDK provides clients with the ability to create an in-memory directory server. An in-memory directory server is very useful for coding and performing unit tests – there is no need to install a server such as OpenLDAP or OpenDS. All one needs is Java and the standard edition of the UnboundID LDAP SDK.
LdapListenerExample.java contains code which provides a demonstration of the in-memory directory server available with the standard edition of the UnboundID LDAP SDK – click on the filename to view. The demonstration code:
- creates an in-memory directory server using the naming context specified by the
--namingContextcommand line argument that listens on the port specified by the--portcommand line argument, and creates an entry specified by the--bindDnand--bindPasswordcommand line arguments - adds schema files specified by the
--schemaFilecommand line argument (which can occur multiple times) - checks for support of each control OID specified by the
--controlOIDcommand line argument. This command line argument is optional and can be specified zero, one, or more times - adds entries that are found in the file named in the parameter to the
--ldifFilecommand line argument - reads entries from the in-memory directory server using the search parameters:
--baseObjectthe base object from which the search starts, can be specified once--scopethe scope of the search for entries, can be specified once--filterthe filter to use in the search for entries, can be specified once--attributeattributes to request from entries, can be specified zero, one, or more times. If not specified, defaults to all attributes except operational attributes.
Compile the code and execute it with something like:
java -cp CLASSPATH samplecode.LdapListenerExample \ --namingContext "DC=example,DC=com" \ --baseObject "dc=example,dc=com" \ --scope SUB \ --filter "(objectClass=*)" \ --hostname localhost \ --port 11389 \ --bindDn cn=admin \ --bindPassword password \ --schemaFile 00-core.ldif \ --schemaFile 01-pwpolicy.ldif \ --schemaFile 02-config.ldif \ --schemaFile 03-changelog.ldif \ --schemaFile 03-rfc2713.ldif \ --schemaFile 03-rfc2714.ldif \ --schemaFile 03-rfc2739.ldif \ --schemaFile 03-rfc2926.ldif \ --schemaFile 03-rfc2985.ldif \ --schemaFile 03-rfc3112.ldif \ --schemaFile 03-rfc3712.ldif \ --schemaFile 03-uddiv3.ldif \ --schemaFile 04-rfc2307bis.ldif \ --schemaFile 05-unboundid-config.ldif \ --schemaFile 06-unboundid-proxy-config.ldif \ --schemaFile 07-unboundid-sync-config.ldif \ --controlOID 1.2.840.113556.1.4.319 \ --ldifFile file.LDIF
Example contents of file.LDIF that could be used to test the server:
dn: DC=example,DC=com dc: example objectClass: top objectClass: domain dn: o=deleteMe,dc=example,dc=com objectClass: top objectClass: organization o: deleteMe dn: cn=uid,o=deleteMe,dc=example,dc=com objectClass: top objectClass: inetOrgPerson objectClass: shadowAccount uid: testUID cn: testUID cn: This is a common name for the sub entry. sn: This is the surname for the sub entry. displayName: This is name commonly displayed for the sub entry. employeeNumber: 11111 jpegPhoto:<file:///Users/terrygardner/Pictures/ldap-logo.png description: This is an entry subordinate to o=deleteMe. userPassword: password shadowMax: 11111
When the demonstration is executed, something similar to the following output should be seen:
received entry: DC=example,DC=com
received entry: o=deleteMe,dc=example,dc=com
received entry: cn=uid,o=deleteMe,dc=example,dc=com
Request Control '1.2.840.113556.1.4.319' is supported by this server.
entry: SearchResultEntry(dn='DC=example,DC=com', messageID=1, attributes={
Attribute(name=dc, values={'example'}),
Attribute(name=objectClass, values={'top', 'domain'})}, controls={})
entry: SearchResultEntry(dn='o=deleteMe,dc=example,dc=com', messageID=1, attributes={
Attribute(name=objectClass, values={'top', 'organization'}), Attribute(name=o, values={'deleteMe'})}, controls={})
entry: SearchResultEntry(dn='cn=uid,o=deleteMe,dc=example,dc=com', messageID=1, attributes={
Attribute(name=objectClass, values={'top', 'inetOrgPerson', 'organizationalPerson', 'person', 'shadowAccount'}),
Attribute(name=uid, values={'testUID'}),
Attribute(name=cn, values={'testUID', 'This is a common name for the sub entry.', 'uid'}),
Attribute(name=sn, values={'This is the surname for the sub entry.'}),
Attribute(name=displayName, values={'This is name commonly displayed for the sub entry.'}),
Attribute(name=employeeNumber, values={'11111'}),
Attribute(name=jpegPhoto, base64Values={'iVBORw0KGgoAAAANSU … gAAAABJRU5ErkJggg=='}),
Attribute(name=description, values={'This is an entry subordinate to o=deleteMe.'}),
Attribute(name=userPassword, values={'password'}),
Attribute(name=shadowMax, values={'11111'})}, controls={})