I was playing around a little bit with triggers and stored procedures. For me (as beginner) almost everything worked fine, except this big problem (don't know if it is a bug or if i did something wrong): If you restart the server, the attribute triggerExecutionSubentry in the subentry gets lost... [10:52:14] WARN [org.apache.directory.server.core.trigger.TriggerSpecCache] - Found triggerExecutionSubentry 'cn=trigger,dc=ds,dc=test,dc=net' without any prescriptiveTriggerSpecification
This is what i found out (without warranty, comments/imporovements welcome). Maybe it helps a little bit. Approach: 1 Implementing Stored Procedure 2 Adding entry for Stored Procedure 3 Adding the trigger as Attritbute (trigger for one Entry only) 4 Or adding Triggers for more Entries, e.g. (Sub)-Tree 5 Activate and deactivate Triggers More docs: http://joacim.breiler.com/apacheds/ch09s02.html#Planned%20New%20Features%20for%20Triggers http://people.apache.org/~ersiner/ldapcon.2007/LDAPcon.2007_LDAP.Stored.Procedures.and.Triggers.in.ApacheDS_by.Ersin.Er_Paper.pdf 1 Implementing the Stored Procedure Stored Prodedure are simple POJO with one or more public static methods (later called by the trigger). Example: package com.test; import java.util.ArrayList; import org.apache.directory.api.ldap.model.entry.Entry; import org.apache.directory.api.ldap.model.entry.Modification; public class TestTriggerInterceptor { public static void helloTrigger(Entry oldEntry, ArrayList<Modification> mods ) { System.out.println("Entry found: " + oldEntry.getDn()); for (Modification modification : mods) { System.out.println(modification.getOperation() + " " + modification.getAttribute()); } } } 2 Adding Stored Procedures Adding a new ou for triggers, for example: ou=Stored Procedures,ou=system Adding a new entry (=StoredProcedure) for saving the StoredProcedure (ObjectClass javaStoredProcUnit) Example: DN: storedProcUnitName=com.test.TestTriggerInterceptor,ou=Stored Procedures,ou=system Definition LDAP Stored Procedure: • ObjectClass: javaStoredProcUnit and storedProcUnit • storedProcUnitName: complete classname, e.g. com.test.TestTriggerInterceptor • storedProcLangId: always “Java” • javaByteCode: Upload byte-code with ds-studio (the .class - File) 3 Adding the trigger as Attritbute for one Entry only: Adding the attribut entryTriggerSpecification in the entry. The Value of the Attribute entryTriggerSpecification is the trigger, example: AFTER Modify CALL "com.test.TestTriggerInterceptor:helloTrigger" ($oldEntry, $modification); --> helloTrigger is the public static Method, we implemented above Possible Triggers: • AFTER Modify CALL • AFTER Add CALL … • AFTER Delete CALL … • AFTER ModifyDN CALL … Some possible parameters for the trigger: (found in org.apache.directory.api.ldap.trigger.StoredProcedureParameter): Modify_OBJECT( "$object" ) Modify_MODIFICATION( "$modification" ) Modify_OLD_ENTRY( "$oldEntry" ) Modify_NEW_ENTRY( "$newEntry" ) Add_ENTRY( "$entry" ) Add_ATTRIBUTES( "$attributes" ) Delete_NAME( "$name" ) Delete_DELETED_ENTRY( "$deletedEntry" ) ModifyDN_ENTRY( "$entry" ) ModifyDN_NEW_RDN( "$newrdn" ) ModifyDN_DELETE_OLD_RDN( "$deleteoldrdn" ) ModifyDN_NEW_SUPERIOR( "$newSuperior" ) ModifyDN_OLD_RDN( "$oldRDN" ) ModifyDN_OLD_SUPERIOR_DN( "$oldRDN" ) ModifyDN_NEW_DN( "$oldRDN" ) Examples for static mehtods and trigger attribute entryTriggerSpecification: Static method: public static void changeTrigger(Entry entry, ArrayList<Modification> mods ) { … } Trigger: AFTER Modify CALL "com.test.TriggerInterceptor:changeTrigger" ($oldEntry, $modification); Static method: public static void addTrigger(Dn newEntryDn, Entry addEntry ) { … } Trigger: AFTER Add CALL "com.test.TriggerInterceptor:addTrigger" ($entry, $attributes ); Static method: public static void deleteTrigger(Entry deleteEntry) { … } Trigger: AFTER Delete CALL " com.test.TriggerInterceptor:deleteTrigger" ($deletedEntry); 4 Adding Triggers for more Entries, e.g. (Sub)-Tree First: Adding an Administrative Area for Triggers --> adding new attribute administrativeRole with the Value triggerExecutionSpecificArea (didn't tries triggerExecutionInnerArea, don't what this is for) Then: adding a trigger-subentry (objectClass: triggerExecutionSubentry and subentry) Then: adding a prescriptiveTriggerSpecification attribute to the subentry. The value for prescriptiveTriggerSpecification is again the trigger, for Example: AFTER Modify CALL "com.test.TriggerInterceptor:changeTrigger" ($oldEntry, $modification); This approach does not work any more for me. When i restart my server, i can see the following log-Entry, when the server restarts: [10:52:14] WARN [org.apache.directory.server.core.trigger.TriggerSpecCache] - Found triggerExecutionSubentry 'cn=trigger,dc=ds,dc=test,dc=net' without any prescriptiveTriggerSpecification --> the subentry has definitely the attribute prescriptiveTriggerSpecification, i don't know how to solve ... 5 Activate and deactivate Triggers Setting the attribut ads-enabled to TRUE/FALSE: DN: ads-interceptorId=triggerInterceptor,ou=interceptors,ads-directoryServiceId=default,ou=config Emmanuel Lécharny <[email protected]> schrieb am 9:35 Freitag, 3.Februar 2017: Le 03/02/2017 à 09:14, Jim Willeke a écrit : > BTW: eDirectory has had LDAP Event Services which allows a client or a > server process to register for events and take an action. > > https://www.novell.com/documentation/developer/ldapover/ldap_enu/data/ag7bleo.html It's a slightly different system, AFAIU. events are sent to the client for it to act. In ApacheDS, it's really a way to configure the server to do something when a specific update occurs. -- Emmanuel Lecharny Symas.com directory.apache.org
