bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington/**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The following objects are available in an onSync script handler.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * syncResults contains the information about
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * - the synchronized targets as syncDetails
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * - the synchronization action being performed
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * - the success of the synchronization
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * syncResults: {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "syncDetails": [
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "result": "SUCCESSFUL",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "oldTargetValue": null,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "reconId": null,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "action": "CREATE",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "targetId": "f601fe2d-c0bc-49c3-a95c-6f64addc33d5",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "mapping": "managedUser_systemAdAccounts",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "targetObjectSet": "system/ad/account",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "situation": "ABSENT",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "sourceId": "efb53d24-599d-4d43-9e56-12f2e13dc91c"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * },
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "result": "FAILED",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "oldTargetValue": null,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "cause": {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "code": 409,
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * "reason": "Conflict",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "message": "Missing required field: __PASSWORD__"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * },
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "reconId": null,
ce4d3fddc8fe2eddd68a20af9570b3cc63ece5abNeil Madden * "action": "CREATE",
ce4d3fddc8fe2eddd68a20af9570b3cc63ece5abNeil Madden * "mapping": "managedUser_systemLdapAccounts",
ce4d3fddc8fe2eddd68a20af9570b3cc63ece5abNeil Madden * "targetObjectSet": "system/ldap/account",
ce4d3fddc8fe2eddd68a20af9570b3cc63ece5abNeil Madden * "situation": "ABSENT",
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * "sourceId": "efb53d24-599d-4d43-9e56-12f2e13dc91c"
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * ],
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * "action": "notifyCreate",
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * "success": false
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington *
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * The request object is available. A sample create request is shown:
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington *
ce4d3fddc8fe2eddd68a20af9570b3cc63ece5abNeil Madden * request: {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * "method": "create",
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * "fields": {},
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * "resourceName": "",
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * "content": {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington * "_rev": "20",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "mail": "mail2@example.com",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "sn": "Doe",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "_id": "efb53d24-599d-4d43-9e56-12f2e13dc91c",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "description": "Created By XML1",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "accountStatus": "active",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "roles": {},
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "userName": "DDOE1",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "givenName": "Darth"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * },
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "newResourceId": "efb53d24-599d-4d43-9e56-12f2e13dc91c"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Additionally, request will contain the additional parameter "compensating" when this script is invoked the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * second time through when reverting a change as part of a failed operation:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "additionalParameters": {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "compensating": "true"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * },
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The previous state of the object before the change is given as 'oldObject':
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * oldObject: null
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The updated or new state of the object after the change is given as 'newObject':
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * newObject: {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "_rev": "21",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "mail": "mail2@example.com",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "sn": "Doe",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "_id": "efb53d24-599d-4d43-9e56-12f2e13dc91c",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "description": "Created By XML1",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "accountStatus": "active",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "roles": [],
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "effectiveAssignments": [],
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "userName": "DDOE1",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "givenName": "Darth",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "effectiveRoles": []
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * resourceName: an object representing the resource name URI full path
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * resourceName.toString(): managed/user/efb53d24-599d-4d43-9e56-12f2e13dc91c
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * resourceName.leaf().toString(): efb53d24-599d-4d43-9e56-12f2e13dc91c
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * resourceName.parent().toString(): managed/user
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster(function() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster var _ = require("lib/lodash.js");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (syncResults.success) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster logger.debug("sync was a success; no compensation necessary");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (request !== null
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster && request.additionalParameters !== null
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster && request.additionalParameters.compensating === "true") {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster logger.debug("already compensating, returning");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster logger.debug("compensating for " + resourceName);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster var params = { "compensating" : true };
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster switch (syncResults.action) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case "notifyCreate":
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster openidm.delete(resourceName.toString(), newObject._rev, params);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (e) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster logger.warn("Was not able to delete {} from compensation script", resourceName.toString(), e);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington break;
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington case "notifyUpdate":
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster openidm.update(resourceName.toString(), newObject._rev, oldObject, params);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (e) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster logger.warn("Was not able to update {} from compensation script", resourceName.toString(), e);
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster break;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case "notifyDelete":
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster openidm.create(resourceName.parent().toString(), resourceName.leaf().toString(), oldObject, params);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (e) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster logger.warn("Was not able to create {} from compensation script", resourceName.toString(), e);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster break;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster logger.debug(resourceName + " sync failure compensation complete");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // throw the error that caused the sync failure
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster var firstFailure = _.find(syncResults.syncDetails,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster function (r) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return r.result === "FAILED" && r.cause !== undefined;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster });
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington if (firstFailure !== null) {
bee2440354b4bc8796e1de0b6cbd60e1f68deba0Phill Cunnington throw firstFailure.cause;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster