You are viewing a plain text version of this content. The canonical link for it is here.
Posted to api@directory.apache.org by "Harris, Christopher P" <ch...@baxter.com> on 2014/08/15 01:42:03 UTC

Trying to get LdapConnectionTemplate working

Hi,

I've been following the example code from Section 2.10 using v1.0.0-M24.  My goal is to use an LdapConnectionTemplate to bind to AD, return a response/cursor, and use an EntryMapper to map each cursor iteration's value to a Person object.

I'm getting the following error message:
ERR_02002_FAILURE_ON_UNDERLYING_CURSOR Failure on underlying Cursor

I'm not sure what's wrong at this point.  I have a basic query example working that doesn't use a template.

I'm including my code, which contains the method with the basic query that does work and the method with the query using the template that doesn't work.

Can you help me figure out why searchLdapForCeoUsingTemplate() is not working?


Here's LdapClient.java:
/**
*
 */

import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.directory.api.ldap.model.cursor.CursorException;
import org.apache.directory.api.ldap.model.cursor.SearchCursor;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.message.Response;
import org.apache.directory.api.ldap.model.message.SearchRequest;
import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
import org.apache.directory.api.ldap.model.message.SearchResultDone;
import org.apache.directory.api.ldap.model.message.SearchResultEntry;
import org.apache.directory.api.ldap.model.message.SearchScope;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.ldap.client.api.DefaultLdapConnectionFactory;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.ldap.client.api.LdapConnectionConfig;
import org.apache.directory.ldap.client.api.LdapConnectionPool;
import org.apache.directory.ldap.client.api.LdapNetworkConnection;
import org.apache.directory.ldap.client.api.PoolableLdapConnectionFactory;
import org.apache.directory.ldap.client.api.SearchCursorImpl;
import org.apache.directory.ldap.client.template.EntryMapper;
import org.apache.directory.ldap.client.template.LdapConnectionTemplate;

/**
* @author Chris Harris
*
*/
public class LdapClient {

               public LdapClient() {

               }

               private static final EntryMapper personEntryMapper =
                              new EntryMapper<Person>() {
                                             @Override
                                             public Person map( Entry entry ) throws LdapException {
                                                            return new Person.Builder()
                                                                           .setFirstName(entry.get( "givenName" ).getString())
                                                                           .setLastName(entry.get( "sn" ).getString())
                                                                           .build();
                                             }
                              };

               public Person searchLdapForCeoUsingTemplate() {
                              LdapConnectionConfig config = new LdapConnectionConfig();
                              config.setLdapHost( <my host> );
                              config.setLdapPort( <my port> );
                              config.setName( <my DN> );
                              config.setCredentials( <my Password> );

                              DefaultLdapConnectionFactory factory = new DefaultLdapConnectionFactory( config );
                              factory.setTimeOut( 30000 );

                              // optional, values below are defaults
                              GenericObjectPool.Config poolConfig = new GenericObjectPool.Config();
                              poolConfig.lifo = true;
                              poolConfig.maxActive = 8;
                              poolConfig.maxIdle = 8;
                              poolConfig.maxWait = -1L;
                              poolConfig.minEvictableIdleTimeMillis = 1000L * 60L * 30L;
                              poolConfig.minIdle = 0;
                              poolConfig.numTestsPerEvictionRun = 3;
                              poolConfig.softMinEvictableIdleTimeMillis = -1L;
                              poolConfig.testOnBorrow = false;
                              poolConfig.testOnReturn = false;
                              poolConfig.testWhileIdle = false;
                              poolConfig.timeBetweenEvictionRunsMillis = -1L;
                              poolConfig.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK;

                              LdapConnectionTemplate ldapConnectionTemplate =
                                  new LdapConnectionTemplate( new LdapConnectionPool(
                                      new PoolableLdapConnectionFactory( factory ), poolConfig ) );

                              List<Person> allThePeople = ldapConnectionTemplate.search(
                                                 <my search base>,
                                                 <my query string>,
                                                 SearchScope.SUBTREE,
                                                 personEntryMapper );

                              for (Person p : allThePeople) {
                                             System.out.println(p.getFirstName());
                                             System.out.println(p.getLastName());
                              }

                              return allThePeople.get(0);
               }

