java ldap unboundid-ldap-sdk

LDAP: Cómo devolver más de 1000 resultados(java)



unboundid-ldap-sdk (4)

Estoy utilizando el SDK de LDAP de este sitio: https://www.unboundid.com/products/ldap-sdk/ . Me gustaría hacer una operación de búsqueda que devuelva muchas entradas.

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

Así que aquí está 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 configuro el límite de tamaño a "2000".


El cliente LDAP está configurando 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. No importa cuál sea el límite de tamaño solicitado por el cliente, el límite de tamaño del servidor lo reemplaza. Póngase en contacto con el administrador del servidor de directorio y solicite que se aumente el límite de tamaño.


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

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 desde here .


Resolví 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; }


Si bien es casi seguro que el servidor está aplicando el límite de tamaño de 1000 entradas, hay formas potenciales 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 se admite en el SDK de LDAP según https://docs.ldap.com/ldap-sdk/docs/javadoc/com/unboundid/ldap/sdk/controls/SimplePagedResultsControl.html ), luego puede usarlo para recorrer los resultados en "páginas" que contienen un número específico de entradas.

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