Announcement Announcement Module
Collapse
No announcement yet.
sizelimit Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • sizelimit

    Can I somehow define sizelimit for my ldap searches?

  • #2
    You can use one of the search methods that take SearchControls as an argument and set that parameter manually.

    However if the sizelimit is actually exceeded you will get a SearchLimitExceededException thrown from LdapTemplate, which will cause the collected objects thus far to be lost, which may or may not be what you want.

    If you want to keep the results you'll need to call the search(Name, String, SearchControls, SearchResultCallbackHandler) method and create the SearchResultCallbackHandler (e.g. a LdapTemplate.ContextMapperCallbackHandler) manually.

    Comment


    • #3
      I try this...

      Hello...

      Here is my test code:

      Code:
      private static Logger log = Logger.getLogger(TestSpringLDAP.class);
      
      	@Test
      	public void getAllUsers()
      	{
      		LdapContextSource source = new LdapContextSource();
      		source.setUrl(TestConfig.LDAP_CONNECTION_URL);
      		source.setBase(TestConfig.LDAP_BASE);
      		source.setUserName(TestConfig.LDAP_USER_NAME);
      		source.setPassword(TestConfig.LDAP_PASSWORD);
      		source.setDirObjectFactory(DefaultDirObjectFactory.class);
      		source.setAnonymousReadOnly(true);
      	        source.setContextFactory(com.sun.jndi.ldap.LdapCtxFactory.class);
      		source.setCacheEnvironmentProperties(false);
      		source.setPooled(false);
      		LdapTemplate template = new LdapTemplate(source);
      		template.setIgnorePartialResultException(true);
      		SearchControls searchControls = new SearchControls();
      		searchControls.setCountLimit(5);
      		searchControls.setReturningObjFlag(true);
      		searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
      		List result = null;
      		result = template.search("", "(objectClass=person)", searchControls, new PersonContextMapper());
      	}
      
      	private static class PersonContextMapper implements ContextMapper
      	{
      		public Object mapFromContext(Object ctx)
      		{
      			DirContextAdapter context = (DirContextAdapter) ctx;
      			String result = context.getStringAttribute("uid");
      			Person person = new Person();
      			System.out.println("ctx " + ctx);
      			return result;
      		}
      	}
      and I've got a:
      LDAP: error code 4 - Sizelimit Exceeded]; remaining name ''

      What's wrong?

      Comment


      • #4
        That is the expected behaviour:
        Originally posted by rasky View Post
        However if the sizelimit is actually exceeded you will get a SearchLimitExceededException thrown from LdapTemplate, which will cause the collected objects thus far to be lost, which may or may not be what you want.

        If you want to keep the results you'll need to call the search(Name, String, SearchControls, SearchResultCallbackHandler) method and create the SearchResultCallbackHandler (e.g. a LdapTemplate.ContextMapperCallbackHandler) manually.

        Comment


        • #5
          Thanx

          Thanx for reply.

          But method search(Name, String, SearchControls, SearchResultCallbackHandler) is in the LdapTemplate package from http://sourceforge.net/projects/ldaptemplate/ and there is not defined LdapTemplate(LdapContextSource) constructor.

          Comment


          • #6
            Originally posted by Nullpointer View Post
            Thanx for reply.

            But method search(Name, String, SearchControls, SearchResultCallbackHandler) is in the LdapTemplate package from http://sourceforge.net/projects/ldaptemplate/ and there is not defined LdapTemplate(LdapContextSource) constructor.
            Ah, quite right. SearchResultCallbackHandler was replaced by NameClassPairCallbackHandler in Spring LDAP. Sorry for the confusion.

            Comment


            • #7
              SearchLimitExceededException

              Hello,

              As stated in this thread I now pass an AttributesMapperCallbackHandler to the search method and still get SearchLimitExceededException. I even tried setting count limit in SearchControls to 0.

              Here's the code:

              CollectingNameClassPairCallbackHandler handler = ldapTemplate.new AttributesMapperCallbackHandler(new PersonAttributesMapper());

              ldapTemplate.search("", orFilter.encode(), searchControls, handler);

              <bean id="searchControls" class="javax.naming.directory.SearchControls">
              <property name="countLimit" value="0" />
              <property name="searchScope" value="2" />
              </bean>

              <bean id="ldapSearchBean" class="de.mun.services.cd.LdapSearchServiceImpl">
              <property name="ldapTemplate"><ref bean="ldapTemplate"/></property>
              <property name="searchControls"><ref bean="searchControls"/></property>
              </bean>

              Please help :-(

              Comment


              • #8
                It's possible to specify search limit in server configuration as well, so there's always the possibility of getting that exception even though you haven't specified any count limit yourself.

                Also, using an AttributesMapperCallbackHandler will not prevent any exceptions from being thrown. It does however give you access to the results that have been processed up to when the exception is thrown, using the getList() method of CollectingNameClassPairCallbackHandler.

                Comment


                • #9
                  sizelimit

                  Hello,
                  Thanks for the reply.

                  If I implement the same search functionality in the traditional way using InitialDirContext, I get all the results returned without any exception being thrown.

                  ctx = new InitialDirContext(env);
                  SearchControls ctls = new SearchControls();
                  ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
                  ctls.setReturningAttributes (ldapattrs );

                  NamingEnumeration answer = ctx.search(CONTEXT, filter, ctls);

                  This implies there's no search limit specified on the server. So what are the other possibilities of getting the exception? Is there no way of getting all the results?

                  Comment


                  • #10
                    Did you actually try to loop through the NamingEnumeration you get back in the plain JNDI code? The LimitExceededException may be thrown when calling NamingEnumeration.hasMore().

                    Once again, if the search limit is actually exceeded there's really no simple way of avoiding the Exception being thrown. But you can get hold of the entries collected up to when the exception was thrown using e.g. an AttributesMapperCallbackHandler instantiated by you before you call LdapTemplate. That instance holds a list that will be filled with all entries found so far.

                    Comment


                    • #11
                      Spring LDAP v1.3.1 - SizeLimitExceededException

                      Hi,
                      I have got the same situation as mentioned in the below thread.
                      Brief Desc of my Problem :
                      I have a traditional program to query from our LDAP.
                      It works good. Even if the search result is larger for the given input search string.
                      The program returns the first 1000 records (guess the limit is at the server side).
                      But a similar program using spring LdapTemplate throws an exception
                      "Caused by: javax.naming.SizeLimitExceededException: [LDAP: error code 4 - Sizelimit Exceeded]"

                      LDAP Search code in Traditional approach
                      Code:
                      public static void main(String[] args) {
                          try {
                            System.out.println("Using LDAP URL: " + ldapURL);
                            String searchString = (args != null & args.length > 0) ? args[0] : "joh";
                            // Create the initial directory context
                            LdapContext ctx = new InitialLdapContext(env, null);
                            // Create the search controls     
                            SearchControls searchCtls = new SearchControls();
                            //Specify the attributes to return
                            String returnedAtts[] = { "cn", "name", "displayName" };
                            //searchCtls.setReturningAttributes(returnedAtts);
                            //Specify the search scope
                            searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
                            //specify the LDAP search filter
                            //This example uses Ambiguous Name Resolution (ANR);
                            String searchFilter = "(&(objectClass=user)(anr=" + searchString + "))";
                            //initialize counter to total the results
                            int totalResults = 0;
                            searchCtls.setCountLimit(2);
                            // Search for objects using the filter
                            NamingEnumeration<SearchResult> searchResultsEnumeration = ctx.search(
                                searchBase, searchFilter, searchCtls);
                            
                            //Loop through the search results
                            while (searchResultsEnumeration.hasMoreElements()) {
                              SearchResult searchResult = searchResultsEnumeration.next();
                              totalResults++;
                              //System.out.println(">>>" + searchResult.getName());
                              System.out.println("----------------------");
                              // Print out some of the attributes, catch the exception if the attributes have no values
                              Attributes currentResultAttributes = searchResult.getAttributes();
                              if (currentResultAttributes != null) {
                                try {
                                  for (NamingEnumeration allCurResultAttributes = currentResultAttributes.getAll(); allCurResultAttributes.hasMore();) {
                                    Attribute attr = (Attribute) allCurResultAttributes.next();
                                    System.out.println("\t" + attr.getID());
                                    for (NamingEnumeration e = attr.getAll(); e.hasMore(); System.out.println("\t\t" + e.next()));
                                  }
                      
                                } catch (NullPointerException e) {
                                  System.out.println("problem listing attributes: " + e);
                                }
                              }
                            }
                            System.out.println("Total results: " + totalResults);
                      
                            ctx.close();
                          } catch (NamingException e) {
                            System.out.println("Problem searching directory: " + e);
                          }
                        }
                      }

                      LDAP search using Spring Ldap Template

                      Code:
                      public List<Person> findUserByName(String searchString) {
                      		logger.info("Enterign LdapSearchUtil.findUserByName");
                      		List<Person> lstperson = null;
                      		try{
                      			// creating search key 
                      		StringBuilder builder = new StringBuilder();
                      		builder.append(ConstantUtil.STAR).append(searchString).append(ConstantUtil.STAR);
                      		
                      		//Adding the filter
                      		AndFilter andFilter = new AndFilter();
                      		andFilter.and(new EqualsFilter(LdapConstantUtil.SEARCH_OBJECT_CLASS,LdapConstantUtil.SEARCH_OBJECT_PERSON));
                      		andFilter.and(new EqualsFilter(LdapConstantUtil.SEARCH_OBJECT_CLASS,LdapConstantUtil.SEARCH_OBJECT_TOP));
                      		andFilter.and(new EqualsFilter(LdapConstantUtil.LDAP_SEARCH_ANR, searchString));
                      		logger.debug("filter added--->"+andFilter.toString());
                      		searchCtls.setCountLimit(100);
                      		searchCtls.setTimeLimit(0);
                      		searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
                      		ContextSource contextSource = ldapTemplate.getContextSource();
                      		DirContext ctx = contextSource.getReadWriteContext();
                      		LdapContext lCtx = (LdapContext) ctx;
                      		lCtx.setRequestControls(new Control[]{
                      		         new PagedResultsControl(100, Control.CRITICAL) });
                      		lstperson = (List<Person>)ldapTemplate.search(LdapConstantUtil.USER_TREE_BASE_NODE, 
                      				andFilter.encode(),searchCtls,
                      				searchPersonLdapAttributeMapper );
                      		}catch (Exception ex) {
                      			logger.error("Enterign LdapSearchUtil.findUserByName",ex);
                      		}
                      		logger.info("Exiting LdapSearchUtil.findUserByName");
                      		return lstperson;
                      	}
                      we are stuck with this for quite sometime. Would be great if we get a better solution to tackle this problem.

                      Comment


                      • #12
                        we continued with a work around for this problem. We suppressed the exception SizeLimitExceededException and used AttributesMapperCallbackHandler to retrieve the results.

                        Code:
                        CollectingNameClassPairCallbackHandler handler = new AttributesMapperCallbackHandler(searchPersonLdapAttributeMapper);
                                try {
                                		ldapTemplate.search(LdapConstantUtil.USER_TREE_BASE_NODE,andFilter.encode(),searchControls, handler);
                                	} catch (SizeLimitExceededException ex) {
                                		logger.error("SizeLimitExceededException caught in  PersonLdapDAOImpl.findUserByName",ex);
                                		// safely ignore. Spring LDAP handles this exception different to SUNs implementation.
                                	}
                        	    lstperson = handler.getList();

                        Comment

                        Working...
                        X