directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alex Karasulu <akaras...@apache.org>
Subject Re: Search result in LDAP API
Date Thu, 28 Apr 2011 20:34:08 GMT
On Thu, Apr 28, 2011 at 11:30 PM, Emmanuel Lecharny <elecharny@gmail.com>wrote:

> 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.
>
>
Yeah I recommend taking our time with this. This is a big change. Maybe we
can experiment with it a little and see how test client code looks when
using the different approaches.

I would be really careful with this since it's pretty much the biggest
operation of all :-).

Regards,
Alex

Mime
View raw message