1616
1717package org .springframework .ldap .test .unboundid ;
1818
19+ import java .util .List ;
20+ import java .util .function .Consumer ;
21+
22+ import javax .naming .InvalidNameException ;
23+ import javax .naming .ldap .LdapName ;
24+ import javax .naming .ldap .Rdn ;
25+
1926import com .unboundid .ldap .listener .InMemoryDirectoryServer ;
2027import com .unboundid .ldap .listener .InMemoryDirectoryServerConfig ;
2128import com .unboundid .ldap .listener .InMemoryListenerConfig ;
2431import com .unboundid .ldap .sdk .LDAPException ;
2532
2633import org .springframework .util .Assert ;
34+ import org .springframework .util .CollectionUtils ;
2735
2836/**
2937 * Helper class for embedded Unboundid ldap server.
@@ -45,27 +53,30 @@ public EmbeddedLdapServer(InMemoryDirectoryServer directoryServer) {
4553 this .directoryServer = directoryServer ;
4654 }
4755
56+ /**
57+ * Creates a new {@link Builder} with a given partition suffix.
58+ *
59+ * @since 3.3
60+ */
61+ public static Builder withPartitionSuffix (String partitionSuffix ) {
62+ return new Builder (partitionSuffix );
63+ }
64+
4865 /**
4966 * Creates and starts new embedded LDAP server.
67+ * @deprecated Use the builder pattern exposed via
68+ * {@link #withPartitionSuffix(String)} instead.
5069 */
70+ @ Deprecated (since = "3.3" )
5171 public static EmbeddedLdapServer newEmbeddedServer (String defaultPartitionName , String defaultPartitionSuffix ,
52- int port ) throws Exception {
53- InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig (defaultPartitionSuffix );
54- config .addAdditionalBindCredentials ("uid=admin,ou=system" , "secret" );
55-
56- config .setListenerConfigs (InMemoryListenerConfig .createLDAPConfig ("LDAP" , port ));
57-
58- config .setEnforceSingleStructuralObjectClass (false );
59- config .setEnforceAttributeSyntaxCompliance (true );
72+ int port ) {
73+ EmbeddedLdapServer server = EmbeddedLdapServer .withPartitionSuffix (defaultPartitionSuffix )
74+ .partitionName (defaultPartitionName )
75+ .port (port )
76+ .build ();
6077
61- Entry entry = new Entry (new DN (defaultPartitionSuffix ));
62- entry .addAttribute ("objectClass" , "top" , "domain" , "extensibleObject" );
63- entry .addAttribute ("dc" , defaultPartitionName );
64-
65- InMemoryDirectoryServer directoryServer = new InMemoryDirectoryServer (config );
66- directoryServer .add (entry );
67- directoryServer .startListening ();
68- return new EmbeddedLdapServer (directoryServer );
78+ server .start ();
79+ return server ;
6980 }
7081
7182 /**
@@ -102,4 +113,119 @@ public void shutdown() {
102113 this .directoryServer .shutDown (true );
103114 }
104115
116+ /**
117+ * Helper class for embedded Unboundid ldap server.
118+ *
119+ * @author Emanuel Trandafir
120+ * @since 3.3
121+ */
122+ public static final class Builder {
123+
124+ private final String partitionSuffix ;
125+
126+ private String partitionName ;
127+
128+ private int port = 0 ;
129+
130+ private Consumer <InMemoryDirectoryServerConfig > configurationCustomizer = (__ ) -> {
131+ };
132+
133+ private Builder (String partitionSuffix ) {
134+ this .partitionSuffix = partitionSuffix ;
135+ this .partitionName = leftMostElement (partitionSuffix );
136+ }
137+
138+ /**
139+ * Sets the port for the embedded LDAP server.
140+ * @param port the port for the embedded LDAP server. Defaults to 0 in which case
141+ * the server should automatically choose an available port.
142+ * @return this {@link Builder} instance.
143+ */
144+ public Builder port (int port ) {
145+ this .port = port ;
146+ return this ;
147+ }
148+
149+ /**
150+ * Sets a customizer for the {@link InMemoryDirectoryServerConfig}.
151+ * @param configurationCustomizer a {@link Consumer} function that will be applied
152+ * to the {@link InMemoryDirectoryServerConfig} before creating the
153+ * {@link InMemoryDirectoryServer}. The default values, it a Consumer function
154+ * that does nothing: (config) -> {}
155+ * @return this {@link Builder} instance.
156+ */
157+ public Builder configurationCustomizer (Consumer <InMemoryDirectoryServerConfig > configurationCustomizer ) {
158+ this .configurationCustomizer = configurationCustomizer ;
159+ return this ;
160+ }
161+
162+ /**
163+ * Sets the partition name for the embedded LDAP server.
164+ * @param partitionName the partition name for the embedded LDAP server. Defaults
165+ * to the left most element of the partition suffix.
166+ * @return this {@link Builder} instance.
167+ */
168+ public Builder partitionName (String partitionName ) {
169+ this .partitionName = partitionName ;
170+ return this ;
171+ }
172+
173+ /**
174+ * Builds and returns a {@link EmbeddedLdapServer}.
175+ * <p>
176+ * In order to start the server, you should call
177+ * {@link EmbeddedLdapServer#start()}.
178+ * @return a new {@link EmbeddedLdapServer}.
179+ */
180+ public EmbeddedLdapServer build () {
181+ try {
182+ InMemoryDirectoryServerConfig config = inMemoryDirectoryServerConfig (this .partitionSuffix , this .port );
183+ this .configurationCustomizer .accept (config );
184+
185+ Entry entry = ldapEntry (this .partitionName , this .partitionSuffix );
186+ InMemoryDirectoryServer directoryServer = inMemoryDirectoryServer (config , entry );
187+ return new EmbeddedLdapServer (directoryServer );
188+ }
189+ catch (Exception ex ) {
190+ throw new RuntimeException (ex );
191+ }
192+ }
193+
194+ static String leftMostElement (String partitionSuffix ) {
195+ try {
196+ List <Rdn > rdns = new LdapName (partitionSuffix ).getRdns ();
197+ return CollectionUtils .lastElement (rdns ).getValue ().toString ();
198+ }
199+ catch (InvalidNameException ex ) {
200+ throw new RuntimeException (ex );
201+ }
202+ }
203+
204+ private static InMemoryDirectoryServerConfig inMemoryDirectoryServerConfig (String partitionSuffix , int port )
205+ throws LDAPException {
206+ InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig (partitionSuffix );
207+ config .addAdditionalBindCredentials ("uid=admin,ou=system" , "secret" );
208+ config .setListenerConfigs (InMemoryListenerConfig .createLDAPConfig ("LDAP" , port ));
209+ config .setEnforceSingleStructuralObjectClass (false );
210+ config .setEnforceAttributeSyntaxCompliance (true );
211+ return config ;
212+ }
213+
214+ private static Entry ldapEntry (String defaultPartitionName , String defaultPartitionSuffix )
215+ throws LDAPException {
216+ Entry entry = new Entry (new DN (defaultPartitionSuffix ));
217+ entry .addAttribute ("objectClass" , "top" , "domain" , "extensibleObject" );
218+ entry .addAttribute ("dc" , defaultPartitionName );
219+ return entry ;
220+ }
221+
222+ private static InMemoryDirectoryServer inMemoryDirectoryServer (InMemoryDirectoryServerConfig config ,
223+ Entry entry ) throws LDAPException {
224+ InMemoryDirectoryServer directoryServer = new InMemoryDirectoryServer (config );
225+ directoryServer .add (entry );
226+ return directoryServer ;
227+ }
228+
229+ }
230+
105231}
0 commit comments