Hi,
here is a description of the data structure used to handle the
Administrative model in the AP branch.
We manipulate two kinds of objects that need to be stored in memory when
the server is started :
- administrativePoints (APs)
- subentries (SEs)
The relation between those two elements are simple :
- an AP can have zero to many SEs
- a SE can cover one to many APs role, but only one AP entry
- APs and SEs both have roles : AccessControl (AC), CollectiveAttribute
(CA), TriggeExecution (TE) and SubSchema (SS)
- roles are defined by some auxiliary ObjectClass in SEs, by an
attribute (AdministrativeRole) in APs
- the relation between an AP and a SE exists only if they have the same
role.
- A SE *must* be declared under an AP, which means that we can't have an
isolated AP, when the AP can be defined alone, but in this case, it's
just a placeholder.
As an example, if we define an AP for 2 roles (AC and CA), and three
subentries : SE1 for CA, and SE2 for AC and CA (the two subentries
define two different areas with their respective subtreeSpecification),
the SE1 is associated with the AP entry and with the CA role, and SE2 is
associated with the same AP entry but covers 2 roles.
Here, an AP entry is associated with 2 SEs, and SEs can cover one to
many roles.
To handle this, we need to define the following structures :
- AdministrativePoint will describe a AP role. It will be loaded when
the server is started, and loaded into some caches : one cache per role.
As we can't have 2 APs with the same role at one level in the DIT, we
can safely store the cache in a DnNode<AdministrativePoint> structure.
The AdministrativePoint itself is an interface, with some extented classes :
(AdministrativePoint)
o
|
+-- [AbstractAdministrativePoint] (A)
^
|
+-- [AutonomousAdministrativePoint]
|
+-- [AccessControlAdministrativePoint](A)
| ^
| |
| +-- AccessControlAAP
| |
| +-- AccessControlIAP
| |
| +-- AccessControlSAP
|
+-- [CollectiveAttributeAdministrativePoint](A)
| ^
| |
| +-- CollectiveAttributeAAP
| |
| +-- CollectiveAttributeIAP
| |
| +-- CollectiveAttributeSAP
|
+-- [TriggerExecutionAdministrativePoint](A)
| ^
| |
| +-- TriggerExecutionAAP
| |
| +-- TriggerExecutionIAP
| |
| +-- TriggerExecutionSAP
|
+-- [SubSchemaAdministrativePoint](A)
^
|
+-- SubSchemaAAP
|
+-- SubSchemaSAP
As we can see, we have as many classes as we have roles, and covered
area. (At this point, I'm not sure we need to define the AAP classes for
each role).
The abstract class holds all the fields needed to manipulate the APs
(except for the AAP) :
- DN dn : the AP position in the DIT
- String uuid : the AP EntryUUID
- seqNumber : the AP sequence number (one per role)
- AdministrativeRole role : the role (AC, CA, TE or SS)
- AdministrativePoint parent : the AP's parent. (used when the current
AP is an IAP : we will have to update it's parent's seqNumber if it's
deleted)
- Map<String, AdministrativePoint> children : the AP sub-APs (used when
there are some IAPs children)
- Set<Subentry> subentries : the set of subentries attached to this AP role
The Subentry class is simpler, as it holds only a few fields :
- SubtreeSpecification ss : defines the area on which the subentry acts
- Set<AdministrativeRole> administrativeRoles : The set of roles this
subentry is handling
- String uuid : The subentry EntryUUID
We also use some caches for AdminsitrativePoint and Subentries. they are
used as speedups for accessing those elements. Each kind of
AdministrativePoint will have its own cache, which will be a
DnNode<AdministrativePoint>, those caches are being handled by the
DirectoryService.
The SubEntryCache is slightly different, as it's currently a fixed size
cache, with a limited number of element stored into it. This is a bad
implementation, and has to be replaced by a standard cache, using
EhCache. It's supposed to be used to retrieve a subentry without havng
to do a lookup into the backend, when modifying the APs or the
subentries, but I don't think it's actually necessary. the rationnal is
that when we modify an AP, removing a role, the associated subentry
*must* have been deleted first, so a subentry cache is useless in this
case. And when updating an entry, we refer to the AP, which already has
a reference to the subentry, so we don't need a subentry cache. It will
be removed.
That's pretty much it. The last thing is the SeqNumbers which are added
to each AP entry, as we may have up o four different roles to manage,
and there is no reason to update an entry when we change a subentry for
a role the entry is not related with.
Hope it's clear enugh !
--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com