directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Emmanuel Lecharny <elecha...@gmail.com>
Subject Exception interceptor pb
Date Thu, 06 Jan 2011 16:26:51 GMT
Hi,

today, while tracking some issue in the server, I jumped into some code 
in the ExceptionInterceptor that I find questionable. Let me explain 
something we already discussed on IRC.

When we do a search, we go through the chain of interceptors, down to 
the backend. In the backend, we process the request, and construct a 
Cursor based on the search filter and the scope.

This cursor has not yet fetch any entry.

Then we go back the chain up to the SearchHandler. In the process, we 
construct a list of filters to apply to each entry we will fetch. Those 
filters simply select good candidates, and reject bad ones. They also 
eliminate not requested attributes or values.

When we go up the chain, and process the ExceptionInterceptor, the 
following code is executed :
     public EntryFilteringCursor search( NextInterceptor 
nextInterceptor, SearchOperationContext searchContext )
     {
         EntryFilteringCursor cursor = nextInterceptor.search( 
searchContext );

         // Check that if the cursor is empty, it's not because the DN 
is invalid.
         if ( !cursor.available() && !searchContext.getDn().isEmpty() && 
!subschemSubentryDn.equals( searchContext.getDn()) )
         {
             // We just check that the entry exists only if we didn't 
found any entry
             assertHasEntry( searchContext, "Attempt to search under 
non-existant entry:", searchContext.getDn() );
         }

         return cursor;
     }

The assertHasEntry method is :

     private void assertHasEntry( OperationContext opContext, String 
msg, DN dn ) throws LdapException
     {
         if ( !opContext.hasEntry( dn, ByPassConstants.HAS_ENTRY_BYPASS ) )
         {
             throw new LdapNoSuchObjectException( msg + dn.getName() );
         }
     }

And now, the problem : the cursor.available() call *always* return 
false, thus we most of the case do a lookup, which is costly. Every 
single search we do will always fetch N+1 entry : The N entry to return, 
plus the first entry a second time.

This is useless.

The reason why this check is being done is that we need to send a 
LDAP_NO_SUCH_OBJECT result if there is no entry returned.

We discussed some options we have. Currently, we have 2 :
- make the cursor return something different from false if there is an 
entry, even if we don't prefetch the entry.
- postpone this test and handle the case in the SearchHandler

Option #1 implies a huge refactoring of the cursor API. Not sure we want 
to do this
Option #2 is probably better. We just have to check that it's valid to 
check for the absence of an entry if the candidate have been discarded 
by some upper filter (for instance, if we rejected some entry because 
the ACIs mandated it). In this case, should we send back a 
LDAP_NO_SUCH_OBJECT?

I will experiment with Option #2, re-read the RFC, and update you.

-- 
Regards,
Cordialement,
Emmanuel L├ęcharny
www.iktek.com


Mime
View raw message