| Title: 1.4 - Interceptors |
| NavPrev: 1.3-directory-service.html |
| NavPrevText: 1.3 - DirectoryService |
| NavUp: 1-architecture.html |
| NavUpText: 1 - Architecture |
| NavNext: 1.5-backend.html |
| NavNextText: 1.5 - Backend |
| Notice: Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| . |
| http://www.apache.org/licenses/LICENSE-2.0 |
| . |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| |
| # 1.4 - Interceptors |
| |
| _Interceptors_ are functional layers inside the _DirectoryService_. Each one of them are responsible for a specific task. They are ordered, and this order is not to be changed. |
| |
| Each operation received by the _DirectoryService_ will be processed by various interceptors, one after the other, down to the backend, and again when the result comes back to the caller. An _interceptor_ can call the next _interceptor_, whcih will be determinated by the position it has in the chain of _interceptors_, or simply return. Note that calling the next _interceptor_ does not require that you know which one will be called. |
| |
| Some _Interceptors_ can be disabled, some other can be enabled. It's also possible to add some new one. |
| |
| All in all, they will handle operations from a specific functional aspect. |
| |
| ## Handled operations |
| |
| Each _Interceptor_ handles a subset of the possible operations, among those listed in the following table : |
| |
| | Operation | Description | |
| |---|---| |
| | add | Adds an entry in the backend | |
| | bind | Binds on the DirectoryService | |
| | compare | Compares the elements with the associated entry in the backend | |
| | delete | Deletes the entry | |
| | getRooDSE | Gets back the RootDSE entry | |
| | hasEntry | Tells if an entry exists | |
| | lookup | Fetches an entry | |
| | modify | Modifies an entry | |
| | move | Moves an entry | |
| | moveAndRename | Moves and renames an entry | |
| | rename | Renames an entry | |
| | search | Searches for entries | |
| | unbind | Unbinds from the DirectoryService | |
| |
| It is important to understand that each operation will go through each _Interceptor_ declared to handle the operation, down to the backend. |
| |
| ## Existing interceptors |
| |
| The following interceptors are already present in the server, even if they are not enabled. |
| In this table, we list all the operations each interceptor is handling, and if the _interceptor_ is enabled by default or not : |
| |
| | Interceptor | Enabled |add|bnd|cmp|del|DSE|has|lkp|mod|mov|m&r|ren|sea|ubd| |
| |---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| |
| | AciAuthorizationInterceptor | yes | X | - | X | X | - | X | X | X | X | X | X | X | - | |
| | AdministrativePointInterceptor | yes | X | - | - | X | - | - | - | X | X | X | X | ? | - | |
| | AuthenticationInterceptor | yes | X | X | X | X | X | X | X | X | X | X | X | X | X | |
| | ChangeLogInterceptor | yes || X | - | - | X | - | - | - | X | X | X | X | - | - | |
| | CollectiveAttributeInterceptor | yes | X | - | - | - | - | - | X | X | - | - | - | X | - | |
| | DefaultAuthorizationInterceptor | yes | - | - | - | X | - | - | X | X | X | X | X | X | - | |
| | DelayInducingInterceptor | no | - | - | - | - | - | - | - | - | - | - | - | X | - | |
| | EventInterceptor | yes | X | - | - | X | - | - | - | X | X | X | X | - | - | |
| | ExceptionInterceptor | yes | X | - | - | X | - | - | - | X | X | X | X | - | - | |
| | JournalInterceptor | yes | X | - | - | X | - | - | - | X | X | X | X | - | - | |
| | KeyDerivationInterceptor | no | X | - | - | - | - | - | - | X | - | - | - | - | - | |
| | NormalizationInterceptor | yes | X | X | X | X | - | X | X | X | X | X | X | X | - | |
| | NumberIncrementInterceptor | yes | X | - | - | - | - | - | - | - | - | - | - | - | - | |
| | OperationalAttributeInterceptor | yes | X | - | - | X | - | - | X | X | X | X | X | X | - | |
| | PasswordHashingInterceptor | no | X | - | - | - | - | - | - | X | - | - | - | - | - | |
| | CryptPasswordHashingInterceptor | no | X | - | - | - | - | - | - | X | - | - | - | - | - | |
| | Md5PasswordHashingInterceptor | no | X | - | - | - | - | - | - | X | - | - | - | - | - | |
| | Pkcs5s2PasswordHashingInterceptor | no | X | - | - | - | - | - | - | X | - | - | - | - | - | |
| | Sha256PasswordHashingInterceptor | no | X | - | - | - | - | - | - | X | - | - | - | - | - | |
| | Sha384PasswordHashingInterceptor | no | X | - | - | - | - | - | - | X | - | - | - | - | - | |
| | Sha512PasswordHashingInterceptor | no | X | - | - | - | - | - | - | X | - | - | - | - | - | |
| | ShaPasswordHashingInterceptor | no | X | - | - | - | - | - | - | X | - | - | - | - | - | |
| | Smd5PasswordHashingInterceptor | no | X | - | - | - | - | - | - | X | - | - | - | - | - | |
| | Ssha256PasswordHashingInterceptor | no | X | - | - | - | - | - | - | X | - | - | - | - | - | |
| | Ssha384PasswordHashingInterceptor | no | X | - | - | - | - | - | - | X | - | - | - | - | - | |
| | Ssha512PasswordHashingInterceptor | no | X | - | - | - | - | - | - | X | - | - | - | - | - | |
| | SshaPasswordHashingInterceptor | no | X | - | - | - | - | - | - | X | - | - | - | - | - | |
| | ReferralInterceptor | yes | X | - | - | X | - | - | - | X | X | X | X | - | - | |
| | SchemaInterceptor | yes | X | - | X | - | - | - | X | X | - | ? | X | X | - | |
| | SubentryInterceptor | yes | X | - | - | X | - | - | ? | X | X | X | X | X | - | |
| | TimerInterceptor | no | X | X | X | X | X | X | X | X | X | X | X | X | X | |
| | TriggerInterceptor | yes | X | - | - | X | - | - | - | X | X | X | X | - | - | |
| |
| The operations that are available are the operations for which we have some implementation in the interceptor class. For instance, the _JournalInterceptor_ class implement the _add_, _delete_, _modify_, _move_, _moveAndRename_ and _rename_ methods. |
| |
| ## Interceptors order |
| |
| As we already said, the _Interceptors_ order is significant : why would we proceed an _Add_ operation through all the _Interceptors_ if the user is simply denied the right to add an entry by the _AciAuthorizationInterceptor_ ? |
| |
| Currently, the following order is enforced : |
| |
| | Order | Interceptor | |
| |---|---| |
| | 1 | NormalizationInterceptor | |
| | 2 | AuthenticationInterceptor | |
| | 3 | ReferralInterceptor | |
| | 4 | AciAuthorizationInterceptor | |
| | 5 | DefaultAuthorizationInterceptor | |
| | 6 | AdministrativePointInterceptor | |
| | 7 | ExceptionInterceptor | |
| | 8 | SchemaInterceptor | |
| | 9 | OperationalAttributeInterceptor | |
| | 10 | SubentryInterceptor | |
| | 11 | EventInterceptor | |
| | 12 | TriggerInterceptor | |
| | 13 | ChangeLogInterceptor | |
| | 14 | JournalInterceptor | |
| |
| ## Example |
| |
| Let's consider the _search_ operation. It will be processed successively by the following _Interceptors_, as it can be deduced by the two previous tables : |
| |
| * NormalizationInterceptor |
| * AuthenticationInterceptor |
| * AciAuthorizationInterceptor |
| * DefaultAuthorizationInterceptor |
| * SchemaInterceptor |
| * OperationalAttributeInterceptor |
| * SubentryInterceptor |
| |
| |
| We can do the same exercise for each operation. |
| |
| ## Processing |
| |
| Basically, an _Interceptor_ receives a request for an operation, does some pre-processing, calls the next _Interceptor_ in the chain, does some post-processing, and returns a result. |
| |
| Calling the next _Interceptor_ is as simple as calling the _next(OperationContext)_ method, which will compute the right _Interceptor_. |
| |
| The pre-processing and post-processing are standard Java code, there is nothing special there. |
| |
| Each operation is passed into an instance of a specific _OperationContext_, which contains all what is needed about the operation and the environment. |