diff --git a/pom.xml b/pom.xml
index a7b330f6..7a0f41e9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -872,6 +872,21 @@
xml-apis
1.4.01
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.9.6
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ 2.9.6
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.9.6
+
diff --git a/src/main/java/org/lsc/AbstractSynchronize.java b/src/main/java/org/lsc/AbstractSynchronize.java
index 3e19b925..350d0d86 100644
--- a/src/main/java/org/lsc/AbstractSynchronize.java
+++ b/src/main/java/org/lsc/AbstractSynchronize.java
@@ -53,6 +53,12 @@
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import java.lang.ProcessBuilder;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.PrintWriter;
+import com.fasterxml.jackson.databind.ObjectMapper; // For encoding object to JSON
+import com.fasterxml.jackson.databind.ObjectWriter;
import javax.naming.CommunicationException;
@@ -257,6 +263,9 @@ protected final boolean clean2Ldap(Task task) {
// if we got here, we have a modification to apply - let's
// do it!
if (task.getDestinationService().apply(lm)) {
+ // Retrieve posthook for the current operation
+ String hook = syncOptions.getDeletePostHook();
+ Hooks.postSyncHook(hook, lm);
counter.incrementCountCompleted();
logAction(lm, id, task.getName());
} else {
@@ -828,6 +837,10 @@ public boolean run(IBean entry) {
// if we got here, we have a modification to apply - let's do it!
if (task.getDestinationService().apply(lm)) {
+ // Retrieve posthook for the current operation
+ String hook = task.getSyncOptions().getPostHook(modificationType);
+ Hooks.postSyncHook(hook, lm);
+
counter.incrementCountCompleted();
abstractSynchronize.logAction(lm, id, syncName);
return true;
@@ -939,3 +952,101 @@ public synchronized int getCountCompleted() {
return countCompleted;
}
}
+
+/**
+ * This object is managing posthook scripts
+ */
+class Hooks {
+
+ static final Logger LOGGER = LoggerFactory.getLogger(AbstractSynchronize.class);
+ /**
+ * Method calling a postSyncHook if necessary
+ *
+ * @return nothing
+ */
+ public final static void postSyncHook(final String hook, final LscModifications lm) {
+
+ if( hook != null && ! hook.equals("") )
+ {
+ // Compute json modifications
+ String jsonModifications = null;
+
+ switch (lm.getOperation()) {
+ case CREATE_OBJECT:
+ jsonModifications = getJsonModifications(lm);
+ callHook("create", hook, lm.getMainIdentifier(), jsonModifications);
+ break;
+
+ case UPDATE_OBJECT:
+ jsonModifications = getJsonModifications(lm);
+ callHook("update", hook, lm.getMainIdentifier(), jsonModifications);
+ break;
+
+ case CHANGE_ID:
+ jsonModifications = getJsonModifications(lm);
+ callHook("changeId", hook, lm.getMainIdentifier(), jsonModifications);
+ break;
+
+ case DELETE_OBJECT:
+ callHook("delete", hook, lm.getMainIdentifier(), jsonModifications);
+ break;
+
+ default:
+ LOGGER.info("Error: unknown operation for posthook {}", hook);
+ }
+ }
+ }
+
+ public final static void callHook( String operationType,
+ String hook,
+ String identifier,
+ String jsonModifications) {
+
+ LOGGER.info("Calling {} posthook {} for {}", operationType, hook, identifier);
+ try {
+ if( jsonModifications != null ) {
+ Process p = new ProcessBuilder(
+ hook,
+ identifier,
+ operationType,
+ jsonModifications)
+ .start();
+ }
+ else {
+ Process p = new ProcessBuilder(
+ hook,
+ identifier,
+ operationType)
+ .start();
+ }
+ }
+ catch(IOException e) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ e.printStackTrace(pw);
+ LOGGER.error("Error while calling {} posthook {} for {}: {}",
+ operationType,hook, identifier, sw.toString());
+ }
+ }
+
+ /**
+ * Method computing modifications as json
+ *
+ * @return modifications in a json String
+ */
+ public final static String getJsonModifications(final LscModifications lm) {
+ ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
+ String json = "";
+ try {
+ json = ow.writeValueAsString(lm.getLscAttributeModifications());
+ }
+ catch(Exception e) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ e.printStackTrace(pw);
+ LOGGER.error("Error while encoding LSC modifications to json", sw.toString());
+ }
+ return json;
+ }
+
+}
diff --git a/src/main/java/org/lsc/beans/syncoptions/ForceSyncOptions.java b/src/main/java/org/lsc/beans/syncoptions/ForceSyncOptions.java
index f5f6c1ba..8157887e 100644
--- a/src/main/java/org/lsc/beans/syncoptions/ForceSyncOptions.java
+++ b/src/main/java/org/lsc/beans/syncoptions/ForceSyncOptions.java
@@ -128,6 +128,26 @@ public String getCondition(LscModificationType operation) {
return DEFAULT_CONDITION;
}
+ public String getCreatePostHook() {
+ return "";
+ }
+
+ public String getDeletePostHook() {
+ return "";
+ }
+
+ public String getUpdatePostHook() {
+ return "";
+ }
+
+ public String getChangeIdPostHook() {
+ return "";
+ }
+
+ public String getPostHook(LscModificationType operation) {
+ return "";
+ }
+
public String getDn() {
return null;//((Ldap)task.getDestinationService()).getDn();
}
diff --git a/src/main/java/org/lsc/beans/syncoptions/ISyncOptions.java b/src/main/java/org/lsc/beans/syncoptions/ISyncOptions.java
index 9df18858..d60bfee5 100644
--- a/src/main/java/org/lsc/beans/syncoptions/ISyncOptions.java
+++ b/src/main/java/org/lsc/beans/syncoptions/ISyncOptions.java
@@ -153,6 +153,37 @@ public interface ISyncOptions {
String getCondition(LscModificationType operation);
+ /**
+ * Returns the posthook for a creation
+ *
+ * @return the posthook or "" if none is specified (default)
+ */
+ String getCreatePostHook();
+
+ /**
+ * Returns the posthook for an update
+ *
+ * @return the posthook or "" if none is specified (default)
+ */
+ String getUpdatePostHook();
+
+ /**
+ * Returns the posthook for a delete
+ *
+ * @return the posthook or "" if none is specified (default)
+ */
+ String getDeletePostHook();
+
+ /**
+ * Returns the posthook for a id change
+ *
+ * @return the posthook or "" if none is specified (default)
+ */
+ String getChangeIdPostHook();
+
+
+ String getPostHook(LscModificationType operation);
+
/**
* Return the expression used to infer the new object DN
* @return the new object dn pattern
diff --git a/src/main/java/org/lsc/beans/syncoptions/PropertiesBasedSyncOptions.java b/src/main/java/org/lsc/beans/syncoptions/PropertiesBasedSyncOptions.java
index aa04944d..deff1099 100644
--- a/src/main/java/org/lsc/beans/syncoptions/PropertiesBasedSyncOptions.java
+++ b/src/main/java/org/lsc/beans/syncoptions/PropertiesBasedSyncOptions.java
@@ -196,6 +196,53 @@ public String getCondition(LscModificationType operation) {
}
return result;
}
+
+ public String getCreatePostHook() {
+ if (conf.getHooks() == null || conf.getHooks().getCreatePostHook() == null) {
+ return "";
+ }
+ return conf.getHooks().getCreatePostHook();
+ }
+
+ public String getDeletePostHook() {
+ if (conf.getHooks() == null || conf.getHooks().getDeletePostHook() == null) {
+ return "";
+ }
+ return conf.getHooks().getDeletePostHook();
+ }
+
+ public String getUpdatePostHook() {
+ if (conf.getHooks() == null || conf.getHooks().getUpdatePostHook() == null) {
+ return "";
+ }
+ return conf.getHooks().getUpdatePostHook();
+ }
+
+ public String getChangeIdPostHook() {
+ if (conf.getHooks() == null || conf.getHooks().getChangeIdPostHook() == null) {
+ return "";
+ }
+ return conf.getHooks().getChangeIdPostHook();
+ }
+
+ public String getPostHook(LscModificationType operation) {
+ String result = "";
+ switch (operation) {
+ case CREATE_OBJECT:
+ result = this.getCreatePostHook();
+ break;
+ case UPDATE_OBJECT:
+ result = this.getUpdatePostHook();
+ break;
+ case DELETE_OBJECT:
+ result = this.getDeletePostHook();
+ break;
+ case CHANGE_ID:
+ result = this.getChangeIdPostHook();
+ break;
+ }
+ return result;
+ }
public String getDelimiter(String name) {
DatasetType dataset = LscConfiguration.getDataset(conf, name);
diff --git a/src/main/java/org/lsc/configuration/.gitignore b/src/main/java/org/lsc/configuration/.gitignore
index faf60484..e83453ba 100644
--- a/src/main/java/org/lsc/configuration/.gitignore
+++ b/src/main/java/org/lsc/configuration/.gitignore
@@ -4,6 +4,7 @@
/AuditType.java
/AuditsType.java
/ConditionsType.java
+/HooksType.java
/ConnectionType.java
/ConnectionsType.java
/CsvAuditType.java
diff --git a/src/main/resources/schemas/lsc-core-2.2.xsd b/src/main/resources/schemas/lsc-core-2.2.xsd
index 968c0227..8f416e87 100644
--- a/src/main/resources/schemas/lsc-core-2.2.xsd
+++ b/src/main/resources/schemas/lsc-core-2.2.xsd
@@ -323,7 +323,16 @@
-
+
+
+
+
+
+
+
+
+
+
@@ -334,6 +343,7 @@
default="FORCE" />
+