2012-07-03 23 views
11

Estoy usando el SDK de LDAP desde este sitio: https://www.unboundid.com/products/ldap-sdk/. Me gustaría realizar una operación de búsqueda que devuelva muchas entradas.LDAP: cómo devolver más de 1000 resultados (java)

De acuerdo con el sitio de Preguntas frecuentes, (https://www.unboundid.com/products/ldap-sdk/docs/ldapsdk-faq.php#search) Tengo que utilizar una implementación SearchResultListener.

Así que aquí es lo que hice:

public class UpdateThread extends Thread implements SearchResultListener { 
... 
// create request 
final SearchRequest request = new SearchRequest(this, instance.getBaseDN(),SearchScope.SUB, filter); 
// Setting size limit of results. 
request.setSizeLimit(2000); 

... 

// Get every result one by one. 
@Override 
public void searchEntryReturned(SearchResultEntry arg0) { 
    System.out.println("entry "+arg0.getDN()); 

} 

El problema es que "searchEntryReturned" devuelve un máximo de 1000 resultados. Incluso si configuré el límite de tamaño en "2000".

Respuesta

8

Aunque es casi seguro que el servidor está aplicando el límite de tamaño de 1000 entradas, existen formas posibles de evitarlo al emitir la solicitud en varias partes.

Si el servidor admite el uso del control de resultados paginado simple (como se define en RFC 2696 y compatible con LDAP SDK según https://docs.ldap.com/ldap-sdk/docs/javadoc/com/unboundid/ldap/sdk/controls/SimplePagedResultsControl.html), puede usarlo para recorrer los resultados en "páginas" que contienen un número de entradas.

Alternativamente, se podría usar el control de solicitud de vista de lista virtual (VLV) (https://www.unboundid.com/products/ldap-sdk/docs/javadoc/index.html?com/unboundid/ldap/sdk/controls/VirtualListViewRequestControl.html), pero probablemente solo recomendaría que si el servidor no admite el control de resultados paginado simple porque el control de solicitud VLV también requiera los resultados se ordenan, y eso probablemente requiera una configuración especial en el servidor o algún procesamiento bastante costoso para poder dar servicio a la solicitud.

+0

Se trabajó (simple control de resultados paginados)! Muchas gracias ! – stage

5

El cliente LDAP está estableciendo un límite de tamaño "solicitado por el cliente" de 2000. Este límite solicitado por el cliente no puede anular los límites establecidos en la configuración del servidor. Independientemente del límite de tamaño solicitado por el cliente, el límite de tamaño del servidor lo anula. Póngase en contacto con su administrador de servidor de directorio y solicite que se aumente el límite de tamaño.

8

Es bastante simple implementar una consulta LDAP paginada usando java estándar, al agregar un PagedResultsControl al LdapContext, sin utilizar una API de terceros según la respuesta de Neil anterior.

Hashtable<String, Object> env = new Hashtable<String, Object>(11); 
env 
    .put(Context.INITIAL_CONTEXT_FACTORY, 
     "com.sun.jndi.ldap.LdapCtxFactory"); 

/* Specify host and port to use for directory service */ 
env.put(Context.PROVIDER_URL, 
    "ldap://localhost:389/ou=People,o=JNDITutorial"); 

try { 
    LdapContext ctx = new InitialLdapContext(env, null); 

    // Activate paged results 
    int pageSize = 5; 
    byte[] cookie = null; 
    ctx.setRequestControls(new Control[] { new PagedResultsControl(pageSize, 
     Control.NONCRITICAL) }); 
    int total; 

    do { 
    /* perform the search */ 
    NamingEnumeration results = ctx.search("", "(objectclass=*)", 
     new SearchControls()); 

    /* for each entry print out name + all attrs and values */ 
    while (results != null && results.hasMore()) { 
     SearchResult entry = (SearchResult) results.next(); 
     System.out.println(entry.getName()); 
    } 

    // Examine the paged results control response 
    Control[] controls = ctx.getResponseControls(); 
    if (controls != null) { 
     for (int i = 0; i < controls.length; i++) { 
     if (controls[i] instanceof PagedResultsResponseControl) { 
      PagedResultsResponseControl prrc = (PagedResultsResponseControl) controls[i]; 
      total = prrc.getResultSize(); 
      if (total != 0) { 
      System.out.println("***************** END-OF-PAGE " 
       + "(total : " + total + ") *****************\n"); 
      } else { 
      System.out.println("***************** END-OF-PAGE " 
       + "(total: unknown) ***************\n"); 
      } 
      cookie = prrc.getCookie(); 
     } 
     } 
    } else { 
     System.out.println("No controls were sent from the server"); 
    } 
    // Re-activate paged results 
    ctx.setRequestControls(new Control[] { new PagedResultsControl(
     pageSize, cookie, Control.CRITICAL) }); 

    } while (cookie != null); 

    ctx.close(); 

Ejemplo copiado de here.

4

Solucioné como @PeterK, pero con algunas modificaciones

public List<MyUser> listUsers() { 
    LOG.info("listUsers() inicio"); 
    List<MyUser> users = new ArrayList<MyUser>(); 

    Hashtable env = new Hashtable(); 
    env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CTX); 
    env.put(Context.PROVIDER_URL, 'ldap://192.168.10.10:389'); 
    env.put(Context.SECURITY_AUTHENTICATION, CONNECTION_TYPE); 
    env.put(Context.SECURITY_PRINCIPAL, USER_ADMIN_PASSWORD); 
    env.put(Context.SECURITY_CREDENTIALS, USER_ADMIN); 

    try { 
     LdapContext ctx = new InitialLdapContext(env, null); 

     // Activate paged results 
     int pageSize = 1000; 
     byte[] cookie = null; 
     ctx.setRequestControls(new Control[] { new PagedResultsControl(pageSize, Control.NONCRITICAL) }); 
     int total; 

     do { 
      /* perform the search */ 
      SearchControls sc = new SearchControls(); 
      sc.setSearchScope(SearchControls.SUBTREE_SCOPE); 
      String filtro = "(&(sAMAccountName=*)&(objectClass=user))"; 
      NamingEnumeration results = ctx.search(getBaseDn(ctx), filtro, sc); 

      /* for each entry */ 
      while (results.hasMoreElements()) { 
       SearchResult result = (SearchResult) results.nextElement(); 
       Attributes attributes = result.getAttributes(); 
       //convert to MyUser class 
       MyUser user = toUser(attributes); 
       users.add(user); 
      } 

      // Examine the paged results control response 
      Control[] controls = ctx.getResponseControls(); 
      if (controls != null) { 
       for (int i = 0; i < controls.length; i++) { 
        if (controls[i] instanceof PagedResultsResponseControl) { 
         PagedResultsResponseControl prrc = (PagedResultsResponseControl) controls[i]; 
         total = prrc.getResultSize(); 
         if (total != 0) { 
          System.out.println("***************** END-OF-PAGE " + "(total : " + total + ") *****************\n"); 
         } else { 
          System.out.println("***************** END-OF-PAGE " + "(total: unknown) ***************\n"); 
         } 
         cookie = prrc.getCookie(); 
        } 
       } 
      } else { 
       System.out.println("No controls were sent from the server"); 
      } 
      // Re-activate paged results 
      ctx.setRequestControls(new Control[] { new PagedResultsControl(pageSize, cookie, Control.CRITICAL) }); 

     } while (cookie != null); 

     ctx.close(); 

    } catch (NamingException e) { 
     System.err.println("PagedSearch failed."); 
     e.printStackTrace(); 
    } catch (IOException ie) { 
     System.err.println("PagedSearch failed."); 
     ie.printStackTrace(); 
    } catch (Exception ie) { 
     System.err.println("PagedSearch failed."); 
     ie.printStackTrace(); 
    } 

    LOG.info("listUsers() size = " + (users.size())); 
    LOG.info("listUsers() fim"); 

    return users; 
} 


private MyUser toUser(Attributes attributes) throws NamingException { 
    if (attributes != null) { 
     String fullName = attributes.get("distinguishedName") != null ? attributes.get("distinguishedName").get().toString() : null; 
     String mail = attributes.get("mail") != null ? attributes.get("mail").get().toString() : null; 
     String userName = attributes.get("cn") != null ? attributes.get("cn").get().toString() : null; 
     String userPrincipalName = attributes.get("userPrincipalName") != null ? attributes.get("userPrincipalName").get().toString() : null; 

     if (userPrincipalName != null) { 
      String[] user = userPrincipalName.split("@"); 
      if (user != null && user.length > 0) { 
       userName = user[0]; 
      } 
     } 

     MyUser user = new MyUser(); 
     user.setFullName(fullName); 
     user.setEmail(mail); 
     user.setName(userName); 
     user.setUserPrincipalName(userPrincipalName); 
     user.setRoles(getRolesUser(attributes)); 

     return user; 
    } 

    return null; 
} 
+0

PeterK nunca verá su mensaje como lo hizo – Drew

+0

¿Cómo hacer esto? ... –

+0

ingresará un comentario en su respuesta. Recuerde: bajo su Respuesta, las siguientes personas reciben una alerta cuando publica un comentario en su Respuesta ... (1) Op. Creo, pero no me detengo, (2) Otro comentarista como yo, si esa persona es la única persona con un hilo de comentarios como en nadie más está comentando, (3) alguien que @ su Nombre que ya está bajo su respuesta en un comentario o el Op – Drew

Cuestiones relacionadas