Name
sn_service_builder.ASBPublishService
Description
No description available
Script
var ASBPublishService = Class.create();
ASBPublishService.prototype = {
initialize: function() {
this.utils = new sn_service_builder.ASBUtils();
this.CONSTANTS = new sn_service_builder.ASBConstants();
this.DPM_ACTIVE = GlidePluginManager.isActive('com.snc.dpm');
if (this.DPM_ACTIVE)
this.DPM_SB_UTILS = new sn_service_builder.ASBUtilsDPM();
},
/**
* publishService
* copies the data of the draft service to the published service and
* deletes the draft records
*
* @param {string} serviceTable - the service table ie cmdb_ci_service_business
* @param {sysId} serviceId - the service that will be published
* @returns {boolean} true if succeeded, false otherwise
*/
publishService: function (serviceTable, serviceId) {
//Get the draft service
var draftServiceGr = new GlideRecord(serviceTable);
if (!draftServiceGr.get(serviceId))
return false;
//Check if the draft service is a new service
if (draftServiceGr.getValue(this.CONSTANTS.FIELD.PUBLISHED_REF) === null) {
//Since it is new, there is no original to copy data to and no reference tables need updating
try {
this._publishNewService(draftServiceGr);
} catch (err) {
//Error while publishing rollback by setting service and offerings back to draft
gs.error('[ASB] Could not publish service');
return false;
}
return true;
}
try {
this._publishExistingService(draftServiceGr);
} catch (err) {
//There was an error while publishing, so rollback
gs.error('[ASB] Problem while publishing ' + draftServiceGr + ': ' + err);
return false;
}
return true;
},
/**
* _publishNewService
* publishes the new service and its offerings
*
* @param {GlideRecord} serviceGr - the service that will be published
*/
_publishNewService: function(serviceGr) {
if (!serviceGr || !serviceGr.isValidRecord())
throw "Error while updating Service: invalid service passed into method";
// update offerings first
var offeringGr = new GlideRecord(this.CONSTANTS.TABLE.SERVICE_OFFERING);
offeringGr.addQuery(this.CONSTANTS.FIELD.PARENT, serviceGr.getUniqueValue());
offeringGr.query();
while (offeringGr.next()) {
var offeringCheckoutResult = this.utils.setCheckoutState(offeringGr,
this.CONSTANTS.FIELD_VALUE.FALSE,
this.CONSTANTS.FIELD_VALUE.PUBLISHED);
if (!offeringCheckoutResult)
throw 'Error while updating Offering: ' + offeringGr.getValue(this.CONSTANTS.FIELD.NAME) + ': ' + offeringGr.getUniqueValue();
}
var result = this.utils.setCheckoutState(serviceGr,
this.CONSTANTS.FIELD_VALUE.FALSE,
this.CONSTANTS.FIELD_VALUE.PUBLISHED);
if (!result)
throw 'Error while updating Service: ' + serviceGr.getValue(this.CONSTANTS.FIELD.NAME) + ': ' + serviceGr.getUniqueValue();
},
/**
* _publishExistingService
* publishes the draft service and its offerings
*
* @param {GlideRecord} draftServiceGr - the service that will be published
*/
_publishExistingService: function (draftServiceGr) {
// 1. Publish new offerings
// 2. Publish existing offerings with changes
// 3. Delete offerings without a "draft" offering record
//get offerings to publish first
var draftOfferingsGr = new GlideRecord(this.CONSTANTS.TABLE.SERVICE_OFFERING);
draftOfferingsGr.addQuery(this.CONSTANTS.FIELD.PARENT, draftServiceGr.getUniqueValue());
draftOfferingsGr.query();
// Update offerings
// We use validOfferingIds to keep track of the offerings that we've processed (new and updated offerings).
// Offering that is not in the sys id list, means that we've deleted the draft offering and the published record
// should be deleted as well.
var validOfferingIds = '';
while (draftOfferingsGr.next()) {
var offeringPublishedRef = draftOfferingsGr.getValue(this.CONSTANTS.FIELD.PUBLISHED_REF);
if (offeringPublishedRef)
validOfferingIds += offeringPublishedRef+',';
// If it doesn't have a published_ref, then it means it is a newly created offering, so push draft Id.
else
validOfferingIds += draftOfferingsGr.getUniqueValue()+',';
this._publishOffering(draftOfferingsGr, draftServiceGr.getValue(this.CONSTANTS.FIELD.PUBLISHED_REF));
}
var serviceRefTableMappings = {};
if (this.DPM_ACTIVE)
serviceRefTableMappings = this.DPM_SB_UTILS.getReferenceTableMappings(draftServiceGr.getTableName());
serviceRefTableMappings[this.CONSTANTS.TABLE.CMDB_REL_CI] = {
field: this.CONSTANTS.FIELD.CHILD,
query: this.CONSTANTS.FIELD.TYPE + '=' + this.CONSTANTS.FIELD_VALUE.PROVIDES_BY_PROVIDES
};
// update reference tables
for (var tableName in serviceRefTableMappings) {
if (serviceRefTableMappings.hasOwnProperty(tableName)) {
this.updateReferences(tableName,
serviceRefTableMappings[tableName].field,
draftServiceGr.getValue(this.CONSTANTS.FIELD.PUBLISHED_REF),
draftServiceGr.getUniqueValue(),
(serviceRefTableMappings[tableName].query || null));
}
}
//copy draft data to published record
var publishedServiceGr = new GlideRecord(draftServiceGr.getTableName());
publishedServiceGr.get(draftServiceGr.getValue(this.CONSTANTS.FIELD.PUBLISHED_REF));
this.utils.copyFields(draftServiceGr, publishedServiceGr, this.CONSTANTS.EXCLUDED_SERVICE_FIELDS());
if (publishedServiceGr.update() == null)
throw 'Could not copy draft record data to published record for ' + draftOfferingGr.name;
//delete draft
if (!draftServiceGr.deleteRecord())
throw 'Could not delete draft record for ' + draftServiceGr.name;
//update published state for service and offerings
this._publishNewService(publishedServiceGr);
},
_publishOffering: function(draftOfferingGr, publishedServiceId) {
// If published record exists (update offering)
if (draftOfferingGr.getValue(this.CONSTANTS.FIELD.PUBLISHED_REF)) {
//copy data from draft to published
var publishedOfferingGr = new GlideRecord(this.CONSTANTS.TABLE.SERVICE_OFFERING);
publishedOfferingGr.get(draftOfferingGr.getValue(this.CONSTANTS.FIELD.PUBLISHED_REF));
this.utils.copyFields(draftOfferingGr, publishedOfferingGr, this.CONSTANTS.EXCLUDED_OFFERING_FIELDS());
if (publishedOfferingGr.update() == null)
throw 'Could not copy draft record data to published record for ' + draftOfferingGr.name;
//Note: May want a different method for handling commitments
var subscribeTables = [
this.CONSTANTS.TABLE.SERVICE_SUBSCRIBE_COMPANY,
this.CONSTANTS.TABLE.SERVICE_SUBSCRIBE_DEPARTMENT,
this.CONSTANTS.TABLE.SERVICE_SUBSCRIBE_LOCATION,
this.CONSTANTS.TABLE.SERVICE_SUBSCRIBE_SYS_USER_GRP,
this.CONSTANTS.TABLE.SERVICE_SUBSCRIBE_SYS_USER,
this.CONSTANTS.TABLE.SERVICE_OFFERING_COMMITMENT,
this.CONSTANTS.TABLE.SC_CAT_ITEM_SUBSCRIBE_MTOM
];
var offeringRefTableMappings = {};
if (this.DPM_ACTIVE)
offeringRefTableMappings = this.DPM_SB_UTILS.getReferenceTableMappings(this.CONSTANTS.TABLE.SERVICE_OFFERING);
offeringRefTableMappings[this.CONSTANTS.TABLE.CMDB_REL_CI] = {
field: this.CONSTANTS.FIELD.PARENT,
query: this.CONSTANTS.FIELD.TYPE + '=' + this.CONSTANTS.FIELD_VALUE.DEPENDS_ON_USED_BY
};
for (var i = 0; i < subscribeTables.length; i++) {
this.updateReferences(subscribeTables[i],
this.CONSTANTS.FIELD.SERVICE_OFFERING,
draftOfferingGr.getValue(this.CONSTANTS.FIELD.PUBLISHED_REF),
draftOfferingGr.getUniqueValue());
}
for (var tableName in offeringRefTableMappings) {
if (offeringRefTableMappings.hasOwnProperty(tableName)) {
this.updateReferences(tableName,
offeringRefTableMappings[tableName].field,
draftOfferingGr.getValue(this.CONSTANTS.FIELD.PUBLISHED_REF),
draftOfferingGr.getUniqueValue(),
(offeringRefTableMappings[tableName].query || null));
}
}
//delete draft
if (!draftOfferingGr.deleteRecord())
throw 'Could not delete draft record for ' + draftOfferingGr.name;
// Else it is a new offering created in SB
} else {
draftOfferingGr.setValue(this.CONSTANTS.FIELD.PARENT, publishedServiceId);
draftOfferingGr.update();
}
},
/**
* updateReferences
* deletes the entries of the published record and updates
* the entries of the draft record to be the published record
*
* @param {string} tableName - the mtom table ie cmdb_rel_ci
* @param {string} refrenceField - the field that contains the reference to the item
* @param {sysId} publishedId - the id of the record that is published
* @param {sysId} draftId - the id of the record that is in draft
* @param {string} encodedQuery - optional: additional query to filter records on
*/
updateReferences: function(tableName, referenceField, publishedId, draftId, encodedQuery) {
//delete all of the records with a reference to the publishedId
this.utils.deleteReferences(tableName, referenceField, publishedId, encodedQuery);
//update all of the records with a reference to the draft Id, to have
//a reference to the publishedId instead
var draftGr = new GlideRecord(tableName);
draftGr.addQuery(referenceField, draftId);
if (encodedQuery)
draftGr.addEncodedQuery(encodedQuery);
draftGr.query();
while (draftGr.next()) {
draftGr.setValue(referenceField, publishedId);
if (!draftGr.update())
throw 'Could not update ' + tableName + ' references from ' + draftId + ' to ' + publishedId;
}
},
/* Method that deletes orphaned offerings.
* @param {GlideRecord} publishedServiceGr - GlideRecord of the published parent service.
* @param {string} validOfferingIds - String with comma separated offering sys ids. These are the sys
*/
_deleteOrphanedOfferings: function(publishedServiceGr, validOfferingIds) {
var publishedServiceId = publishedServiceGr.getUniqueValue();
if (!publishedServiceId)
throw 'Could not get service id';
var orphanedOfferings = new GlideRecord(this.CONSTANTS.TABLE.SERVICE_OFFERING);
orphanedOfferings.addQuery('parent', publishedServiceId);
orphanedOfferings.addQuery('sys_id', 'NOT IN', validOfferingIds);
orphanedOfferings.query();
if (orphanedOfferings.getRowCount() === 0)
return;
orphanedOfferings.deleteMultiple();
},
type: 'ASBPublishService'
};
Sys ID
465586ea07b2201070e493d0fad3003d