               public Entry searchLdapForCeo() {
                              SearchCursor cursor = new SearchCursorImpl(null, 30000, TimeUnit.SECONDS);
        LdapConnection connection = new LdapNetworkConnection(<my host>, <my port>);
        Entry entry = null;
        try {
            connection.bind(<my DN>, <my password>);

            SearchRequest sr = new SearchRequestImpl();
           sr.setBase(new Dn(<my search base>));
            StringBuilder sb = new StringBuilder(<my query string>);
            sr.setFilter(sb.toString());
            sr.setScope( SearchScope.SUBTREE );
            cursor = connection.search(sr);
            Response response;

            while (cursor.next() && cursor.isEntry()) {
                response = cursor.get();
                System.out.println(((SearchResultEntry)response).getEntry());
                entry = cursor.getEntry();
            }

            SearchResultDone done = cursor.getSearchResultDone();
        } catch (LdapException ex) {
            Logger.getLogger(LdapClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (CursorException ex) {
            Logger.getLogger(LdapClient.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            cursor.close();
            try {
                connection.close();
            } catch (IOException ex) {
                Logger.getLogger(LdapClient.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return entry;
               }
}


Here's Person.java:
/**
*
 */

public class Person {

       protected Person() {

       }

       public static class Builder {
             private Person person;

             public Builder() {
                    this.person = new Person();
             }

             public Builder setFirstName(String firstName) {
                    this.person.firstName = firstName;
                    return this;
             }

             public Builder setLastName(String lastName) {
                    this.person.lastName = lastName;
                    return this;
             }

             public Person build() {
                    return this.person;
             }
       }

       private String firstName;
       private String lastName;

       public String getFirstName() {
             return firstName;
       }
       public void setFirstName(String firstName) {
             this.firstName = firstName;
       }
       public String getLastName() {
             return lastName;
       }
       public void setLastName(String lastName) {
             this.lastName = lastName;
       }
}


Here's my JUnit test:
/**
*
 */

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class LdapClientTest {

       private static LdapClient ldapClient;

       @BeforeClass
       public static void setUpBeforeClass() throws Exception {
             ldapClient = new LdapClient();
       }

       @Before
       public void setUp() throws Exception {
       }

       @Test
       public void testSearchLdapForCeo() {
             assertNotEquals(null, ldapClient.searchLdapForCeo());
       }

       @Test
       public void testSearchLdapForCeoUsingLdapSearchTemplate() {
             assertNotEquals(null, ldapClient.searchLdapForCeoUsingTemplate());
       }

       @After
       public void tearDown() throws Exception {
       }

       @AfterClass
             public static void tearDownAfterClass() throws Exception {
       }
}


The information transmitted is intended only for the person(s) or entity to which it is addressed and may contain confidential and/or legally privileged material. Delivery of this message to any person other than the intended recipient(s) is not intended in any way to waive privilege or confidentiality. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by entities other than the intended recipient is prohibited. If you receive this in error, please contact the sender and delete the material from any computer.

For Translation:

http://www.baxter.com/email_disclaimer

RE: Trying to get LdapConnectionTemplate working

Posted by "Harris, Christopher P" <ch...@baxter.com>.
Thanks, Emmanuel.

I created DIRAPI-202 as per your suggestion.

 - Chris

-----Original Message-----
From: Emmanuel Lécharny [mailto:elecharny@gmail.com] 
Sent: Thursday, August 14, 2014 7:15 PM
To: api@directory.apache.org
Subject: Re: Trying to get LdapConnectionTemplate working

Le 15/08/14 01:42, Harris, Christopher P a écrit :
> Hi,

Hi,

could you create a JIRA with all the elements you provided ? That would be the best possible way to get someone looking at the pb, considering the vacations period...

Thanks !
>
> I've been following the example code from Section 2.10 using v1.0.0-M24.  My goal is to use an LdapConnectionTemplate to bind to AD, return a response/cursor, and use an EntryMapper to map each cursor iteration's value to a Person object.
>
> I'm getting the following error message:
> ERR_02002_FAILURE_ON_UNDERLYING_CURSOR Failure on underlying Cursor
>
> I'm not sure what's wrong at this point.  I have a basic query example working that doesn't use a template.
>
> I'm including my code, which contains the method with the basic query that does work and the method with the query using the template that doesn't work.
>
> Can you help me figure out why searchLdapForCeoUsingTemplate() is not working?
>
>
> Here's LdapClient.java:
> /**
> *
>  */
>
> import java.io.IOException;
> import java.util.List;
> import java.util.concurrent.TimeUnit;
> import java.util.logging.Level;
> import java.util.logging.Logger;
>
> import org.apache.commons.pool.impl.GenericObjectPool;
> import org.apache.directory.api.ldap.model.cursor.CursorException;
> import org.apache.directory.api.ldap.model.cursor.SearchCursor;
> import org.apache.directory.api.ldap.model.entry.Entry;
> import org.apache.directory.api.ldap.model.exception.LdapException;
> import org.apache.directory.api.ldap.model.message.Response;
> import org.apache.directory.api.ldap.model.message.SearchRequest;
> import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
> import org.apache.directory.api.ldap.model.message.SearchResultDone;
> import org.apache.directory.api.ldap.model.message.SearchResultEntry;
> import org.apache.directory.api.ldap.model.message.SearchScope;
> import org.apache.directory.api.ldap.model.name.Dn;
> import 
> org.apache.directory.ldap.client.api.DefaultLdapConnectionFactory;
> import org.apache.directory.ldap.client.api.LdapConnection;
> import org.apache.directory.ldap.client.api.LdapConnectionConfig;
> import org.apache.directory.ldap.client.api.LdapConnectionPool;
> import org.apache.directory.ldap.client.api.LdapNetworkConnection;
> import 
> org.apache.directory.ldap.client.api.PoolableLdapConnectionFactory;
> import org.apache.directory.ldap.client.api.SearchCursorImpl;
> import org.apache.directory.ldap.client.template.EntryMapper;
> import 
> org.apache.directory.ldap.client.template.LdapConnectionTemplate;
>
> /**
> * @author Chris Harris
> *
> */
> public class LdapClient {
>
>                public LdapClient() {
>
>                }
>
>                private static final EntryMapper personEntryMapper =
>                               new EntryMapper<Person>() {
>                                              @Override
>                                              public Person map( Entry entry ) throws LdapException {
>                                                             return new Person.Builder()
>                                                                            .setFirstName(entry.get( "givenName" ).getString())
>                                                                            .setLastName(entry.get( "sn" ).getString())
>                                                                            .build();
>                                              }
>                               };
>
>                public Person searchLdapForCeoUsingTemplate() {
>                               LdapConnectionConfig config = new LdapConnectionConfig();
>                               config.setLdapHost( <my host> );
>                               config.setLdapPort( <my port> );
>                               config.setName( <my DN> );
>                               config.setCredentials( <my Password> );
>
>                               DefaultLdapConnectionFactory factory = new DefaultLdapConnectionFactory( config );
>                               factory.setTimeOut( 30000 );
>
>                               // optional, values below are defaults
>                               GenericObjectPool.Config poolConfig = new GenericObjectPool.Config();
>                               poolConfig.lifo = true;
>                               poolConfig.maxActive = 8;
>                               poolConfig.maxIdle = 8;
>                               poolConfig.maxWait = -1L;
>                               poolConfig.minEvictableIdleTimeMillis = 1000L * 60L * 30L;
>                               poolConfig.minIdle = 0;
>                               poolConfig.numTestsPerEvictionRun = 3;
>                               poolConfig.softMinEvictableIdleTimeMillis = -1L;
>                               poolConfig.testOnBorrow = false;
>                               poolConfig.testOnReturn = false;
>                               poolConfig.testWhileIdle = false;
>                               poolConfig.timeBetweenEvictionRunsMillis = -1L;
>                               poolConfig.whenExhaustedAction = 
> GenericObjectPool.WHEN_EXHAUSTED_BLOCK;
>
>                               LdapConnectionTemplate ldapConnectionTemplate =
>                                   new LdapConnectionTemplate( new LdapConnectionPool(
>                                       new 
> PoolableLdapConnectionFactory( factory ), poolConfig ) );
>
>                               List<Person> allThePeople = ldapConnectionTemplate.search(
>                                                  <my search base>,
>                                                  <my query string>,
>                                                  SearchScope.SUBTREE,
>                                                  personEntryMapper );
>
>                               for (Person p : allThePeople) {
>                                              System.out.println(p.getFirstName());
>                                              System.out.println(p.getLastName());
>                               }
>
>                               return allThePeople.get(0);
>                }
>
>                public Entry searchLdapForCeo() {
>                               SearchCursor cursor = new SearchCursorImpl(null, 30000, TimeUnit.SECONDS);
>         LdapConnection connection = new LdapNetworkConnection(<my host>, <my port>);
>         Entry entry = null;
>         try {
>             connection.bind(<my DN>, <my password>);
>
>             SearchRequest sr = new SearchRequestImpl();
>            sr.setBase(new Dn(<my search base>));
>             StringBuilder sb = new StringBuilder(<my query string>);
>             sr.setFilter(sb.toString());
>             sr.setScope( SearchScope.SUBTREE );
>             cursor = connection.search(sr);
>             Response response;
>
>             while (cursor.next() && cursor.isEntry()) {
>                 response = cursor.get();
>                 System.out.println(((SearchResultEntry)response).getEntry());
>                 entry = cursor.getEntry();
>             }
>
>             SearchResultDone done = cursor.getSearchResultDone();
>         } catch (LdapException ex) {
>             Logger.getLogger(LdapClient.class.getName()).log(Level.SEVERE, null, ex);
>         } catch (CursorException ex) {
>             Logger.getLogger(LdapClient.class.getName()).log(Level.SEVERE, null, ex);
>         } finally {
>             cursor.close();
>             try {
>                 connection.close();
>             } catch (IOException ex) {
>                 Logger.getLogger(LdapClient.class.getName()).log(Level.SEVERE, null, ex);
>             }
>         }
>         return entry;
>                }
> }
>
>
> Here's Person.java:
> /**
> *
>  */
>
> public class Person {
>
>        protected Person() {
>
>        }
>
>        public static class Builder {
>              private Person person;
>
>              public Builder() {
>                     this.person = new Person();
>              }
>
>              public Builder setFirstName(String firstName) {
>                     this.person.firstName = firstName;
>                     return this;
>              }
>
>              public Builder setLastName(String lastName) {
>                     this.person.lastName = lastName;
>                     return this;
>              }
>
>              public Person build() {
>                     return this.person;
>              }
>        }
>
>        private String firstName;
>        private String lastName;
>
>        public String getFirstName() {
>              return firstName;
>        }
>        public void setFirstName(String firstName) {
>              this.firstName = firstName;
>        }
>        public String getLastName() {
>              return lastName;
>        }
>        public void setLastName(String lastName) {
>              this.lastName = lastName;
>        }
> }
>
>
> Here's my JUnit test:
> /**
> *
>  */
>
> import static org.junit.Assert.*;
>
> import org.junit.After;
> import org.junit.AfterClass;
> import org.junit.Before;
> import org.junit.BeforeClass;
> import org.junit.Test;
>
> public class LdapClientTest {
>
>        private static LdapClient ldapClient;
>
>        @BeforeClass
>        public static void setUpBeforeClass() throws Exception {
>              ldapClient = new LdapClient();
>        }
>
>        @Before
>        public void setUp() throws Exception {
>        }
>
>        @Test
>        public void testSearchLdapForCeo() {
>              assertNotEquals(null, ldapClient.searchLdapForCeo());
>        }
>
>        @Test
>        public void testSearchLdapForCeoUsingLdapSearchTemplate() {
>              assertNotEquals(null, ldapClient.searchLdapForCeoUsingTemplate());
>        }
>
>        @After
>        public void tearDown() throws Exception {
>        }
>
>        @AfterClass
>              public static void tearDownAfterClass() throws Exception {
>        }
> }
>
>
> The information transmitted is intended only for the person(s) or entity to which it is addressed and may contain confidential and/or legally privileged material. Delivery of this message to any person other than the intended recipient(s) is not intended in any way to waive privilege or confidentiality. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by entities other than the intended recipient is prohibited. If you receive this in error, please contact the sender and delete the material from any computer.
>
> For Translation:
>
> http://www.baxter.com/email_disclaimer
>

The information transmitted is intended only for the person(s) or entity to which it is addressed and may contain confidential and/or legally privileged material. Delivery of this message to any person other than the intended recipient(s) is not intended in any way to waive privilege or confidentiality. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by entities other than the intended recipient is prohibited. If you receive this in error, please contact the sender and delete the material from any computer.

For Translation:

http://www.baxter.com/email_disclaimer

Re: Trying to get LdapConnectionTemplate working

Posted by Emmanuel Lécharny <el...@gmail.com>.
Le 15/08/14 01:42, Harris, Christopher P a écrit :
> Hi,

Hi,

could you create a JIRA with all the elements you provided ? That would
be the best possible way to get someone looking at the pb, considering
the vacations period...

Thanks !
>
> I've been following the example code from Section 2.10 using v1.0.0-M24.  My goal is to use an LdapConnectionTemplate to bind to AD, return a response/cursor, and use an EntryMapper to map each cursor iteration's value to a Person object.
>
> I'm getting the following error message:
> ERR_02002_FAILURE_ON_UNDERLYING_CURSOR Failure on underlying Cursor
>
> I'm not sure what's wrong at this point.  I have a basic query example working that doesn't use a template.
>
> I'm including my code, which contains the method with the basic query that does work and the method with the query using the template that doesn't work.
>
> Can you help me figure out why searchLdapForCeoUsingTemplate() is not working?
>
>
> Here's LdapClient.java:
> /**
> *
>  */
>
> import java.io.IOException;
> import java.util.List;
> import java.util.concurrent.TimeUnit;
> import java.util.logging.Level;
> import java.util.logging.Logger;
>
> import org.apache.commons.pool.impl.GenericObjectPool;
> import org.apache.directory.api.ldap.model.cursor.CursorException;
> import org.apache.directory.api.ldap.model.cursor.SearchCursor;
> import org.apache.directory.api.ldap.model.entry.Entry;
> import org.apache.directory.api.ldap.model.exception.LdapException;
> import org.apache.directory.api.ldap.model.message.Response;
> import org.apache.directory.api.ldap.model.message.SearchRequest;
> import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
> import org.apache.directory.api.ldap.model.message.SearchResultDone;
> import org.apache.directory.api.ldap.model.message.SearchResultEntry;
> import org.apache.directory.api.ldap.model.message.SearchScope;
> import org.apache.directory.api.ldap.model.name.Dn;
> import org.apache.directory.ldap.client.api.DefaultLdapConnectionFactory;
> import org.apache.directory.ldap.client.api.LdapConnection;
> import org.apache.directory.ldap.client.api.LdapConnectionConfig;
> import org.apache.directory.ldap.client.api.LdapConnectionPool;
> import org.apache.directory.ldap.client.api.LdapNetworkConnection;
> import org.apache.directory.ldap.client.api.PoolableLdapConnectionFactory;
> import org.apache.directory.ldap.client.api.SearchCursorImpl;
> import org.apache.directory.ldap.client.template.EntryMapper;
> import org.apache.directory.ldap.client.template.LdapConnectionTemplate;
>
> /**
> * @author Chris Harris
> *
> */
> public class LdapClient {
>
>                public LdapClient() {
>
>                }
>
>                private static final EntryMapper personEntryMapper =
>                               new EntryMapper<Person>() {
>                                              @Override
>                                              public Person map( Entry entry ) throws LdapException {
>                                                             return new Person.Builder()
>                                                                            .setFirstName(entry.get( "givenName" ).getString())
>                                                                            .setLastName(entry.get( "sn" ).getString())
>                                                                            .build();
>                                              }
>                               };
>
>                public Person searchLdapForCeoUsingTemplate() {
>                               LdapConnectionConfig config = new LdapConnectionConfig();
>                               config.setLdapHost( <my host> );
>                               config.setLdapPort( <my port> );
>                               config.setName( <my DN> );
>                               config.setCredentials( <my Password> );
>
>                               DefaultLdapConnectionFactory factory = new DefaultLdapConnectionFactory( config );
>                               factory.setTimeOut( 30000 );
>
>                               // optional, values below are defaults
>                               GenericObjectPool.Config poolConfig = new GenericObjectPool.Config();
>                               poolConfig.lifo = true;
>                               poolConfig.maxActive = 8;
>                               poolConfig.maxIdle = 8;
>                               poolConfig.maxWait = -1L;
>                               poolConfig.minEvictableIdleTimeMillis = 1000L * 60L * 30L;
>                               poolConfig.minIdle = 0;
>                               poolConfig.numTestsPerEvictionRun = 3;
>                               poolConfig.softMinEvictableIdleTimeMillis = -1L;
>                               poolConfig.testOnBorrow = false;
>                               poolConfig.testOnReturn = false;
>                               poolConfig.testWhileIdle = false;
>                               poolConfig.timeBetweenEvictionRunsMillis = -1L;
>                               poolConfig.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK;
>
>                               LdapConnectionTemplate ldapConnectionTemplate =
>                                   new LdapConnectionTemplate( new LdapConnectionPool(
>                                       new PoolableLdapConnectionFactory( factory ), poolConfig ) );
>
>                               List<Person> allThePeople = ldapConnectionTemplate.search(
>                                                  <my search base>,
>                                                  <my query string>,
>                                                  SearchScope.SUBTREE,
>                                                  personEntryMapper );
>
>                               for (Person p : allThePeople) {
>                                              System.out.println(p.getFirstName());
>                                              System.out.println(p.getLastName());
>                               }
>
>                               return allThePeople.get(0);
>                }
>
>                public Entry searchLdapForCeo() {
>                               SearchCursor cursor = new SearchCursorImpl(null, 30000, TimeUnit.SECONDS);
>         LdapConnection connection = new LdapNetworkConnection(<my host>, <my port>);
>         Entry entry = null;
>         try {
>             connection.bind(<my DN>, <my password>);
>
>             SearchRequest sr = new SearchRequestImpl();
>            sr.setBase(new Dn(<my search base>));
>             StringBuilder sb = new StringBuilder(<my query string>);
>             sr.setFilter(sb.toString());
>             sr.setScope( SearchScope.SUBTREE );
>             cursor = connection.search(sr);
>             Response response;
>
>             while (cursor.next() && cursor.isEntry()) {
>                 response = cursor.get();
>                 System.out.println(((SearchResultEntry)response).getEntry());
>                 entry = cursor.getEntry();
>             }
>
>             SearchResultDone done = cursor.getSearchResultDone();
>         } catch (LdapException ex) {
>             Logger.getLogger(LdapClient.class.getName()).log(Level.SEVERE, null, ex);
>         } catch (CursorException ex) {
>             Logger.getLogger(LdapClient.class.getName()).log(Level.SEVERE, null, ex);
>         } finally {
>             cursor.close();
>             try {
>                 connection.close();
>             } catch (IOException ex) {
>                 Logger.getLogger(LdapClient.class.getName()).log(Level.SEVERE, null, ex);
>             }
>         }
>         return entry;
>                }
> }
>
>
> Here's Person.java:
> /**
> *
>  */
>
> public class Person {
>
>        protected Person() {
>
>        }
>
>        public static class Builder {
>              private Person person;
>
>              public Builder() {
>                     this.person = new Person();
>              }
>
>              public Builder setFirstName(String firstName) {
>                     this.person.firstName = firstName;
>                     return this;
>              }
>
>              public Builder setLastName(String lastName) {
>                     this.person.lastName = lastName;
>                     return this;
>              }
>
>              public Person build() {
>                     return this.person;
>              }
>        }
>
>        private String firstName;
>        private String lastName;
>
>        public String getFirstName() {
>              return firstName;
>        }
>        public void setFirstName(String firstName) {
>              this.firstName = firstName;
>        }
>        public String getLastName() {
>              return lastName;
>        }
>        public void setLastName(String lastName) {
>              this.lastName = lastName;
>        }
> }
>
>
> Here's my JUnit test:
> /**
> *
>  */
>
> import static org.junit.Assert.*;
>
> import org.junit.After;
> import org.junit.AfterClass;
> import org.junit.Before;
> import org.junit.BeforeClass;
> import org.junit.Test;
>
> public class LdapClientTest {
>
>        private static LdapClient ldapClient;
>
>        @BeforeClass
>        public static void setUpBeforeClass() throws Exception {
>              ldapClient = new LdapClient();
>        }
>
>        @Before
>        public void setUp() throws Exception {
>        }
>
>        @Test
>        public void testSearchLdapForCeo() {
>              assertNotEquals(null, ldapClient.searchLdapForCeo());
>        }
>
>        @Test
>        public void testSearchLdapForCeoUsingLdapSearchTemplate() {
>              assertNotEquals(null, ldapClient.searchLdapForCeoUsingTemplate());
>        }
>
>        @After
>        public void tearDown() throws Exception {
>        }
>
>        @AfterClass
>              public static void tearDownAfterClass() throws Exception {
>        }
> }
>
>
> The information transmitted is intended only for the person(s) or entity to which it is addressed and may contain confidential and/or legally privileged material. Delivery of this message to any person other than the intended recipient(s) is not intended in any way to waive privilege or confidentiality. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by entities other than the intended recipient is prohibited. If you receive this in error, please contact the sender and delete the material from any computer.
>
> For Translation:
>
> http://www.baxter.com/email_disclaimer
>