directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Emmanuel Lecharny <elecha...@gmail.com>
Subject Re: Search result in LDAP API
Date Thu, 28 Apr 2011 20:30:33 GMT
On 4/28/11 10:19 PM, Alex Karasulu wrote:
> On Thu, Apr 28, 2011 at 2:39 PM, Kiran Ayyagari<kayyagari@apache.org>wrote:
>
>> On Thu, Apr 28, 2011 at 4:38 PM, Emmanuel Lecharny<elecharny@gmail.com>
>> wrote:
>>> Hi guys,
>>>
>>> yesterday, as I started to write the doc about the Search Operation, I
>> faced
>>> some issue. Let me explain.
>>>
>>> When you do a simple search, you get back a cursor :
>>>
>>>         SearchCursor cursor = connection.search( "ou=system",
>>> "(objectclass=*)", SearchScope.ONELEVEL );
>>>
>>> The SearchCursor extends Cursor<Response>.
>>>
>>> That means you get some Response when you do a search, so you have to
>> write
>>> such code to get back the entries :
>>>
>>>         while ( cursor.next() )
>>>         {
>>>             Entry entry = ((SearchResultEntry)(cursor.get())).getEntry();
>>>
>>> which is just horrible.
>>>
>>> The reason is that the search can return three kinds of responses :
>>> - normal entries
>>> - search result done
>>> - and referrals
>>>
>> there is one more, the IntermediateResponse
>>
>>> We can deal with the searchResultDone (and we do, you can call a
>>> cursor.getSearchResultDone() when you quit the loop), but the referral
>>> handling is a bit more special.
>>>
>>> We have many options to clean up the API here :
>>> - first, we can consider that a cursor.get() will always return an entry
>> (or
>>> a SearchResultEntry). In this case, if the next result is a referral, we
>>> have two cases. The first one, if the users have asked the API to chase
>>> referrals, he will get back an entry, and we are fine. The other case is
>>> when we don't chase referrals, and then we can just throw a
>>> ReferralException, up to the client to catch this exception
>> IMHO a cursor, should never assume about the type of elements it is
>> serving beyond a certain level of abstraction
>>   (sadly in LDAP, as we know, the result set contains different types
>> of objects for the same operation,
>>   But we have already made some changes in this way, like getting the
>> SearchResultDone)
>>> - second, we can expect the user to check the result type before grabbing
>>> it. If it's a SearchResultEntry, then do a cursor.getEntry(), otherwise
>> do a
>>> cursor.getReferral().
>> this is exactly the way we wanted it to work, not just for referrals
>> but any sort of search response,
>> i.e the cursor returns the ResponseS (the super type) and it is upto
>> the user to deal based on the specific subtype
>> infact the above shown code snippet casts directly to a
>> SearchResultEntry cause we know first hand that this search
>> (perhaps done in a test case) will *only* return search entries and
>> nothing else.
>>
>>> - third, we can cumulate all the referrals and ask the user to look on
>> the
>>> cursor a second time to deal with referral. We would have to store those
>>> referrals internally to the cursor, and add a nextReferral() method.
>>>
>> IMO, this should be avoided by all means, cause in the worst case it
>> will lead to a OOM
>>
>>> I personally find the first solution the least painful for our users. In
>> any
>>> case, we have to do two things :
>>> - change the current API
>>> - implement the Referral chasing in the API
>>>
>>> So, now, wdyt ?
>> my preference would be to keep the get() method as it is and add new
>> method(s) like getEntry() , getReferral()
>> and user can call the respective method based on his requirement, and
>> these method can throw
>> an exception when the expected type is not compatible
>> e.x NotAnEntryException when getEntry() is called but the current
>> result is a referral
>>
>>
> And so that leads to the need for checks to see what kind of object we have
> the cursor currently positioned under:
>
>      isEntry()
>      isReferral()
>      isIntermediate()
>
> This is probably best. I agree with Kiran that keeping around referral
> objects and returning them in the end is not good from a memory perspective.
> But if I remember correctly according to the protocol, an LDAP server does
> this automatically: meaning it's supposed to return the referrals at the end
> after returning regular entries.
>
> Someone please let me know if this is the case. Have not had the time to
> look this up.

We reached a bit different conclusion, following Stefan's suggestions 
which sounds good. For the record :
- the search( SearchRequest ) operation will return a SearchCursor, and 
it will be up to the (advanced) user to deal with the different response 
types (SearchResultEntry, SearchResultReferral and IntermediateResponse)
- any other search will return an EntryCursor.
- the SearchResutDone result will just be managed when we get out of the 
loop
- we can add the isEntry(), isReferral() and isIntermediate() methods, 
in addition to the getEntry(), getReferral() and getIntermediate() 
methods in the SearchCursor interface

That sounds to be a good compromise, as of today.


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


Mime
View raw message