directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Göktürk Gezer <>
Subject Implementing Interceptor Extendibility
Date Sun, 30 Oct 2011 17:02:55 GMT
Hi Devs,

I'd like to do some brainstorming about Interceptor extension mechanism
which we're about to implement. Ideas those will come out from that thread
will enlighten our way on other extension points of the ApacheDS.

The first main issue is whether we're going to preserve old standalone
ApacheDS or not? Preserving API in nonOSGI environments had purpose. And
with the very simple method we've used in API, we can also preserve
ApacheDS's nonOSGI version too. Doing it will have pros and cons. The main
advantage will be of course letting existing user semantics unchanged. But
implementing extendibility without breaking ApaheDS's nonOSGI version will
put some limits on our extension capability on individual components.
Besides those limitations, we'll also end up having two different runtime
behaviour of ApacheDS. Documentation will be obviously painful. And some
aspects won't be implementable if we choose to preserve nonOSGI version.
For example, OSGI can give us the opportunity to don't restart server after
some changes on configuration, which will be perfect improvement of course.
But to make this we must go fully OSGI. List is long. We've talked about it
before but i wanted to ask that question again, because its an alive topic
and subject to change. Maybe some of yours mind could have been changed,
and i want to know if it did. If we proceed like what we've been talked
earlier, then I'm going to make ApacheDS (not shared) an OSGI application,
and use all of its loveliness.

To talk about Interceptors specifically, here is the design that i'm
thinking. To manage OSGI heavy dynamic nature, we must implement our
Interceptor related code in the closest module that is using Interceptors,
which is InterceptorChain in our case. First step will be implement a
component called InterceptorHub which is responsible for keeping list of
all Interceptors installed in the container(means installed in OSGI as
bundle). This hub will create an instance of every Interceptor per every
ApacheDS instance and keep it.

When an InterceptorChain want to iterate through interceptors, it will get
them from InterceptorHub rather then DirectoryService.getInterceptors(). So
it will get the most recent list of interceptors every time.

Currently in our config.ldif file, there is an interceptors entries. We can
leave those entries there for specifying mandatory interceptors. So if any
of them is not exists at the time server is starting we can throw an
exception saying necessary interceptor is not exist. But we won't be have
to list additional interceptors in that list. They will be automatically
attached to the active ApacheDS instances.

We'll also change the Interceptor implementations to be an IPojo component.
Those components will publish two main properties. First is their ordering
and the second is their bypass list.

Ordering is something we've talked about but i couldn't get a clear
explanation about it. What i suggest is like this: we publish three kind of
ordering from interceptor: strict, level and relax. "strict" means strict
ordering, this will be published from core interceptors and that strict
order will create a level. If we publish it as level we must also attach an
index with it, such as level-3. If we publish it as relax it means it can
be called anywhere in the chain after the strict ones. So lets suppose we
documented the core interceptor ordering like:

1- InterceptorA
2- InterceptorB
3- InterceptorC

So there is 3 level in interceptor chain. If somebody implement an
additional interceptor named InterceptorD and publish its ordering
as level-2, it is saying it must be called after InterceptorA(level-1). So
the new list will be:

1- InterceptorA
2- InterceptorD
3- InterceptorC

I didnt't numbered B as 3 but rather i grouped it with the InterceptorD,
putting InterceptorD above it. Why? What happens if vendor wants to
implement two custom interceptor named InterceptorD and InterceptorE and
want 2 of them to be called right after InterceptorA(after 1th level) but
want InterceptorD to be called first. So we must suborder those 2
interceptors. That's why i treated the first core list as levels rather
than orders ! So the ordering which is published from custom interceptor is
not sufficient to describe good ordering. We must also publish subordering
which specifies the ordering between that specific vendor's interceptors.

So lets suppose InterceptorD(ordering="strict-2",subordering="foo1"),
InterceptorE(ordering="strict-2", subordering="foo2"). Both interceptors
want to be executed after 1th level(means after InterceptorA). But they
also publish subordering with the same token, "foo". So they will be called
after 1.level which is InterceptorA, but also they will be called in order
InterceptorD - interceptorE with the help of their subordering string.

We can also depend on string ordering of Interceptor class names here, but
i think its not good. We can also merge ordering and subordering in one,
like (ordering="level2-foo1"). This way, we can define infinite subordering
by separating them with dashes.

So this is my way to give interceptor writers a way to describe their
interceptor's order in the chain. If i'm missing something here please say
it and i'll put it in consideration too.

View raw message