On Tue, Dec 11, 2012 at 3:23 PM, Emmanuel Lécharny <elecharny@gmail.com> wrote:
Hi !

I spent some time those past two days checking the way we are processing
the filtering of attributes when doing a search or a lookup. A new
OperationContext class has been created to merge the common elements
from the lookup, search and list operation. So far, so good.

Still, while adding some new tests, I saw that we still have issues :
- we can't do a lookup and filter the attributes, we don't get back
inherited attrs (like 'cn' or 'sn' when filtering using 'name')
- we do the filtering in many places (SchemaInterceptor,
AbstractBtreePartition, OperationalAttribute)
- we create too many lists in the middle for the sake of managing the
returned attributes

Basically, we have to follow a list of rules :
o when we have a '*' in the list, we should return all the user
attributes. We don't mind if we have some user attributes in the list,
they will be ignored
o when we have a '+' in the list, we should return all the operational
attributes. We don't mind if we have some operational attributes in the
list, they will be ignored
o if we have either a '+', a '*' or any attribute in the list, then we
should ignore the '1.1' attribute
o if we have no attributes, no '*', no '+', no '1.1', then '*' is
assumed to be present
o when we have any attribute in the list, not shadowed by the '*' or '+'
attributes, then we should return any attribute which chain of superior
contain one of the give attribute (ie, having 'name' in the list will
allow 'cn', 'sn', and every attribute which superior is 'name' to be

The four first rules can be enforced when we process the incoming
request and create the OperationContext. We will then just have either a
list of attributes naked (no '+', '*' or '1.1'), or a lits of attributes
with either '+' or '*', or just '+' and/or '*', or '1.1'.

Once this preliminary work is done, we can now filter the attributes
where it's needed (and it's not in the backend, because some attributes
may be added after we get back the entry from the backend : typically,
the entryDn attribute, or any collective attribute, or some potential
virtual attributes).

Considering the list of interceptors, and their order :
 - NormalizationInterceptor
 - AuthenticationInterceptor
 - ReferralInterceptor
 - AciAuthorizationInterceptor
 - DefaultAuthorizationInterceptor
 - AdministrativePointInterceptor
 - ExceptionInterceptor
 - SchemaInterceptor
 - OperationalAttributeInterceptor
 - CollectiveAttributeInterceptor
 - SubentryInterceptor
 - EventInterceptor
 - TriggerInterceptor
 - ChangeLogInterceptor
 - JournalInterceptor

the best place to do this filtering is probably in the SchemaInterceptor.

But, and there is a big but, when processing a search request, we do a
direct lookup from the backend, and we are not going through this chain.
What happens is that we are building a list of filters, and we apply
this list of filters on every entry fetched from the backend doing a
direct lookup. So the filter added by the SchemaInterceptor should also
do this filtering.

as the filtering is only applicable for search(and lookup) why not apply this logic in the cursor
after evaluating an entry, I know that this filtering logic was scattered before but with all that
moved to a utility class I think using that inside the cursor is the right thing rather than doing it in an
I don't think I have missed anything in this analysis, but if so, please
feel free to correct me !

Side note : I wonder if we shouldn't add a VirtualAttributeInterceptor
to process any virtual attributes, like the EntryDn. This interceptor
could be added after the SchemaInterceptor in the chain. wdyt ?

nooo  :) let us add this when we support more than one virtual attribute

thanks Emmanuel for the detailed information
Emmanuel Lécharny

Kiran Ayyagari