diff --git a/README.md b/README.md
index 86ac3d4..6312029 100644
--- a/README.md
+++ b/README.md
@@ -2,3 +2,40 @@
A helper class to queue XDS events into a Micro Focus Identity Manager driver cache
Initially developed by Peter Lambrechtsen and published at https://community.microfocus.com/t5/Identity-Manager-Tips/Sending-a-XDS-Message-from-one-driver-to-another/ta-p/1777175 , this version fixes a few bugs and adds javadocs.
+
+If a supplied document is only a command and lacks the complete nds wrapper, a wrapper will be added.
+Includes support for injecting both regular "add/modify" events and also "migrate into Identity Vault" style queries.
+
+# dxqueue-es
+
+This version is a port of the code to ECMAScript and adds more robust validation.
+
+
+There are minor differences between the internal pre-validation of DOM documents. In the ECMAScript version, all attempts are made to try and ensure that invalid documents are not queued. Instead an error message is returned.
+This is to prevent crashing or hanging of the engine. Also the ECMAScript version, one can pass a document where the operation/element node is the root of the documet and it will be accepted.
+
+Also The JAR version expects that you select pass a child of the root node.
+
+## sendQueueEvent
+Support for queueing "add/modify" style operations.
+
+The JAR version is called from the defined namespace.
+ dxqueue:sendQueueEvent(java.lang.String driverDN, org.w3c.dom.Element element)
+
+The ECMAScript version is a drop-in replacement for the Java helper class, with identical calling syntax.
+Any well formed operation, including driver-specific operations and namespaces can be queued.
+
+ es:sendQueueEvent(java.lang.String driverDN, org.w3c.dom.Element element)
+
+
+## sendMigrateApp
+Support for queueing "migrate into Identity Vault" style queries.
+
+The JAR version is called from the defined namespace.
+ dxqueue:sendMigrateApp(java.lang.String driverDN, org.w3c.dom.Element element)
+
+The ECMAScript version is a drop-in replacement for the Java helper class, with identical calling syntax.
+
+Only query or query-ex operations can be queued.
+
+ es:sendMigrateApp(java.lang.String driverDN, org.w3c.dom.Element element)
diff --git a/demo/SendMigrateApp-es.trace b/demo/SendMigrateApp-es.trace
new file mode 100644
index 0000000..16bad55
--- /dev/null
+++ b/demo/SendMigrateApp-es.trace
@@ -0,0 +1,288 @@
+[10/31/21 12:56:08.800]:SendMigrateApp ST:Start transaction.
+[10/31/21 12:56:08.801]:SendMigrateApp ST:Processing events for transaction.
+[10/31/21 12:56:08.801]:SendMigrateApp ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+
+ dsque-test
+
+
+ dsqueue-test
+
+
+
+
+
+[10/31/21 12:56:08.802]:SendMigrateApp ST:Applying event transformation policies.
+[10/31/21 12:56:08.802]:SendMigrateApp ST:Applying policy: %+C%14CSend Migrate App%-C.
+[10/31/21 12:56:08.803]:SendMigrateApp ST: Applying to modify #1.
+[10/31/21 12:56:08.803]:SendMigrateApp ST: Evaluating selection criteria for rule 'Query Event'.
+[10/31/21 12:56:08.803]:SendMigrateApp ST: (if-global-variable 'drv.action.queueEvent' available) = TRUE.
+[10/31/21 12:56:08.803]:SendMigrateApp ST: Rule selected.
+[10/31/21 12:56:08.803]:SendMigrateApp ST: Applying rule 'Query Event'.
+[10/31/21 12:56:08.803]:SendMigrateApp ST: Action: do-set-local-variable("attrsToClone",notrace="true",scope="policy",arg-node-set(token-split(",",csv="true","cached-time,class-id,class-name,timestamp"))).
+[10/31/21 12:56:08.804]:SendMigrateApp ST: -- trace suppressed --
+[10/31/21 12:56:08.804]:SendMigrateApp ST: Action: do-append-xml-element("query","..").
+[10/31/21 12:56:08.804]:SendMigrateApp ST: Action: do-for-each(arg-node-set(token-xpath("../query[last()]"))).
+[10/31/21 12:56:08.804]:SendMigrateApp ST: arg-node-set(token-xpath("../query[last()]"))
+[10/31/21 12:56:08.804]:SendMigrateApp ST: token-xpath("../query[last()]")
+[10/31/21 12:56:08.804]:SendMigrateApp ST: Token Value: {}.
+[10/31/21 12:56:08.804]:SendMigrateApp ST: Arg Value: {}.
+[10/31/21 12:56:08.804]:SendMigrateApp ST: Performing actions for local-variable(current-node) = .
+[10/31/21 12:56:08.805]:SendMigrateApp ST: Action: do-set-local-variable("parent-node",scope="policy",arg-node-set(token-local-variable("current-node"))).
+[10/31/21 12:56:08.805]:SendMigrateApp ST: arg-node-set(token-local-variable("current-node"))
+[10/31/21 12:56:08.805]:SendMigrateApp ST: token-local-variable("current-node")
+[10/31/21 12:56:08.805]:SendMigrateApp ST: Token Value: {}.
+[10/31/21 12:56:08.805]:SendMigrateApp ST: Arg Value: {}.
+[10/31/21 12:56:08.805]:SendMigrateApp ST: Action: do-set-xml-attr("event-id","$current-node","migrateQuery:trigger").
+[10/31/21 12:56:08.805]:SendMigrateApp ST: arg-string("migrateQuery:trigger")
+[10/31/21 12:56:08.806]:SendMigrateApp ST: token-text("migrateQuery:trigger")
+[10/31/21 12:56:08.806]:SendMigrateApp ST: Arg Value: "migrateQuery:trigger".
+[10/31/21 12:56:08.806]:SendMigrateApp ST: Action: do-clone-xpath(dest-expression="$current-node",notrace="true",src-expression="@*[name()=$attrsToClone]").
+[10/31/21 12:56:08.806]:SendMigrateApp ST: Action: do-set-xml-attr("scope","$current-node","entry").
+[10/31/21 12:56:08.806]:SendMigrateApp ST: arg-string("entry")
+[10/31/21 12:56:08.806]:SendMigrateApp ST: token-text("entry")
+[10/31/21 12:56:08.806]:SendMigrateApp ST: Arg Value: "entry".
+[10/31/21 12:56:08.807]:SendMigrateApp ST: Action: do-clone-xpath(dest-expression="$current-node",notrace="true",src-expression="$current-op/association").
+[10/31/21 12:56:08.807]:SendMigrateApp ST: Action: do-append-xml-element("search-attr","$current-node",before="*[1]",notrace="true").
+[10/31/21 12:56:08.807]:SendMigrateApp ST: Action: do-set-xml-attr("attr-name","$current-node/search-attr","CN").
+[10/31/21 12:56:08.807]:SendMigrateApp ST: arg-string("CN")
+[10/31/21 12:56:08.807]:SendMigrateApp ST: token-text("CN")
+[10/31/21 12:56:08.807]:SendMigrateApp ST: Arg Value: "CN".
+[10/31/21 12:56:08.807]:SendMigrateApp ST: Action: do-append-xml-element("value","$current-node/search-attr[last()]",before="*[1]",notrace="true").
+[10/31/21 12:56:08.808]:SendMigrateApp ST: Action: do-append-xml-text("$current-node/search-attr[last()]/value[last()]",token-src-name()).
+[10/31/21 12:56:08.808]:SendMigrateApp ST: arg-string(token-src-name())
+[10/31/21 12:56:08.808]:SendMigrateApp ST: token-src-name()
+[10/31/21 12:56:08.808]:SendMigrateApp ST: Token Value: "employee2".
+[10/31/21 12:56:08.808]:SendMigrateApp ST: Arg Value: "employee2".
+[10/31/21 12:56:08.808]:SendMigrateApp ST: Action: do-set-local-variable("varQueryXDS-ns",scope="policy",arg-node-set(token-xml-parse(token-xml-serialize(token-xpath("$current-node",notrace="true"))))).
+[10/31/21 12:56:08.809]:SendMigrateApp ST: arg-node-set(token-xml-parse(token-xml-serialize(token-xpath("$current-node",notrace="true"))))
+[10/31/21 12:56:08.809]:SendMigrateApp ST: token-xml-parse(token-xml-serialize(token-xpath("$current-node",notrace="true")))
+[10/31/21 12:56:08.809]:SendMigrateApp ST: token-xml-parse(token-xml-serialize(token-xpath("$current-node",notrace="true")))
+[10/31/21 12:56:08.809]:SendMigrateApp ST: token-xml-serialize(token-xpath("$current-node",notrace="true"))
+[10/31/21 12:56:08.809]:SendMigrateApp ST: token-xml-serialize(token-xpath("$current-node",notrace="true"))
+[10/31/21 12:56:08.809]:SendMigrateApp ST: token-xpath("$current-node",notrace="true")
+[10/31/21 12:56:08.810]:SendMigrateApp ST: Token Value: { @cached-time = "20211031125608.711Z" @class-name = "User" @event-id = "migrateQuery:trigger" @scope = "entry" @timestamp = "1635684968#2"}.
+[10/31/21 12:56:08.815]:SendMigrateApp ST: Arg Value: { @cached-time = "20211031125608.711Z" @class-name = "User" @event-id = "migrateQuery:trigger" @scope = "entry" @timestamp = "1635684968#2"}.
+[10/31/21 12:56:08.815]:SendMigrateApp ST: Token Value: "
+
+ employee2
+
+".
+[10/31/21 12:56:08.816]:SendMigrateApp ST: Arg Value: "
+
+ employee2
+
+".
+[10/31/21 12:56:08.817]:SendMigrateApp ST: Token Value: {/}.
+[10/31/21 12:56:08.817]:SendMigrateApp ST: Arg Value: {/}.
+[10/31/21 12:56:08.817]:SendMigrateApp ST: Action: do-strip-xpath("$current-node").
+[10/31/21 12:56:08.817]:SendMigrateApp ST: Action: do-trace-message(token-xml-serialize(token-local-variable("varQueryXDS-ns"))).
+[10/31/21 12:56:08.818]:SendMigrateApp ST: arg-string(token-xml-serialize(token-local-variable("varQueryXDS-ns")))
+[10/31/21 12:56:08.818]:SendMigrateApp ST: token-xml-serialize(token-local-variable("varQueryXDS-ns"))
+[10/31/21 12:56:08.818]:SendMigrateApp ST: token-xml-serialize(token-local-variable("varQueryXDS-ns"))
+[10/31/21 12:56:08.818]:SendMigrateApp ST: token-local-variable("varQueryXDS-ns")
+[10/31/21 12:56:08.818]:SendMigrateApp ST: Token Value: {/}.
+[10/31/21 12:56:08.818]:SendMigrateApp ST: Arg Value: {/}.
+[10/31/21 12:56:08.818]:SendMigrateApp ST: Token Value: "
+
+ employee2
+
+".
+[10/31/21 12:56:08.819]:SendMigrateApp ST: Arg Value: "
+
+ employee2
+
+".
+[10/31/21 12:56:08.819]:SendMigrateApp ST:
+
+ employee2
+
+
+[10/31/21 12:56:08.819]:SendMigrateApp ST: Action: do-set-local-variable("DriverDN",scope="policy",token-parse-dn(dest-dn-format="slash",length="-2",src-dn-format="slash","\IDVP\system\driverset1\SendMigrateApp")+"\JDBC").
+[10/31/21 12:56:08.820]:SendMigrateApp ST: arg-string(token-parse-dn(dest-dn-format="slash",length="-2",src-dn-format="slash","\IDVP\system\driverset1\SendMigrateApp")+"\JDBC")
+[10/31/21 12:56:08.820]:SendMigrateApp ST: token-parse-dn(dest-dn-format="slash",length="-2",src-dn-format="slash","\IDVP\system\driverset1\SendMigrateApp")
+[10/31/21 12:56:08.820]:SendMigrateApp ST: token-parse-dn(dest-dn-format="slash",length="-2",src-dn-format="slash","\IDVP\system\driverset1\SendMigrateApp")
+[10/31/21 12:56:08.820]:SendMigrateApp ST: token-text("\IDVP\system\driverset1\SendMigrateApp")
+[10/31/21 12:56:08.821]:SendMigrateApp ST: Arg Value: "\IDVP\system\driverset1\SendMigrateApp".
+[10/31/21 12:56:08.821]:SendMigrateApp ST: Token Value: "\IDVP\system\driverset1".
+[10/31/21 12:56:08.821]:SendMigrateApp ST: token-text("\JDBC")
+[10/31/21 12:56:08.821]:SendMigrateApp ST: Arg Value: "\IDVP\system\driverset1\JDBC".
+[10/31/21 12:56:08.821]:SendMigrateApp ST: Action: do-if().
+[10/31/21 12:56:08.821]:SendMigrateApp ST: Evaluating conditions.
+[10/31/21 12:56:08.821]:SendMigrateApp ST: (if-global-variable 'drv.action.queueEvent' equal "use-es") = TRUE.
+[10/31/21 12:56:08.822]:SendMigrateApp ST: Performing if actions.
+[10/31/21 12:56:08.822]:SendMigrateApp ST: Action: do-set-local-variable("CmdResult",scope="policy",arg-node-set(token-xpath("es:sendMigrateApp($DriverDN, $varQueryXDS-ns)"))).
+[10/31/21 12:56:08.822]:SendMigrateApp ST: arg-node-set(token-xpath("es:sendMigrateApp($DriverDN, $varQueryXDS-ns)"))
+[10/31/21 12:56:08.822]:SendMigrateApp ST: token-xpath("es:sendMigrateApp($DriverDN, $varQueryXDS-ns)")
+[10/31/21 12:56:08.822]:SendMigrateApp ST: sendMigrateApp: Cleaning up supplied XDS
+[10/31/21 12:56:08.822]:SendMigrateApp ST: sendMigrateApp: Document root node: query
+[10/31/21 12:56:08.823]:SendMigrateApp ST: sendMigrateApp: Cleaned up XDS
+[10/31/21 12:56:08.823]:SendMigrateApp ST: sendMigrateApp: Validating document
+[10/31/21 12:56:08.823]:SendMigrateApp ST: sendMigrateApp: Detected known command: query
+[10/31/21 12:56:08.823]:SendMigrateApp ST: sendMigrateApp: Serializing document to ByteArray with encoding: UTF-8
+[10/31/21 12:56:08.824]:SendMigrateApp ST: sendMigrateApp: Detected tree name: IDVP
+[10/31/21 12:56:08.824]:SendMigrateApp ST: sendMigrateApp: Attempting to authenticate to tree
+[10/31/21 12:56:08.824]:SendMigrateApp ST: sendMigrateApp: Resolving source driver:\IDVP\system\driverset1\SendMigrateApp
+[10/31/21 12:56:08.824]:SendMigrateApp ST: sendMigrateApp: Verifying target driver exists: \IDVP\system\driverset1\JDBC
+[10/31/21 12:56:08.824]:SendMigrateApp ST: sendMigrateApp: Verifying rights to source driver: \IDVP\system\driverset1\SendMigrateApp
+[10/31/21 12:56:08.825]:SendMigrateApp ST: sendMigrateApp: Queuing supplied XDS
+[10/31/21 12:56:08.828]:SendMigrateApp ST: Token Value: { @dtdversion = "4.0" @ndsversion = "8.x"}.
+[10/31/21 12:56:08.829]:SendMigrateApp ST: Arg Value: { @dtdversion = "4.0" @ndsversion = "8.x"}.
+[10/31/21 12:56:08.829]:SendMigrateApp ST: Action: do-if().
+[10/31/21 12:56:08.829]:SendMigrateApp ST: Evaluating conditions.
+[10/31/21 12:56:08.829]:SendMigrateApp ST: (if-global-variable 'drv.action.queueEvent' equal "use-jar") = FALSE.
+[10/31/21 12:56:08.830]:SendMigrateApp ST: Performing else actions.
+[10/31/21 12:56:08.830]:SendMigrateApp ST: Action: do-trace-message(token-xml-serialize(token-xpath("$CmdResult//status"))).
+[10/31/21 12:56:08.830]:SendMigrateApp ST: arg-string(token-xml-serialize(token-xpath("$CmdResult//status")))
+[10/31/21 12:56:08.830]:SendMigrateApp ST: token-xml-serialize(token-xpath("$CmdResult//status"))
+[10/31/21 12:56:08.830]:SendMigrateApp ST: token-xml-serialize(token-xpath("$CmdResult//status"))
+[10/31/21 12:56:08.830]:SendMigrateApp ST: token-xpath("$CmdResult//status")
+[10/31/21 12:56:08.830]:SendMigrateApp ST: Token Value: { @level = "success"}.
+[10/31/21 12:56:08.831]:SendMigrateApp ST: Arg Value: { @level = "success"}.
+[10/31/21 12:56:08.831]:SendMigrateApp ST: Token Value: "Submitted document for execution on subscriber channel on driver: \IDVP\system\driverset1\JDBC".
+[10/31/21 12:56:08.831]:SendMigrateApp ST: Arg Value: "Submitted document for execution on subscriber channel on driver: \IDVP\system\driverset1\JDBC".
+[10/31/21 12:56:08.831]:SendMigrateApp ST:Submitted document for execution on subscriber channel on driver: \IDVP\system\driverset1\JDBC
+[10/31/21 12:56:08.831]:SendMigrateApp ST:Policy returned:
+[10/31/21 12:56:08.832]:SendMigrateApp ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+
+ dsque-test
+
+
+ dsqueue-test
+
+
+
+
+
+[10/31/21 12:56:08.833]:SendMigrateApp ST:Subscriber processing modify for \IDVP\data\users\employee2.
+[10/31/21 12:56:08.833]:SendMigrateApp ST:Converting to
+[10/31/21 12:56:08.833]:SendMigrateApp ST:Reading relevant attributes from \IDVP\data\users\employee2.
+[10/31/21 12:56:08.833]:SendMigrateApp ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+
+
+
+
+
+[10/31/21 12:56:08.834]:SendMigrateApp ST:Pumping XDS to eDirectory.
+[10/31/21 12:56:08.834]:SendMigrateApp ST:Performing operation query for \IDVP\data\users\employee2.
+[10/31/21 12:56:08.834]:SendMigrateApp ST:--JCLNT-- \IDVP\system\driverset1\SendMigrateApp : Duplicating : context = 760807635, tempContext = 760807600
+[10/31/21 12:56:08.835]:SendMigrateApp ST:--JCLNT-- \IDVP\system\driverset1\SendMigrateApp : Calling free on tempContext = 760807600
+[10/31/21 12:56:08.835]:SendMigrateApp ST:Read result:
+[10/31/21 12:56:08.835]:SendMigrateApp ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+[10/31/21 12:56:08.836]:SendMigrateApp ST:Synthetic add:
+[10/31/21 12:56:08.836]:SendMigrateApp ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+ employee2
+
+
+ dsqueue-test
+
+
+ Employee
+
+
+
+
+[10/31/21 12:56:08.838]:SendMigrateApp ST:No object matching policies.
+[10/31/21 12:56:08.838]:SendMigrateApp ST:No object creation policies.
+[10/31/21 12:56:08.838]:SendMigrateApp ST:No object placement policies.
+[10/31/21 12:56:08.838]:SendMigrateApp ST:Submitting add to subscriber shim.
+[10/31/21 12:56:08.838]:SendMigrateApp ST:No command transformation policies.
+[10/31/21 12:56:08.838]:SendMigrateApp ST:Filtering out notification-only attributes.
+[10/31/21 12:56:08.838]:SendMigrateApp ST:Fixing up association references.
+[10/31/21 12:56:08.838]:SendMigrateApp ST:No schema mapping policies.
+[10/31/21 12:56:08.838]:SendMigrateApp ST:No output transformation policies.
+[10/31/21 12:56:08.839]:SendMigrateApp ST:Submitting document to subscriber shim:
+[10/31/21 12:56:08.839]:SendMigrateApp ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+ employee2
+
+
+ dsqueue-test
+
+
+ Employee
+
+
+
+
+[10/31/21 12:56:08.840]:SendMigrateApp ST:SubscriptionShim.execute() returned:
+[10/31/21 12:56:08.840]:SendMigrateApp ST:
+
+
+ DirXML Null Driver
+ NetIQ Corporation
+
+
+
+[10/31/21 12:56:08.841]:SendMigrateApp ST:No input transformation policies.
+[10/31/21 12:56:08.841]:SendMigrateApp ST:No schema mapping policies.
+[10/31/21 12:56:08.841]:SendMigrateApp ST:Resolving association references.
+[10/31/21 12:56:08.841]:SendMigrateApp ST:Processing returned document.
+[10/31/21 12:56:08.841]:SendMigrateApp ST:Processing operation for .
+[10/31/21 12:56:08.841]:SendMigrateApp ST:
+DirXML Log Event -------------------
+ Driver: \IDVP\system\driverset1\SendMigrateApp
+ Channel: Subscriber
+ Object: \IDVP\data\users\employee2
+ Status: Success
+[10/31/21 12:56:08.842]:SendMigrateApp ST:End transaction.
diff --git a/demo/SendMigrateApp.trace b/demo/SendMigrateApp.trace
new file mode 100644
index 0000000..a3e1b0e
--- /dev/null
+++ b/demo/SendMigrateApp.trace
@@ -0,0 +1,298 @@
+[11/01/21 15:52:14.975]:SendMigrateApp ST:Start transaction.
+[11/01/21 15:52:14.975]:SendMigrateApp ST:Processing events for transaction.
+[11/01/21 15:52:14.977]:SendMigrateApp ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+
+ HR-JAR
+
+
+ HR-JAR2
+
+
+
+
+
+[11/01/21 15:52:14.979]:SendMigrateApp ST:Applying event transformation policies.
+[11/01/21 15:52:14.979]:SendMigrateApp ST:Applying policy: %+C%14CSend Migrate App%-C.
+[11/01/21 15:52:14.979]:SendMigrateApp ST: Applying to modify #1.
+[11/01/21 15:52:14.979]:SendMigrateApp ST: Evaluating selection criteria for rule 'Query Event'.
+[11/01/21 15:52:14.980]:SendMigrateApp ST: (if-global-variable 'drv.action.queueEvent' available) = TRUE.
+[11/01/21 15:52:14.980]:SendMigrateApp ST: Rule selected.
+[11/01/21 15:52:14.980]:SendMigrateApp ST: Applying rule 'Query Event'.
+[11/01/21 15:52:14.980]:SendMigrateApp ST: Action: do-set-local-variable("attrsToClone",notrace="true",scope="policy",arg-node-set(token-split(",",csv="true","cached-time,class-id,class-name,timestamp"))).
+[11/01/21 15:52:14.981]:SendMigrateApp ST: -- trace suppressed --
+[11/01/21 15:52:14.981]:SendMigrateApp ST: Action: do-append-xml-element("query","..").
+[11/01/21 15:52:14.982]:SendMigrateApp ST: Action: do-for-each(arg-node-set(token-xpath("../query[last()]"))).
+[11/01/21 15:52:14.982]:SendMigrateApp ST: arg-node-set(token-xpath("../query[last()]"))
+[11/01/21 15:52:14.982]:SendMigrateApp ST: token-xpath("../query[last()]")
+[11/01/21 15:52:14.982]:SendMigrateApp ST: Token Value: {}.
+[11/01/21 15:52:14.982]:SendMigrateApp ST: Arg Value: {}.
+[11/01/21 15:52:14.982]:SendMigrateApp ST: Performing actions for local-variable(current-node) = .
+[11/01/21 15:52:14.983]:SendMigrateApp ST: Action: do-set-local-variable("parent-node",scope="policy",arg-node-set(token-local-variable("current-node"))).
+[11/01/21 15:52:14.983]:SendMigrateApp ST: arg-node-set(token-local-variable("current-node"))
+[11/01/21 15:52:14.983]:SendMigrateApp ST: token-local-variable("current-node")
+[11/01/21 15:52:14.983]:SendMigrateApp ST: Token Value: {}.
+[11/01/21 15:52:14.984]:SendMigrateApp ST: Arg Value: {}.
+[11/01/21 15:52:14.984]:SendMigrateApp ST: Action: do-set-xml-attr("event-id","$current-node","migrateQuery:trigger").
+[11/01/21 15:52:14.984]:SendMigrateApp ST: arg-string("migrateQuery:trigger")
+[11/01/21 15:52:14.984]:SendMigrateApp ST: token-text("migrateQuery:trigger")
+[11/01/21 15:52:14.984]:SendMigrateApp ST: Arg Value: "migrateQuery:trigger".
+[11/01/21 15:52:14.984]:SendMigrateApp ST: Action: do-clone-xpath(dest-expression="$current-node",notrace="true",src-expression="@*[name()=$attrsToClone]").
+[11/01/21 15:52:14.985]:SendMigrateApp ST: Action: do-set-xml-attr("scope","$current-node","entry").
+[11/01/21 15:52:14.985]:SendMigrateApp ST: arg-string("entry")
+[11/01/21 15:52:14.985]:SendMigrateApp ST: token-text("entry")
+[11/01/21 15:52:14.985]:SendMigrateApp ST: Arg Value: "entry".
+[11/01/21 15:52:14.986]:SendMigrateApp ST: Action: do-clone-xpath(dest-expression="$current-node",notrace="true",src-expression="$current-op/association").
+[11/01/21 15:52:14.986]:SendMigrateApp ST: Action: do-append-xml-element("search-attr","$current-node",before="*[1]",notrace="true").
+[11/01/21 15:52:14.986]:SendMigrateApp ST: Action: do-set-xml-attr("attr-name","$current-node/search-attr","CN").
+[11/01/21 15:52:14.986]:SendMigrateApp ST: arg-string("CN")
+[11/01/21 15:52:14.987]:SendMigrateApp ST: token-text("CN")
+[11/01/21 15:52:14.987]:SendMigrateApp ST: Arg Value: "CN".
+[11/01/21 15:52:14.987]:SendMigrateApp ST: Action: do-append-xml-element("value","$current-node/search-attr[last()]",before="*[1]",notrace="true").
+[11/01/21 15:52:14.987]:SendMigrateApp ST: Action: do-append-xml-text("$current-node/search-attr[last()]/value[last()]",token-src-name()).
+[11/01/21 15:52:14.988]:SendMigrateApp ST: arg-string(token-src-name())
+[11/01/21 15:52:14.988]:SendMigrateApp ST: token-src-name()
+[11/01/21 15:52:14.988]:SendMigrateApp ST: Token Value: "employee1".
+[11/01/21 15:52:14.988]:SendMigrateApp ST: Arg Value: "employee1".
+[11/01/21 15:52:14.988]:SendMigrateApp ST: Action: do-set-local-variable("varQueryXDS-ns",scope="policy",arg-node-set(token-xml-parse(token-xml-serialize(token-xpath("$current-node",notrace="true"))))).
+[11/01/21 15:52:14.989]:SendMigrateApp ST: arg-node-set(token-xml-parse(token-xml-serialize(token-xpath("$current-node",notrace="true"))))
+[11/01/21 15:52:14.989]:SendMigrateApp ST: token-xml-parse(token-xml-serialize(token-xpath("$current-node",notrace="true")))
+[11/01/21 15:52:14.989]:SendMigrateApp ST: token-xml-parse(token-xml-serialize(token-xpath("$current-node",notrace="true")))
+[11/01/21 15:52:14.990]:SendMigrateApp ST: token-xml-serialize(token-xpath("$current-node",notrace="true"))
+[11/01/21 15:52:14.990]:SendMigrateApp ST: token-xml-serialize(token-xpath("$current-node",notrace="true"))
+[11/01/21 15:52:14.990]:SendMigrateApp ST: token-xpath("$current-node",notrace="true")
+[11/01/21 15:52:14.990]:SendMigrateApp ST: Token Value: { @cached-time = "20211101155214.898Z" @class-name = "User" @event-id = "migrateQuery:trigger" @scope = "entry" @timestamp = "1635781934#2"}.
+[11/01/21 15:52:15.016]:SendMigrateApp ST: Arg Value: { @cached-time = "20211101155214.898Z" @class-name = "User" @event-id = "migrateQuery:trigger" @scope = "entry" @timestamp = "1635781934#2"}.
+[11/01/21 15:52:15.017]:SendMigrateApp ST: Token Value: "
+
+ employee1
+
+".
+[11/01/21 15:52:15.017]:SendMigrateApp ST: Arg Value: "
+
+ employee1
+
+".
+[11/01/21 15:52:15.018]:SendMigrateApp ST: Token Value: {/}.
+[11/01/21 15:52:15.018]:SendMigrateApp ST: Arg Value: {/}.
+[11/01/21 15:52:15.018]:SendMigrateApp ST: Action: do-strip-xpath("$current-node").
+[11/01/21 15:52:15.018]:SendMigrateApp ST: Action: do-trace-message(token-xml-serialize(token-local-variable("varQueryXDS-ns"))).
+[11/01/21 15:52:15.019]:SendMigrateApp ST: arg-string(token-xml-serialize(token-local-variable("varQueryXDS-ns")))
+[11/01/21 15:52:15.019]:SendMigrateApp ST: token-xml-serialize(token-local-variable("varQueryXDS-ns"))
+[11/01/21 15:52:15.019]:SendMigrateApp ST: token-xml-serialize(token-local-variable("varQueryXDS-ns"))
+[11/01/21 15:52:15.019]:SendMigrateApp ST: token-local-variable("varQueryXDS-ns")
+[11/01/21 15:52:15.020]:SendMigrateApp ST: Token Value: {/}.
+[11/01/21 15:52:15.020]:SendMigrateApp ST: Arg Value: {/}.
+[11/01/21 15:52:15.020]:SendMigrateApp ST: Token Value: "
+
+ employee1
+
+".
+[11/01/21 15:52:15.020]:SendMigrateApp ST: Arg Value: "
+
+ employee1
+
+".
+[11/01/21 15:52:15.021]:SendMigrateApp ST:
+
+ employee1
+
+
+[11/01/21 15:52:15.022]:SendMigrateApp ST: Action: do-set-local-variable("DriverDN",scope="policy",token-parse-dn(dest-dn-format="slash",length="-2",src-dn-format="slash","\IDVP\system\driverset1\SendMigrateApp")+"\JDBC").
+[11/01/21 15:52:15.022]:SendMigrateApp ST: arg-string(token-parse-dn(dest-dn-format="slash",length="-2",src-dn-format="slash","\IDVP\system\driverset1\SendMigrateApp")+"\JDBC")
+[11/01/21 15:52:15.022]:SendMigrateApp ST: token-parse-dn(dest-dn-format="slash",length="-2",src-dn-format="slash","\IDVP\system\driverset1\SendMigrateApp")
+[11/01/21 15:52:15.023]:SendMigrateApp ST: token-parse-dn(dest-dn-format="slash",length="-2",src-dn-format="slash","\IDVP\system\driverset1\SendMigrateApp")
+[11/01/21 15:52:15.023]:SendMigrateApp ST: token-text("\IDVP\system\driverset1\SendMigrateApp")
+[11/01/21 15:52:15.023]:SendMigrateApp ST: Arg Value: "\IDVP\system\driverset1\SendMigrateApp".
+[11/01/21 15:52:15.023]:SendMigrateApp ST: Token Value: "\IDVP\system\driverset1".
+[11/01/21 15:52:15.023]:SendMigrateApp ST: token-text("\JDBC")
+[11/01/21 15:52:15.024]:SendMigrateApp ST: Arg Value: "\IDVP\system\driverset1\JDBC".
+[11/01/21 15:52:15.024]:SendMigrateApp ST: Action: do-if().
+[11/01/21 15:52:15.024]:SendMigrateApp ST: Evaluating conditions.
+[11/01/21 15:52:15.024]:SendMigrateApp ST: (if-global-variable 'drv.action.queueEvent' equal "use-es") = FALSE.
+[11/01/21 15:52:15.024]:SendMigrateApp ST: Action: do-if().
+[11/01/21 15:52:15.024]:SendMigrateApp ST: Evaluating conditions.
+[11/01/21 15:52:15.025]:SendMigrateApp ST: (if-global-variable 'drv.action.queueEvent' equal "use-jar") = TRUE.
+[11/01/21 15:52:15.030]:SendMigrateApp ST: Performing if actions.
+[11/01/21 15:52:15.030]:SendMigrateApp ST: Action: do-set-local-variable("XDS",scope="policy",arg-node-set(token-xml-parse(""+token-xml-serialize(token-local-variable("varQueryXDS-ns"))+""))).
+[11/01/21 15:52:15.031]:SendMigrateApp ST: arg-node-set(token-xml-parse(""+token-xml-serialize(token-local-variable("varQueryXDS-ns"))+""))
+[11/01/21 15:52:15.031]:SendMigrateApp ST: token-xml-parse(""+token-xml-serialize(token-local-variable("varQueryXDS-ns"))+"")
+[11/01/21 15:52:15.031]:SendMigrateApp ST: token-xml-parse(""+token-xml-serialize(token-local-variable("varQueryXDS-ns"))+"")
+[11/01/21 15:52:15.032]:SendMigrateApp ST: token-text("")
+[11/01/21 15:52:15.032]:SendMigrateApp ST: token-xml-serialize(token-local-variable("varQueryXDS-ns"))
+[11/01/21 15:52:15.032]:SendMigrateApp ST: token-xml-serialize(token-local-variable("varQueryXDS-ns"))
+[11/01/21 15:52:15.033]:SendMigrateApp ST: token-local-variable("varQueryXDS-ns")
+[11/01/21 15:52:15.033]:SendMigrateApp ST: Token Value: {/}.
+[11/01/21 15:52:15.033]:SendMigrateApp ST: Arg Value: {/}.
+[11/01/21 15:52:15.033]:SendMigrateApp ST: Token Value: "
+
+ employee1
+
+".
+[11/01/21 15:52:15.034]:SendMigrateApp ST: token-text("")
+[11/01/21 15:52:15.034]:SendMigrateApp ST: Arg Value: "
+
+ employee1
+
+".
+[11/01/21 15:52:15.035]:SendMigrateApp ST: Token Value: {/}.
+[11/01/21 15:52:15.036]:SendMigrateApp ST: Arg Value: {/}.
+[11/01/21 15:52:15.036]:SendMigrateApp ST: Action: do-set-local-variable("CmdResult",scope="policy",arg-node-set(token-xpath("dxqueue:sendMigrateApp($DriverDN, $XDS/nds)"))).
+[11/01/21 15:52:15.037]:SendMigrateApp ST: arg-node-set(token-xpath("dxqueue:sendMigrateApp($DriverDN, $XDS/nds)"))
+[11/01/21 15:52:15.037]:SendMigrateApp ST: token-xpath("dxqueue:sendMigrateApp($DriverDN, $XDS/nds)")
+[11/01/21 15:52:15.044]:SendMigrateApp ST: Token Value: { @dtdversion = "4.0" @ndsversion = "8.x"}.
+[11/01/21 15:52:15.045]:SendMigrateApp ST: Arg Value: { @dtdversion = "4.0" @ndsversion = "8.x"}.
+[11/01/21 15:52:15.045]:SendMigrateApp ST: Action: do-trace-message(token-xml-serialize(token-xpath("$CmdResult//status"))).
+[11/01/21 15:52:15.045]:SendMigrateApp ST: arg-string(token-xml-serialize(token-xpath("$CmdResult//status")))
+[11/01/21 15:52:15.046]:SendMigrateApp ST: token-xml-serialize(token-xpath("$CmdResult//status"))
+[11/01/21 15:52:15.046]:SendMigrateApp ST: token-xml-serialize(token-xpath("$CmdResult//status"))
+[11/01/21 15:52:15.046]:SendMigrateApp ST: token-xpath("$CmdResult//status")
+[11/01/21 15:52:15.046]:SendMigrateApp ST: Token Value: { @level = "success"}.
+[11/01/21 15:52:15.047]:SendMigrateApp ST: Arg Value: { @level = "success"}.
+[11/01/21 15:52:15.047]:SendMigrateApp ST: Token Value: "Submitted document to \IDVP\system\driverset1\JDBC".
+[11/01/21 15:52:15.047]:SendMigrateApp ST: Arg Value: "Submitted document to \IDVP\system\driverset1\JDBC".
+[11/01/21 15:52:15.047]:SendMigrateApp ST:Submitted document to \IDVP\system\driverset1\JDBC
+[11/01/21 15:52:15.048]:SendMigrateApp ST:Policy returned:
+[11/01/21 15:52:15.048]:SendMigrateApp ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+
+ HR-JAR
+
+
+ HR-JAR2
+
+
+
+
+
+[11/01/21 15:52:15.051]:SendMigrateApp ST:Subscriber processing modify for \IDVP\data\users\employee1.
+[11/01/21 15:52:15.051]:SendMigrateApp ST:Converting to
+[11/01/21 15:52:15.051]:SendMigrateApp ST:Reading relevant attributes from \IDVP\data\users\employee1.
+[11/01/21 15:52:15.052]:SendMigrateApp ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+
+
+
+
+
+[11/01/21 15:52:15.053]:SendMigrateApp ST:Pumping XDS to eDirectory.
+[11/01/21 15:52:15.053]:SendMigrateApp ST:Performing operation query for \IDVP\data\users\employee1.
+[11/01/21 15:52:15.053]:SendMigrateApp ST:--JCLNT-- \IDVP\system\driverset1\SendMigrateApp : Duplicating : context = 195362983, tempContext = 195362979
+[11/01/21 15:52:15.054]:SendMigrateApp ST:--JCLNT-- \IDVP\system\driverset1\SendMigrateApp : Calling free on tempContext = 195362979
+[11/01/21 15:52:15.054]:SendMigrateApp ST:Read result:
+[11/01/21 15:52:15.055]:SendMigrateApp ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+[11/01/21 15:52:15.075]:SendMigrateApp ST:Synthetic add:
+[11/01/21 15:52:15.075]:SendMigrateApp ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+ employee1
+
+
+ HR-JAR2
+
+
+ Employee
+
+
+
+
+[11/01/21 15:52:15.078]:SendMigrateApp ST:No object matching policies.
+[11/01/21 15:52:15.078]:SendMigrateApp ST:No object creation policies.
+[11/01/21 15:52:15.079]:SendMigrateApp ST:No object placement policies.
+[11/01/21 15:52:15.079]:SendMigrateApp ST:Submitting add to subscriber shim.
+[11/01/21 15:52:15.079]:SendMigrateApp ST:No command transformation policies.
+[11/01/21 15:52:15.079]:SendMigrateApp ST:Filtering out notification-only attributes.
+[11/01/21 15:52:15.080]:SendMigrateApp ST:Fixing up association references.
+[11/01/21 15:52:15.080]:SendMigrateApp ST:No schema mapping policies.
+[11/01/21 15:52:15.080]:SendMigrateApp ST:No output transformation policies.
+[11/01/21 15:52:15.081]:SendMigrateApp ST:Submitting document to subscriber shim:
+[11/01/21 15:52:15.081]:SendMigrateApp ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+ employee1
+
+
+ HR-JAR2
+
+
+ Employee
+
+
+
+
+[11/01/21 15:52:15.082]:SendMigrateApp ST:SubscriptionShim.execute() returned:
+[11/01/21 15:52:15.083]:SendMigrateApp ST:
+
+
+ DirXML Null Driver
+ NetIQ Corporation
+
+
+
+[11/01/21 15:52:15.083]:SendMigrateApp ST:No input transformation policies.
+[11/01/21 15:52:15.083]:SendMigrateApp ST:No schema mapping policies.
+[11/01/21 15:52:15.084]:SendMigrateApp ST:Resolving association references.
+[11/01/21 15:52:15.084]:SendMigrateApp ST:Processing returned document.
+[11/01/21 15:52:15.084]:SendMigrateApp ST:Processing operation for .
+[11/01/21 15:52:15.084]:SendMigrateApp ST:
+DirXML Log Event -------------------
+ Driver: \IDVP\system\driverset1\SendMigrateApp
+ Channel: Subscriber
+ Object: \IDVP\data\users\employee1
+ Status: Success
+[11/01/21 15:52:15.084]:SendMigrateApp ST:End transaction.
\ No newline at end of file
diff --git a/demo/SendMigrateApp.xml b/demo/SendMigrateApp.xml
new file mode 100644
index 0000000..21b5cb4
--- /dev/null
+++ b/demo/SendMigrateApp.xml
@@ -0,0 +1,211 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Configures the driver shim to send a periodic status message on the publisher channel when there has been no publisher traffic for the given number of seconds.
+ 0
+
+
+
+
+
+
+
+
+
+
+
+ use-es
+ none
+ use-jar
+ use-es
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Query Event
+ This policy will trigger on an incoming event, and generate a XDS Message to put onto the other driver. In this scenario, it does the following:
+- Create a query document
+- Inject it into the other driver tagged as a "Migrate From App" query.
+- Any resulting instance will be turned into a sync by the engine.
+
+There are a few tricks:
+- DriverDN must include the full TreeName.
+- sendMigrateApp will return a Nodeset so you must set the variable type to be a nodeset. - Resulting nodeset can be parsed to determine if the queue event request was successful or not. This does not indicate whether the query ran successfully, only that the queue event was successful.
+- Target driver can be same driver, or another driver. (not yet tested injecting events for drivers that run on another server in driverset)
+- Target driver does not have to be running, but it cannot be disabled.
+
+
+
+
+
+
+
+
+
+ cached-time,class-id,class-name,timestamp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ migrateQuery:trigger
+
+
+
+
+
+ entry
+
+
+
+
+
+
+ CN
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ~dirxml.auto.driverdn~
+
+ \JDBC
+
+
+
+
+
+ use-es
+
+
+
+
+
+
+
+
+
+
+
+
+
+ use-jar
+
+
+
+
+
+
+ <nds><input>
+
+
+
+ </input></nds>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/SendQueue-es.trace b/demo/SendQueue-es.trace
new file mode 100644
index 0000000..0461234
--- /dev/null
+++ b/demo/SendQueue-es.trace
@@ -0,0 +1,348 @@
+[10/31/21 12:56:08.717]:SendQueueEvent ST:Start transaction.
+[10/31/21 12:56:08.717]:SendQueueEvent ST:Processing events for transaction.
+[10/31/21 12:56:08.718]:SendQueueEvent ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+
+ dsque-test
+
+
+ dsqueue-test
+
+
+
+
+
+[10/31/21 12:56:08.719]:SendQueueEvent ST:Applying event transformation policies.
+[10/31/21 12:56:08.719]:SendQueueEvent ST:Applying policy: %+C%14CSend Queue Event%-C.
+[10/31/21 12:56:08.720]:SendQueueEvent ST: Applying to modify #1.
+[10/31/21 12:56:08.720]:SendQueueEvent ST: Evaluating selection criteria for rule 'Capture Event'.
+[10/31/21 12:56:08.720]:SendQueueEvent ST: (if-global-variable 'drv.action.queueEvent' available) = TRUE.
+[10/31/21 12:56:08.720]:SendQueueEvent ST: Rule selected.
+[10/31/21 12:56:08.720]:SendQueueEvent ST: Applying rule 'Capture Event'.
+[10/31/21 12:56:08.722]:SendQueueEvent ST: Action: do-set-local-variable("OPERATION",scope="policy",token-replace-all(">",">",token-replace-all("<","<",token-xml-serialize(token-xpath("."))))).
+[10/31/21 12:56:08.722]:SendQueueEvent ST: arg-string(token-replace-all(">",">",token-replace-all("<","<",token-xml-serialize(token-xpath(".")))))
+[10/31/21 12:56:08.723]:SendQueueEvent ST: token-replace-all(">",">",token-replace-all("<","<",token-xml-serialize(token-xpath("."))))
+[10/31/21 12:56:08.723]:SendQueueEvent ST: token-replace-all(">",">",token-replace-all("<","<",token-xml-serialize(token-xpath("."))))
+[10/31/21 12:56:08.724]:SendQueueEvent ST: token-replace-all("<","<",token-xml-serialize(token-xpath(".")))
+[10/31/21 12:56:08.724]:SendQueueEvent ST: token-replace-all("<","<",token-xml-serialize(token-xpath(".")))
+[10/31/21 12:56:08.724]:SendQueueEvent ST: token-xml-serialize(token-xpath("."))
+[10/31/21 12:56:08.724]:SendQueueEvent ST: token-xml-serialize(token-xpath("."))
+[10/31/21 12:56:08.724]:SendQueueEvent ST: token-xpath(".")
+[10/31/21 12:56:08.724]:SendQueueEvent ST: Token Value: { @cached-time = "20211031125608.697Z" @class-name = "User" @event-id = "b5fd30f29e6f#20211031125608#1#1:4b7da613-d2d2-4075-b9ab-13a67d4bd2d2" @qualified-src-dn = "O=data\OU=users\CN=employee2" @src-dn = "\IDVP\data\users\employee2" @src-entry-id = "33766" @timestamp = "1635684968#2"}.
+[10/31/21 12:56:08.725]:SendQueueEvent ST: Arg Value: { @cached-time = "20211031125608.697Z" @class-name = "User" @event-id = "b5fd30f29e6f#20211031125608#1#1:4b7da613-d2d2-4075-b9ab-13a67d4bd2d2" @qualified-src-dn = "O=data\OU=users\CN=employee2" @src-dn = "\IDVP\data\users\employee2" @src-entry-id = "33766" @timestamp = "1635684968#2"}.
+[10/31/21 12:56:08.726]:SendQueueEvent ST: Token Value: "
+
+
+ dsque-test
+
+
+ dsqueue-test
+
+
+".
+[10/31/21 12:56:08.727]:SendQueueEvent ST: Arg Value: "
+
+
+ dsque-test
+
+
+ dsqueue-test
+
+
+".
+[10/31/21 12:56:08.727]:SendQueueEvent ST: Token Value: "<modify cached-time="20211031125608.697Z" class-name="User" event-id="b5fd30f29e6f#20211031125608#1#1:4b7da613-d2d2-4075-b9ab-13a67d4bd2d2" qualified-src-dn="O=data\OU=users\CN=employee2" src-dn="\IDVP\data\users\employee2" src-entry-id="33766" timestamp="1635684968#2">
+ <modify-attr attr-name="Given Name">
+ <remove-value>
+ <value timestamp="1635684963#2" type="string">dsque-test</value>
+ </remove-value>
+ <add-value>
+ <value timestamp="1635684968#2" type="string">dsqueue-test</value>
+ </add-value>
+ </modify-attr>
+</modify>".
+[10/31/21 12:56:08.728]:SendQueueEvent ST: Arg Value: "<modify cached-time="20211031125608.697Z" class-name="User" event-id="b5fd30f29e6f#20211031125608#1#1:4b7da613-d2d2-4075-b9ab-13a67d4bd2d2" qualified-src-dn="O=data\OU=users\CN=employee2" src-dn="\IDVP\data\users\employee2" src-entry-id="33766" timestamp="1635684968#2">
+ <modify-attr attr-name="Given Name">
+ <remove-value>
+ <value timestamp="1635684963#2" type="string">dsque-test</value>
+ </remove-value>
+ <add-value>
+ <value timestamp="1635684968#2" type="string">dsqueue-test</value>
+ </add-value>
+ </modify-attr>
+</modify>".
+[10/31/21 12:56:08.729]:SendQueueEvent ST: Token Value: "<modify cached-time="20211031125608.697Z" class-name="User" event-id="b5fd30f29e6f#20211031125608#1#1:4b7da613-d2d2-4075-b9ab-13a67d4bd2d2" qualified-src-dn="O=data\OU=users\CN=employee2" src-dn="\IDVP\data\users\employee2" src-entry-id="33766" timestamp="1635684968#2">
+ <modify-attr attr-name="Given Name">
+ <remove-value>
+ <value timestamp="1635684963#2" type="string">dsque-test</value>
+ </remove-value>
+ <add-value>
+ <value timestamp="1635684968#2" type="string">dsqueue-test</value>
+ </add-value>
+ </modify-attr>
+</modify>".
+[10/31/21 12:56:08.730]:SendQueueEvent ST: Arg Value: "<modify cached-time="20211031125608.697Z" class-name="User" event-id="b5fd30f29e6f#20211031125608#1#1:4b7da613-d2d2-4075-b9ab-13a67d4bd2d2" qualified-src-dn="O=data\OU=users\CN=employee2" src-dn="\IDVP\data\users\employee2" src-entry-id="33766" timestamp="1635684968#2">
+ <modify-attr attr-name="Given Name">
+ <remove-value>
+ <value timestamp="1635684963#2" type="string">dsque-test</value>
+ </remove-value>
+ <add-value>
+ <value timestamp="1635684968#2" type="string">dsqueue-test</value>
+ </add-value>
+ </modify-attr>
+</modify>".
+[10/31/21 12:56:08.731]:SendQueueEvent ST: Action: do-set-local-variable("XDS",scope="policy",arg-node-set(token-xml-parse(""+"INSERT INTO AUDIT(CN,EVENTID,XDS) VALUES ('"+token-attr("CN")+"','"+token-xpath("@event-id")+"','"+token-local-variable("OPERATION")+"')"))).
+[10/31/21 12:56:08.732]:SendQueueEvent ST: arg-node-set(token-xml-parse(""+"INSERT INTO AUDIT(CN,EVENTID,XDS) VALUES ('"+token-attr("CN")+"','"+token-xpath("@event-id")+"','"+token-local-variable("OPERATION")+"')"))
+[10/31/21 12:56:08.732]:SendQueueEvent ST: token-xml-parse(""+"INSERT INTO AUDIT(CN,EVENTID,XDS) VALUES ('"+token-attr("CN")+"','"+token-xpath("@event-id")+"','"+token-local-variable("OPERATION")+"')")
+[10/31/21 12:56:08.733]:SendQueueEvent ST: token-xml-parse(""+"INSERT INTO AUDIT(CN,EVENTID,XDS) VALUES ('"+token-attr("CN")+"','"+token-xpath("@event-id")+"','"+token-local-variable("OPERATION")+"')")
+[10/31/21 12:56:08.733]:SendQueueEvent ST: token-text("")
+[10/31/21 12:56:08.734]:SendQueueEvent ST: token-text("INSERT INTO AUDIT(CN,EVENTID,XDS) VALUES ('")
+[10/31/21 12:56:08.734]:SendQueueEvent ST: token-attr("CN")
+[10/31/21 12:56:08.734]:SendQueueEvent ST: Query from policy
+[10/31/21 12:56:08.734]:SendQueueEvent ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+
+
+
+[10/31/21 12:56:08.735]:SendQueueEvent ST: Pumping XDS to eDirectory.
+[10/31/21 12:56:08.735]:SendQueueEvent ST: Performing operation query for \IDVP\data\users\employee2.
+[10/31/21 12:56:08.735]:SendQueueEvent ST: --JCLNT-- \IDVP\system\driverset1\SendQueueEvent : Duplicating : context = 760807589, tempContext = 760807600
+[10/31/21 12:56:08.736]:SendQueueEvent ST: --JCLNT-- \IDVP\system\driverset1\SendQueueEvent : Calling free on tempContext = 760807600
+[10/31/21 12:56:08.736]:SendQueueEvent ST: Query from policy result
+[10/31/21 12:56:08.736]:SendQueueEvent ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+[10/31/21 12:56:08.737]:SendQueueEvent ST: Token Value: "employee2".
+[10/31/21 12:56:08.737]:SendQueueEvent ST: token-text("','")
+[10/31/21 12:56:08.737]:SendQueueEvent ST: token-xpath("@event-id")
+[10/31/21 12:56:08.737]:SendQueueEvent ST: Token Value: "b5fd30f29e6f#20211031125608#1#1:4b7da613-d2d2-4075-b9ab-13a67d4bd2d2".
+[10/31/21 12:56:08.737]:SendQueueEvent ST: token-text("','")
+[10/31/21 12:56:08.737]:SendQueueEvent ST: token-local-variable("OPERATION")
+[10/31/21 12:56:08.738]:SendQueueEvent ST: Token Value: "<modify cached-time="20211031125608.697Z" class-name="User" event-id="b5fd30f29e6f#20211031125608#1#1:4b7da613-d2d2-4075-b9ab-13a67d4bd2d2" qualified-src-dn="O=data\OU=users\CN=employee2" src-dn="\IDVP\data\users\employee2" src-entry-id="33766" timestamp="1635684968#2">
+ <modify-attr attr-name="Given Name">
+ <remove-value>
+ <value timestamp="1635684963#2" type="string">dsque-test</value>
+ </remove-value>
+ <add-value>
+ <value timestamp="1635684968#2" type="string">dsqueue-test</value>
+ </add-value>
+ </modify-attr>
+</modify>".
+[10/31/21 12:56:08.738]:SendQueueEvent ST: token-text("')")
+[10/31/21 12:56:08.739]:SendQueueEvent ST: Arg Value: "INSERT INTO AUDIT(CN,EVENTID,XDS) VALUES ('employee2','b5fd30f29e6f#20211031125608#1#1:4b7da613-d2d2-4075-b9ab-13a67d4bd2d2','<modify cached-time="20211031125608.697Z" class-name="User" event-id="b5fd30f29e6f#20211031125608#1#1:4b7da613-d2d2-4075-b9ab-13a67d4bd2d2" qualified-src-dn="O=data\OU=users\CN=employee2" src-dn="\IDVP\data\users\employee2" src-entry-id="33766" timestamp="1635684968#2">
+ <modify-attr attr-name="Given Name">
+ <remove-value>
+ <value timestamp="1635684963#2" type="string">dsque-test</value>
+ </remove-value>
+ <add-value>
+ <value timestamp="1635684968#2" type="string">dsqueue-test</value>
+ </add-value>
+ </modify-attr>
+</modify>')".
+[10/31/21 12:56:08.740]:SendQueueEvent ST: Token Value: {/}.
+[10/31/21 12:56:08.740]:SendQueueEvent ST: Arg Value: {/}.
+[10/31/21 12:56:08.740]:SendQueueEvent ST: Action: do-set-local-variable("DriverDN",scope="policy",token-parse-dn(dest-dn-format="slash",length="-2",src-dn-format="slash","\IDVP\system\driverset1\SendQueueEvent")+"\JDBC").
+[10/31/21 12:56:08.740]:SendQueueEvent ST: arg-string(token-parse-dn(dest-dn-format="slash",length="-2",src-dn-format="slash","\IDVP\system\driverset1\SendQueueEvent")+"\JDBC")
+[10/31/21 12:56:08.741]:SendQueueEvent ST: token-parse-dn(dest-dn-format="slash",length="-2",src-dn-format="slash","\IDVP\system\driverset1\SendQueueEvent")
+[10/31/21 12:56:08.741]:SendQueueEvent ST: token-parse-dn(dest-dn-format="slash",length="-2",src-dn-format="slash","\IDVP\system\driverset1\SendQueueEvent")
+[10/31/21 12:56:08.741]:SendQueueEvent ST: token-text("\IDVP\system\driverset1\SendQueueEvent")
+[10/31/21 12:56:08.741]:SendQueueEvent ST: Arg Value: "\IDVP\system\driverset1\SendQueueEvent".
+[10/31/21 12:56:08.742]:SendQueueEvent ST: Token Value: "\IDVP\system\driverset1".
+[10/31/21 12:56:08.742]:SendQueueEvent ST: token-text("\JDBC")
+[10/31/21 12:56:08.742]:SendQueueEvent ST: Arg Value: "\IDVP\system\driverset1\JDBC".
+[10/31/21 12:56:08.742]:SendQueueEvent ST: Action: do-if().
+[10/31/21 12:56:08.742]:SendQueueEvent ST: Evaluating conditions.
+[10/31/21 12:56:08.742]:SendQueueEvent ST: (if-global-variable 'drv.action.queueEvent' equal "use-es") = TRUE.
+[10/31/21 12:56:08.742]:SendQueueEvent ST: Performing if actions.
+[10/31/21 12:56:08.742]:SendQueueEvent ST: Action: do-set-local-variable("CmdResult",scope="policy",arg-node-set(token-xpath("es:sendQueueEvent($DriverDN, $XDS/nds)"))).
+[10/31/21 12:56:08.743]:SendQueueEvent ST: arg-node-set(token-xpath("es:sendQueueEvent($DriverDN, $XDS/nds)"))
+[10/31/21 12:56:08.743]:SendQueueEvent ST: token-xpath("es:sendQueueEvent($DriverDN, $XDS/nds)")
+[10/31/21 12:56:08.743]:SendQueueEvent ST: sendQueueEvent: Cleaning up supplied XDS
+[10/31/21 12:56:08.743]:SendQueueEvent ST: sendQueueEvent: Document root node: nds
+[10/31/21 12:56:08.743]:SendQueueEvent ST: sendQueueEvent: Passthru XDS as-is
+[10/31/21 12:56:08.743]:SendQueueEvent ST: sendQueueEvent: Validating document
+[10/31/21 12:56:08.744]:SendQueueEvent ST: sendQueueEvent: Detected known command: statement
+[10/31/21 12:56:08.744]:SendQueueEvent ST: sendQueueEvent: Serializing document to ByteArray with encoding: UTF-8
+[10/31/21 12:56:08.744]:SendQueueEvent ST: sendQueueEvent: Detected tree name: IDVP
+[10/31/21 12:56:08.744]:SendQueueEvent ST: sendQueueEvent: Attempting to authenticate to tree
+[10/31/21 12:56:08.744]:SendQueueEvent ST: sendQueueEvent: Resolving source driver:\IDVP\system\driverset1\SendQueueEvent
+[10/31/21 12:56:08.745]:SendQueueEvent ST: sendQueueEvent: Verifying target driver exists: \IDVP\system\driverset1\JDBC
+[10/31/21 12:56:08.745]:SendQueueEvent ST: sendQueueEvent: Verifying rights to source driver: \IDVP\system\driverset1\SendQueueEvent
+[10/31/21 12:56:08.745]:SendQueueEvent ST: sendQueueEvent: Queuing supplied XDS
+[10/31/21 12:56:08.749]:SendQueueEvent ST: Token Value: { @dtdversion = "4.0" @ndsversion = "8.x"}.
+[10/31/21 12:56:08.749]:SendQueueEvent ST: Arg Value: { @dtdversion = "4.0" @ndsversion = "8.x"}.
+[10/31/21 12:56:08.749]:SendQueueEvent ST: Action: do-if().
+[10/31/21 12:56:08.749]:SendQueueEvent ST: Evaluating conditions.
+[10/31/21 12:56:08.750]:SendQueueEvent ST: (if-global-variable 'drv.action.queueEvent' equal "use-jar") = FALSE.
+[10/31/21 12:56:08.750]:SendQueueEvent ST: Action: do-trace-message(token-xml-serialize(token-xpath("$CmdResult//status"))).
+[10/31/21 12:56:08.750]:SendQueueEvent ST: arg-string(token-xml-serialize(token-xpath("$CmdResult//status")))
+[10/31/21 12:56:08.750]:SendQueueEvent ST: token-xml-serialize(token-xpath("$CmdResult//status"))
+[10/31/21 12:56:08.750]:SendQueueEvent ST: token-xml-serialize(token-xpath("$CmdResult//status"))
+[10/31/21 12:56:08.750]:SendQueueEvent ST: token-xpath("$CmdResult//status")
+[10/31/21 12:56:08.751]:SendQueueEvent ST: Token Value: { @level = "success"}.
+[10/31/21 12:56:08.751]:SendQueueEvent ST: Arg Value: { @level = "success"}.
+[10/31/21 12:56:08.751]:SendQueueEvent ST: Token Value: "Submitted document for execution on subscriber channel on driver: \IDVP\system\driverset1\JDBC".
+[10/31/21 12:56:08.752]:SendQueueEvent ST: Arg Value: "Submitted document for execution on subscriber channel on driver: \IDVP\system\driverset1\JDBC".
+[10/31/21 12:56:08.752]:SendQueueEvent ST:Submitted document for execution on subscriber channel on driver: \IDVP\system\driverset1\JDBC
+[10/31/21 12:56:08.752]:SendQueueEvent ST:Policy returned:
+[10/31/21 12:56:08.752]:SendQueueEvent ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+
+ dsque-test
+
+
+ dsqueue-test
+
+
+
+
+
+[10/31/21 12:56:08.753]:SendQueueEvent ST:Subscriber processing modify for \IDVP\data\users\employee2.
+[10/31/21 12:56:08.754]:SendQueueEvent ST:Converting to
+[10/31/21 12:56:08.754]:SendQueueEvent ST:Reading relevant attributes from \IDVP\data\users\employee2.
+[10/31/21 12:56:08.754]:SendQueueEvent ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+
+
+
+
+
+[10/31/21 12:56:08.755]:SendQueueEvent ST:Pumping XDS to eDirectory.
+[10/31/21 12:56:08.755]:SendQueueEvent ST:Performing operation query for \IDVP\data\users\employee2.
+[10/31/21 12:56:08.755]:SendQueueEvent ST:--JCLNT-- \IDVP\system\driverset1\SendQueueEvent : Duplicating : context = 760807589, tempContext = 760807600
+[10/31/21 12:56:08.756]:SendQueueEvent ST:--JCLNT-- \IDVP\system\driverset1\SendQueueEvent : Calling free on tempContext = 760807600
+[10/31/21 12:56:08.756]:SendQueueEvent ST:Read result:
+[10/31/21 12:56:08.756]:SendQueueEvent ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+[10/31/21 12:56:08.757]:SendQueueEvent ST:Synthetic add:
+[10/31/21 12:56:08.757]:SendQueueEvent ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+ employee2
+
+
+ dsqueue-test
+
+
+ Employee
+
+
+
+
+[10/31/21 12:56:08.758]:SendQueueEvent ST:No object matching policies.
+[10/31/21 12:56:08.758]:SendQueueEvent ST:No object creation policies.
+[10/31/21 12:56:08.758]:SendQueueEvent ST:No object placement policies.
+[10/31/21 12:56:08.759]:SendQueueEvent ST:Submitting add to subscriber shim.
+[10/31/21 12:56:08.759]:SendQueueEvent ST:No command transformation policies.
+[10/31/21 12:56:08.759]:SendQueueEvent ST:Filtering out notification-only attributes.
+[10/31/21 12:56:08.759]:SendQueueEvent ST:Fixing up association references.
+[10/31/21 12:56:08.759]:SendQueueEvent ST:No schema mapping policies.
+[10/31/21 12:56:08.759]:SendQueueEvent ST:No output transformation policies.
+[10/31/21 12:56:08.759]:SendQueueEvent ST:Submitting document to subscriber shim:
+[10/31/21 12:56:08.759]:SendQueueEvent ST:
+
+
+ DirXML
+ NetIQ Corporation
+
+
+
+
+ employee2
+
+
+ dsqueue-test
+
+
+ Employee
+
+
+
+
+[10/31/21 12:56:08.761]:SendQueueEvent ST:SubscriptionShim.execute() returned:
+[10/31/21 12:56:08.761]:SendQueueEvent ST:
+
+
+ DirXML Null Driver
+ NetIQ Corporation
+
+
+
+[10/31/21 12:56:08.761]:SendQueueEvent ST:No input transformation policies.
+[10/31/21 12:56:08.761]:SendQueueEvent ST:No schema mapping policies.
+[10/31/21 12:56:08.761]:SendQueueEvent ST:Resolving association references.
+[10/31/21 12:56:08.762]:SendQueueEvent ST:Processing returned document.
+[10/31/21 12:56:08.762]:SendQueueEvent ST:Processing operation for .
+[10/31/21 12:56:08.762]:SendQueueEvent ST:
+DirXML Log Event -------------------
+ Driver: \IDVP\system\driverset1\SendQueueEvent
+ Channel: Subscriber
+ Object: \IDVP\data\users\employee2
+ Status: Success
+[10/31/21 12:56:08.762]:SendQueueEvent ST:End transaction.
diff --git a/demo/SendQueueEvent.xml b/demo/SendQueueEvent.xml
index 0986b13..3af07b0 100755
--- a/demo/SendQueueEvent.xml
+++ b/demo/SendQueueEvent.xml
@@ -1,4 +1,4 @@
-
+
@@ -21,7 +21,8 @@
-
+
+
@@ -43,7 +44,15 @@
-
+
+
+
+ use-es
+ none
+ use-jar
+ use-es
+
+
@@ -63,7 +72,9 @@
This policy will capture the incoming event, and generate a XDS Message to put onto the other driver. This example will create a JDBC Message and log it to the database using the other driver.
There are a few tricks, one is to serialize the incoming XDS, and do a Search and Replace of all the < and > into > and <. Plus the DriverDN must include the full TreeName. Lastly the sendQueueEvent will return a Nodeset so you must set the variable type to be a nodeset
-
+
+
+
@@ -93,14 +104,47 @@ There are a few tricks, one is to serialize the incoming XDS, and do a Search an
- \EDIR\ADMIN\IDM\DriverSet\JDBC
+
+ ~dirxml.auto.driverdn~
+
+ \JDBC
-
-
-
-
-
+
+
+
+ use-es
+
+
+
+
+
+
+
+
+
+
+
+
+
+ use-jar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/dxqueue-es/sendMigrateApp.js b/src/dxqueue-es/sendMigrateApp.js
index 974fdd9..b27e163 100644
--- a/src/dxqueue-es/sendMigrateApp.js
+++ b/src/dxqueue-es/sendMigrateApp.js
@@ -2,11 +2,11 @@ importClass(Packages.com.novell.nds.dhutil.JCHelper);
importClass(Packages.com.novell.nds.dirxml.driver.Trace);
importClass(Packages.com.novell.nds.dirxml.engine.MiscDS);
importClass(Packages.com.novell.nds.dirxml.engine.ThreadGroupVars);
-importClass(Packages.com.novell.nds.dirxml.util.DxWire);
importClass(Packages.com.novell.nds.dirxml.engine.NdsDtd);
importClass(Packages.com.novell.nds.dirxml.engine.XdsUtil);
-
+importClass(Packages.com.novell.nds.dirxml.engine.DirXML);
importClass(Packages.com.novell.nds.dirxml.engine.OperationData);
+importClass(Packages.com.novell.nds.dirxml.util.DxWire);
importClass(Packages.com.novell.xml.dom.DOMQuery);
importClass(Packages.com.novell.xml.dom.DOMWriter);
importClass(Packages.novell.jclient.JCContext);
@@ -14,37 +14,34 @@ importClass(Packages.novell.jclient.JCException);
importClass(Packages.novell.jclient.JClient);
importClass(java.io.StringWriter);
-var debugPrefix = 'sendQueueEvent: ';
+var debugPrefix = 'sendMigrateApp';
+var debugDefault = 3;
function serializeEx(doc, indent) {
//
//requires: java.io.StringWriter
//requires: com.novell.xml.dom.DOMWriter
indent = "undefined" !== typeof indent ? !!indent : !0;
- var sw = new StringWriter;
+ var sw = new StringWriter();
dw = new DOMWriter(doc, sw);
dw.setIndent(!!indent);
dw.write();
return sw.toString();
}
-
function debugMessage(message, level) {
//
//requires: com.novell.nds.dirxml.driver.Trace
//requires: com.novell.nds.dirxml.engine.DirXML
//requires: javax.swing.JOptionPane
-
- //default trace level of 1
- level = 'undefined' !== typeof level ? level : 1;
-
if (message) {
msgString = message.toString()
- if (Packages.com.novell.nds.dirxml.engine.DirXML.isExternal()) {
- Packages.javax.swing.JOptionPane.showMessageDialog(null, debugPrefix + ' ' + msgString);
+ if (DirXML.isExternal()) {
+ Packages.javax.swing.JOptionPane.showMessageDialog(null, debugPrefix + ': ' + msgString);
} else {
- (new Packages.com.novell.nds.dirxml.driver.Trace(debugPrefix))
- .trace(msgString, level);
+ //default trace level of 3
+ level = 'undefined' !== typeof level ? level : debugDefault;
+ (new Trace(debugPrefix)).trace(msgString, level);
}
}
}
@@ -56,14 +53,15 @@ function skeletonXDS(contextNode) {
//requires: com.novell.nds.dirxml.engine.NdsDtd;
// function debugMessage
contextNode = 'undefined' !== typeof contextNode ? contextNode : 'input';
- debugMessage('Creating skeleton using context: ' + contextNode);
+ debugMessage('Creating skeleton using context: ' + contextNode, debugDefault + 1);
return NdsDtd.createDoc(contextNode)
}
+
function properXDS(doc) {
// accepts:
// either an XDS fragment or an entire XDS doc
// it wraps the former in an XDS doc as necessary
-
+ //
// returns:
// XDS document: Document doc
//
@@ -74,38 +72,38 @@ function properXDS(doc) {
//requires: com.novell.nds.dirxml.engine.XdsUtil;
// generate empty empty XDS document.
-
- var docRet = skeletonXDS();
+ var docRet = skeletonXDS('input');
// will return empty XDS document when input is empty
if (null != doc.first()) {
-
- var rootDocNode = ((null == doc.first()
- .getOwnerDocument()) ? doc.first() : doc.first()
- .getOwnerDocument())
+ var rootDocNode = (
+ (null == doc.first().getOwnerDocument())
+ ? doc.first()
+ : doc.first().getOwnerDocument())
.getDocumentElement()
var rootNodeName = rootDocNode.getNodeName()
+ debugMessage('Document root node: ' + rootNodeName);
// Returning unchanged if no re-wrapping is required.
if (null != rootDocNode && rootNodeName.equals('nds')) {
- debugMessage('Returning supplied XDS unchanged, already proper XDS')
+ debugMessage('Returning supplied XDS unchanged, already proper XDS', debugDefault + 1)
return doc;
}
+ // known valid commands from XDS DTD
if (null != rootDocNode && rootNodeName.matches('add|modify|modify-password|query|query-ex|rename|move|delete|trigger|sync')) {
// Merging supplied XDS with wrapper
- debugMessage('Merging supplied XDS with wrapper: ' + rootNodeName)
+ debugMessage('Merging supplied XDS with wrapper: ' + rootNodeName, debugDefault + 1)
Packages.com.novell.nds.dirxml.engine.XdsUtil.graftSubtree(docRet, rootDocNode);
} else {
debugMessage('Invalid document: ' + rootNodeName + 'is not supported.')
return docRet
}
-
}
return docRet.getOwnerDocument().getDocumentElement();
}
function sendMigrateApp(driverDN, myElement) {
- // this function takes either a command (query/query-ex) or an entire XDS doc
+ // this function takes either a query/query-ex command or an entire XDS doc
// if necessary, it wraps the command in an XDS doc.
// returns status document: Document doc
// requires: com.novell.nds.dhutil.JCHelper
@@ -125,98 +123,110 @@ function sendMigrateApp(driverDN, myElement) {
// function debugMessage
// function properXDS
// skeletonXDS
+
+ var supportedOps = 'query|query-ex';
+ // strict processing: can only inject query|query-ex.
+ // as long as the doc is otherwise well formed, it should not crash the engine.
+ var processUnsupportedOps = false
+ var myEncoding = java.nio.charset.StandardCharsets.UTF_8;
+
if (!(Packages.com.novell.nds.dirxml.engine.DirXML.isExternal())) {
try {
debugMessage('Cleaning up supplied XDS');
-
var theElement = properXDS(myElement);
(theElement === myElement) ? debugMessage('Passthru XDS as-is') : debugMessage('Cleaned up XDS')
- //debugMessage('Detected theElement: ' + theElement)
- var myEncoding = java.nio.charset.StandardCharsets.UTF_8;
+ //debugMessage('Detected theElement: ' + theElement, debugDefault + 1)
debugMessage('Validating document')
try {
if (null == rootDoc) {
var rootDoc = theElement.first().getFirstChild().getOwnerDocument()
}
- } catch (e) {debugMessage('First node not found, falling back to first alternate mechanism')}
+ } catch (e) { debugMessage('First node not found, falling back to first alternate mechanism', debugDefault + 1) }
try {
if (null == rootDoc) {
var rootDoc = theElement.getFirstChild().getOwnerDocument()
}
- } catch (e) { debugMessage('First node not found, falling back to second alternate mechanism' + e) }
+ } catch (e) { debugMessage('First node not found, falling back to second alternate mechanism' + e, debugDefault + 1) }
try {
if (null == rootDoc) {
var rootDoc = theElement.first().getOwnerDocument()
}
- } catch (e) { debugMessage('error' + e)}
+ } catch (e) { debugMessage('error' + e) }
if (null == rootDoc) {
- debugMessage('Trying built-in getOwnerDocument() method as last resort');
- var rootDoc = theElement.getOwnerDocument()
+ debugMessage('Trying built-in getOwnerDocument() method as last resort', debugDefault + 1);
+ var rootDoc = theElement.getOwnerDocument()
}
- try { rootNodeName = rootDoc.getNodeName(); } catch (e) { debugMessage('error' + e) }
+
try {
if (null == myOps) {
var myOps = Packages.com.novell.xml.dom.DOMQuery.query(rootDoc, "//input/*");
}
- } catch (e) { debugMessage(e) }
+ } catch (e) {
+ debugMessage(e)
+ }
if (null == myOps.first()) {
- return NdsDtd.createStatusDocument((new java.lang.Integer(2)), null, 'Nothing to submit!')
+ return NdsDtd.createStatusDocument(NdsDtd.SL_WARNING, null, 'Nothing to submit!')
.getDocumentElement()
}
- if (myOps.first().getLocalName().matches('query|query-ex')){
- debugMessage('Detected command: ' + myOps.first().getLocalName())
+
+ if (myOps.first().getLocalName().matches(supportedOps)) {
+ debugMessage('Detected known command: ' + myOps.first().getLocalName())
}
- else {
- return NdsDtd.createStatusDocument((new java.lang.Integer(2)), null, ('command:' + myOps.first().getLocalName() + 'Not valid for this function'))
- .getDocumentElement()
+ else if (processUnsupportedOps) {
+ debugMessage('Detected unknown command: ' + myOps.first().getLocalName() + '. Submitting anyway, it may be ignored by the shim ')
}
+ else {
+ return NdsDtd.createStatusDocument(NdsDtd.SL_ERROR, null, ('command: ' + myOps.first().getLocalName() + 'Not valid for this function'))
+ .getDocumentElement()
+ }
debugMessage('Serializing document to ByteArray with encoding: ' + myEncoding)
var serializedDoc = serializeEx(rootDoc, false)
bytes = serializedDoc.getBytes(myEncoding);
if (null == bytes) {
- return NdsDtd.createStatusDocument((new java.lang.Integer(3)), null, 'XDS could not be converted to ByteArray!')
+ return NdsDtd.createStatusDocument(NdsDtd.SL_ERROR, null, 'XDS could not be converted to ByteArray!')
.getDocumentElement()
- }
- var opdata = new OperationData(null);
+ } else {
+
treeName = MiscDS.getTreeName();
debugMessage('Detected tree name: ' + treeName);
- var context = new Packages.novell.jclient.JCContext(0, treeName, "00.\\+=*'");
+ var context = new JCContext(0, treeName, "00.\\+=*'");
JCHelper.loginAsServer(context);
debugMessage('Attempting to authenticate to tree');
context.authenticate();
var currentDriverDN = ThreadGroupVars.get("vrDriverDN");
- debugMessage('Verifying access to: ' + currentDriverDN);
+ debugMessage('Resolving source driver:' + currentDriverDN);
if (null == currentDriverDN) {
throw new JCException("getEffectivePriviledges()", -672);
}
if (!(driverDN.startsWith("\\"))) {
- debugMessage('Converting ' + driverDN + ' to absolute path...');
+ debugMessage('Converting ' + driverDN + ' to absolute path...', debugDefault + 1);
driverDN = '\\' + treeName + '\\' + driverDN;
}
- debugMessage('Verifying access to: ' + currentDriverDN);
+ debugMessage('Verifying target driver exists: ' + driverDN);
context.nameToID(1, driverDN);
+ debugMessage('Verifying rights to source driver: ' + currentDriverDN);
if ((context.getEffectivePrivileges(currentDriverDN, "[Entry Rights]") & 0x10) == (new java.lang.Long(0))) {
throw new JCException("getEffectivePriviledges()", -672);
}
- debugMessage('MigrateApp with supplied XDS');
- var wireCtor = new Packages.com.novell.nds.dirxml.util.DxWire();
+ debugMessage('Queuing supplied XDS');
+ var wireCtor = new DxWire();
wireCtor.setDnFormat(0);
result = sendWireRequest(context, wireCtor.constructMigrateApp(driverDN, bytes));
- output = NdsDtd.createStatusDocument((new java.lang.Integer(0)), null, 'Submitted migrate app query to subscriber channel on driver: ' + currentDriverDN)
+ output = NdsDtd.createStatusDocument(NdsDtd.SL_SUCCESS, null, 'Submitted document for execution on subscriber channel on driver: ' + driverDN)
.getDocumentElement()
+ }
} catch (t) {
- return NdsDtd.createStatusDocument((new java.lang.Integer(0)), opdata, 'Error: ' + t)
- .getDocumentElement()
+ return NdsDtd.createStatusDocument(NdsDtd.SL_ERROR, null, 'Error: ' + t).getDocumentElement();
} finally {
if (context != null) {
context.free();
@@ -224,6 +234,7 @@ function sendMigrateApp(driverDN, myElement) {
}
}
return output;
+}
function sendWireRequest(context, wireData) {
replyBuffer = new java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, wireData.getResponseSize())
@@ -238,5 +249,4 @@ function sendMigrateApp(driverDN, myElement) {
replyBuffer = temp;
}
return replyBuffer;
- }
-}
\ No newline at end of file
+}
diff --git a/src/dxqueue-es/sendQueueEvent.js b/src/dxqueue-es/sendQueueEvent.js
index f41581f..1b568bd 100644
--- a/src/dxqueue-es/sendQueueEvent.js
+++ b/src/dxqueue-es/sendQueueEvent.js
@@ -22,7 +22,7 @@ function serializeEx(doc, indent) {
//requires: java.io.StringWriter
//requires: com.novell.xml.dom.DOMWriter
indent = "undefined" !== typeof indent ? !!indent : !0;
- var sw = new StringWriter;
+ var sw = new StringWriter();
dw = new DOMWriter(doc, sw);
dw.setIndent(!!indent);
dw.write();
@@ -89,6 +89,7 @@ function properXDS(doc) {
debugMessage('Returning supplied XDS unchanged, already proper XDS', debugDefault + 1)
return doc;
}
+ // known valid commands from XDS DTD
if (null != rootDocNode && rootNodeName.matches('add|modify|modify-password|query|query-ex|rename|move|delete|trigger|sync')) {
// Merging supplied XDS with wrapper
debugMessage('Merging supplied XDS with wrapper: ' + rootNodeName, debugDefault + 1)
@@ -122,38 +123,42 @@ function sendQueueEvent(driverDN, myElement) {
// function debugMessage
// function properXDS
// skeletonXDS
+
+ var supportedOps = 'add|modify|modify-password|rename|move|delete|trigger|sync|statement';
+ // relaxed processing: unsupported commands normally are ignored, but may mean something to specififc shims.
+ // as long as the doc is otherwise well formed, it should not crash the engine.
+ var processUnsupportedOps = true
+ var myEncoding = java.nio.charset.StandardCharsets.UTF_8;
+
if (!(Packages.com.novell.nds.dirxml.engine.DirXML.isExternal())) {
- try {
+ try {
debugMessage('Cleaning up supplied XDS');
var theElement = properXDS(myElement);
(theElement === myElement) ? debugMessage('Passthru XDS as-is') : debugMessage('Cleaned up XDS')
//debugMessage('Detected theElement: ' + theElement, debugDefault + 1)
- var myEncoding = java.nio.charset.StandardCharsets.UTF_8;
debugMessage('Validating document')
try {
if (null == rootDoc) {
var rootDoc = theElement.first().getFirstChild().getOwnerDocument()
}
- } catch (e) { debugMessage('First node not found, falling back to first alternate mechanism') }
+ } catch (e) { debugMessage('First node not found, falling back to first alternate mechanism', debugDefault + 1) }
try {
if (null == rootDoc) {
var rootDoc = theElement.getFirstChild().getOwnerDocument()
}
- } catch (e) { debugMessage('First node not found, falling back to second alternate mechanism' + e) }
+ } catch (e) { debugMessage('First node not found, falling back to second alternate mechanism' + e, debugDefault + 1) }
try {
if (null == rootDoc) {
var rootDoc = theElement.first().getOwnerDocument()
}
} catch (e) { debugMessage('error' + e) }
if (null == rootDoc) {
- debugMessage('Trying built-in getOwnerDocument() method as last resort');
+ debugMessage('Trying built-in getOwnerDocument() method as last resort', debugDefault + 1);
var rootDoc = theElement.getOwnerDocument()
}
- /* does not work for me, always getting "Nothing to submit!"
-
try {
if (null == myOps) {
var myOps = Packages.com.novell.xml.dom.DOMQuery.query(rootDoc, "//input/*");
@@ -163,19 +168,22 @@ function sendQueueEvent(driverDN, myElement) {
}
if (null == myOps.first()) {
- return NdsDtd.createStatusDocument((new java.lang.Integer(2)), null, 'Nothing to submit!')
+ return NdsDtd.createStatusDocument(NdsDtd.SL_WARNING, null, 'Nothing to submit!')
.getDocumentElement()
}
- if (myOps.first().getLocalName().matches('add|modify|modify-password|rename|move|delete|trigger|sync')) {
- debugMessage('Detected command: ' + myOps.first().getLocalName())
+ if (myOps.first().getLocalName().matches(supportedOps)) {
+ debugMessage('Detected known command: ' + myOps.first().getLocalName())
}
- else {
- return NdsDtd.createStatusDocument(NdsDtd.SL_ERROR, null, 'command:' + myOps.first().getLocalName() + ' is not valid for this function')
- .getDocumentElement()
+ else if (processUnsupportedOps) {
+ debugMessage('Detected unknown command: ' + myOps.first().getLocalName() + '. Submitting anyway, it may be ignored by the shim ')
+ }
+
+ else {
+ return NdsDtd.createStatusDocument(NdsDtd.SL_ERROR, null, ('command: ' + myOps.first().getLocalName() + 'Not valid for this function'))
+ .getDocumentElement()
}
- */
debugMessage('Serializing document to ByteArray with encoding: ' + myEncoding)
var serializedDoc = serializeEx(rootDoc, false)
@@ -193,7 +201,7 @@ function sendQueueEvent(driverDN, myElement) {
debugMessage('Attempting to authenticate to tree');
context.authenticate();
var currentDriverDN = ThreadGroupVars.get("vrDriverDN");
- debugMessage('Verifying access to: ' + currentDriverDN);
+ debugMessage('Resolving source driver:' + currentDriverDN);
if (null == currentDriverDN) {
throw new JCException("getEffectivePriviledges()", -672);
}
@@ -202,8 +210,9 @@ function sendQueueEvent(driverDN, myElement) {
driverDN = '\\' + treeName + '\\' + driverDN;
}
- debugMessage('Verifying access to: ' + driverDN);
+ debugMessage('Verifying target driver exists: ' + driverDN);
context.nameToID(1, driverDN);
+ debugMessage('Verifying rights to source driver: ' + currentDriverDN);
if ((context.getEffectivePrivileges(currentDriverDN, "[Entry Rights]") & 0x10) == (new java.lang.Long(0))) {
throw new JCException("getEffectivePriviledges()", -672);
}
@@ -212,7 +221,7 @@ function sendQueueEvent(driverDN, myElement) {
var wireCtor = new DxWire();
wireCtor.setDnFormat(0);
result = sendWireRequest(context, wireCtor.constructQueueEvent(driverDN, bytes));
- output = NdsDtd.createStatusDocument(NdsDtd.SL_SUCCESS, null, 'Submitted document for execution on subscriber channel on driver: ' + currentDriverDN)
+ output = NdsDtd.createStatusDocument(NdsDtd.SL_SUCCESS, null, 'Submitted document for execution on subscriber channel on driver: ' + driverDN)
.getDocumentElement()
}
@@ -240,4 +249,4 @@ function sendWireRequest(context, wireData) {
replyBuffer = temp;
}
return replyBuffer;
-}
\ No newline at end of file
+}
diff --git a/src/dxqueue/send.java b/src/dxqueue/send.java
index d30f2fe..54e5f4a 100644
--- a/src/dxqueue/send.java
+++ b/src/dxqueue/send.java
@@ -1,117 +1,189 @@
-package dxqueue;
-
-import com.novell.nds.dhutil.JCHelper;
-import com.novell.nds.dirxml.driver.Trace;
-import com.novell.nds.dirxml.engine.MiscDS;
-import com.novell.nds.dirxml.engine.NdsDtd;
-import com.novell.nds.dirxml.engine.OperationData;
-import com.novell.nds.dirxml.engine.ThreadGroupVars;
-import com.novell.nds.dirxml.engine.XdsUtil;
-import com.novell.nds.dirxml.util.DxWire;
-import com.novell.xml.dom.DOMWriter;
-import java.io.ByteArrayOutputStream;
-import novell.jclient.JCContext;
-import novell.jclient.JCException;
-import novell.jclient.JClient;
-import org.w3c.dom.Element;
-
-public abstract class send {
-
- // An updated version of https://community.microfocus.com/t5/Identity-Manager-Tips/Sending-a-XDS-Message-from-one-driver-to-another/ta-p/1777175
-
- public static final String VERSION = "1.1.0";
-
- public static Element sendQueueEvent(String driverDN, Element element) {
-
- ByteArrayOutputStream baos;
- JCContext context = null;
- OperationData opdata = new OperationData(null);
- Trace tracer = new Trace("dxqueue");
-
- try {
-
- String treeName = MiscDS.getTreeName();
- context = new JCContext(0, treeName, "00.\\+=*'");
-
- tracer.trace("Authenticating...", 4);
- JCHelper.loginAsServer(context);
- context.authenticate();
-
- String currentDriverDN = (String) ThreadGroupVars.get("vrDriverDN");
- tracer.trace("Verifying access to " + currentDriverDN + "...", 4);
- if (currentDriverDN == null) {
- throw new JCException("getEffectivePriviledges()", -672);
- }
-
- if (!(driverDN.startsWith("\\"))) {
- tracer.trace("Converting " + driverDN + " to absolute path...", 4);
- driverDN = "\\" + treeName + "\\" + driverDN;
- }
-
- tracer.trace("Verifying access to " + driverDN + "...", 4);
- context.nameToID(1, driverDN);
- if ((context.getEffectivePrivileges(currentDriverDN, "[Entry Rights]") & 0x10) == 0L) {
- throw new JCException("getEffectivePriviledges()", -672);
- }
-
- String rootNodeName = element.getNodeName();
- if (!(rootNodeName.equals("nds"))) {
- if (rootNodeName.matches("add|modify|rename|move|delete|trigger|sync")) {
- tracer.trace("Wrapping XDS document around " + rootNodeName + " node...", 4);
- Element rootElement = NdsDtd.createDoc("input");
- XdsUtil.graftSubtree(rootElement, element);
- element = rootElement.getOwnerDocument().getDocumentElement();
- } else {
- return NdsDtd.createStatusDocument(NdsDtd.SL_ERROR, opdata, "Invalid document: " + rootNodeName + " is not supported.").getDocumentElement();
- }
- }
-
- tracer.trace("Converting document to byte array...", 4);
- baos = new ByteArrayOutputStream();
- DOMWriter domWriter = new DOMWriter(element, baos, "UTF-8");
- domWriter.setEncoding("UTF-8");
- domWriter.write();
- byte[] bytes = baos.toByteArray();
-
- tracer.trace("Submitting document...", 4);
- DxWire wireCtor = getDxWire();
- @SuppressWarnings("unused")
- byte[] result = sendWireRequest(context, wireCtor.constructQueueEvent(driverDN, bytes));
-
- return NdsDtd.createStatusDocument(NdsDtd.SL_SUCCESS, opdata, "Submitted document to " + driverDN).getDocumentElement();
-
- } catch (Throwable t) {
-
- return NdsDtd.createStatusDocument(t, opdata).getDocumentElement();
-
- } finally {
-
- if (context != null) {
- context.free();
- }
- }
- }
-
- private static DxWire getDxWire() {
-
- DxWire wireCtor = new DxWire();
- wireCtor.setDnFormat(0);
- return wireCtor;
- }
-
- private static byte[] sendWireRequest(JCContext context, DxWire.DxWireData wireData) throws JCException {
-
- byte[] replyBuffer = new byte[wireData.getResponseSize()];
- int replySize = JClient.ndsRequest(context, wireData.getVerb(), wireData.getRequestData().length, wireData.getRequestData(),
- replyBuffer.length, replyBuffer);
-
- if (replySize == 0) {
- return null;
- } else if (replySize != replyBuffer.length) {
- byte[] temp = new byte[replySize];
- System.arraycopy(replyBuffer, 0, temp, 0, replySize);
- replyBuffer = temp;
- }
- return replyBuffer;
- }
+package dxqueue;
+
+import com.novell.nds.dhutil.JCHelper;
+import com.novell.nds.dirxml.driver.Trace;
+import com.novell.nds.dirxml.engine.MiscDS;
+import com.novell.nds.dirxml.engine.NdsDtd;
+import com.novell.nds.dirxml.engine.OperationData;
+import com.novell.nds.dirxml.engine.ThreadGroupVars;
+import com.novell.nds.dirxml.engine.XdsUtil;
+import com.novell.nds.dirxml.util.DxWire;
+import com.novell.xml.dom.DOMWriter;
+import java.io.ByteArrayOutputStream;
+import novell.jclient.JCContext;
+import novell.jclient.JCException;
+import novell.jclient.JClient;
+import org.w3c.dom.Element;
+
+public abstract class send {
+
+ // An updated version of https://community.microfocus.com/t5/Identity-Manager-Tips/Sending-a-XDS-Message-from-one-driver-to-another/ta-p/1777175
+
+ public static final String VERSION = "1.1.1";
+
+ public static Element sendQueueEvent(String driverDN, Element element) {
+
+ ByteArrayOutputStream baos;
+ JCContext context = null;
+ OperationData opdata = new OperationData(null);
+ Trace tracer = new Trace("dxqueue");
+
+ try {
+
+ String treeName = MiscDS.getTreeName();
+ context = new JCContext(0, treeName, "00.\\+=*'");
+
+ tracer.trace("Authenticating...", 4);
+ JCHelper.loginAsServer(context);
+ context.authenticate();
+
+ String currentDriverDN = (String) ThreadGroupVars.get("vrDriverDN");
+ tracer.trace("Verifying access to " + currentDriverDN + "...", 4);
+ if (currentDriverDN == null) {
+ throw new JCException("getEffectivePriviledges()", -672);
+ }
+
+ if (!(driverDN.startsWith("\\"))) {
+ tracer.trace("Converting " + driverDN + " to absolute path...", 4);
+ driverDN = "\\" + treeName + "\\" + driverDN;
+ }
+
+ tracer.trace("Verifying access to " + driverDN + "...", 4);
+ context.nameToID(1, driverDN);
+ if ((context.getEffectivePrivileges(currentDriverDN, "[Entry Rights]") & 0x10) == 0L) {
+ throw new JCException("getEffectivePriviledges()", -672);
+ }
+
+ String rootNodeName = element.getNodeName();
+ if (!(rootNodeName.equals("nds"))) {
+ if (rootNodeName.matches("add|modify|rename|move|delete|trigger|sync")) {
+ tracer.trace("Wrapping XDS document around " + rootNodeName + " node...", 4);
+ Element rootElement = NdsDtd.createDoc("input");
+ XdsUtil.graftSubtree(rootElement, element);
+ element = rootElement.getOwnerDocument().getDocumentElement();
+ } else {
+ return NdsDtd.createStatusDocument(NdsDtd.SL_ERROR, opdata, "Invalid document: " + rootNodeName + " is not supported.").getDocumentElement();
+ }
+ }
+
+ tracer.trace("Converting document to byte array...", 4);
+ baos = new ByteArrayOutputStream();
+ DOMWriter domWriter = new DOMWriter(element, baos, "UTF-8");
+ domWriter.setEncoding("UTF-8");
+ domWriter.write();
+ byte[] bytes = baos.toByteArray();
+
+ tracer.trace("Submitting document...", 4);
+ DxWire wireCtor = getDxWire();
+ @SuppressWarnings("unused")
+ byte[] result = sendWireRequest(context, wireCtor.constructQueueEvent(driverDN, bytes));
+
+ return NdsDtd.createStatusDocument(NdsDtd.SL_SUCCESS, opdata, "Submitted document to " + driverDN).getDocumentElement();
+
+ } catch (Throwable t) {
+
+ return NdsDtd.createStatusDocument(t, opdata).getDocumentElement();
+
+ } finally {
+
+ if (context != null) {
+ context.free();
+ }
+ }
+ }
+
+ public static Element sendMigrateApp(String driverDN, Element element) {
+
+ ByteArrayOutputStream baos;
+ JCContext context = null;
+ OperationData opdata = new OperationData(null);
+ Trace tracer = new Trace("dxqueue");
+
+ try {
+
+ String treeName = MiscDS.getTreeName();
+ context = new JCContext(0, treeName, "00.\\+=*'");
+
+ tracer.trace("Authenticating...", 4);
+ JCHelper.loginAsServer(context);
+ context.authenticate();
+
+ String currentDriverDN = (String) ThreadGroupVars.get("vrDriverDN");
+ tracer.trace("Verifying access to " + currentDriverDN + "...", 4);
+ if (currentDriverDN == null) {
+ throw new JCException("getEffectivePriviledges()", -672);
+ }
+
+ if (!(driverDN.startsWith("\\"))) {
+ tracer.trace("Converting " + driverDN + " to absolute path...", 4);
+ driverDN = "\\" + treeName + "\\" + driverDN;
+ }
+
+ tracer.trace("Verifying access to " + driverDN + "...", 4);
+ context.nameToID(1, driverDN);
+ if ((context.getEffectivePrivileges(currentDriverDN, "[Entry Rights]") & 0x10) == 0L) {
+ throw new JCException("getEffectivePriviledges()", -672);
+ }
+
+ String rootNodeName = element.getNodeName();
+ if (!(rootNodeName.equals("nds"))) {
+ if (rootNodeName.matches("query|query-ex")) {
+ tracer.trace("Wrapping XDS document around " + rootNodeName + " node...", 4);
+ Element rootElement = NdsDtd.createDoc("input");
+ XdsUtil.graftSubtree(rootElement, element);
+ element = rootElement.getOwnerDocument().getDocumentElement();
+ } else {
+ return NdsDtd.createStatusDocument(NdsDtd.SL_ERROR, opdata, "Invalid document: " + rootNodeName + " is not supported.").getDocumentElement();
+ }
+ }
+
+ tracer.trace("Converting document to byte array...", 4);
+ baos = new ByteArrayOutputStream();
+ DOMWriter domWriter = new DOMWriter(element, baos, "UTF-8");
+ domWriter.setEncoding("UTF-8");
+ domWriter.write();
+ byte[] bytes = baos.toByteArray();
+
+ tracer.trace("Submitting document...", 4);
+ DxWire wireCtor = getDxWire();
+ @SuppressWarnings("unused")
+ byte[] result = sendWireRequest(context, wireCtor.constructMigrateApp(driverDN, bytes));
+
+ return NdsDtd.createStatusDocument(NdsDtd.SL_SUCCESS, opdata, "Submitted document to " + driverDN).getDocumentElement();
+
+ } catch (Throwable t) {
+
+ return NdsDtd.createStatusDocument(t, opdata).getDocumentElement();
+
+ } finally {
+
+ if (context != null) {
+ context.free();
+ }
+ }
+ }
+
+
+ private static DxWire getDxWire() {
+
+ DxWire wireCtor = new DxWire();
+ wireCtor.setDnFormat(0);
+ return wireCtor;
+ }
+
+ private static byte[] sendWireRequest(JCContext context, DxWire.DxWireData wireData) throws JCException {
+
+ byte[] replyBuffer = new byte[wireData.getResponseSize()];
+ int replySize = JClient.ndsRequest(context, wireData.getVerb(), wireData.getRequestData().length, wireData.getRequestData(),
+ replyBuffer.length, replyBuffer);
+
+ if (replySize == 0) {
+ return null;
+ } else if (replySize != replyBuffer.length) {
+ byte[] temp = new byte[replySize];
+ System.arraycopy(replyBuffer, 0, temp, 0, replySize);
+ replyBuffer = temp;
+ }
+ return replyBuffer;
+ }
}
\ No newline at end of file