Name

global.AccUpdateSetPublisher

Description

No description available

Script

var AccUpdateSetPublisher = Class.create();
AccUpdateSetPublisher.prototype = {

  SN_AGENT_ASSET: 'sn_agent_asset',
  SN_AGENT_ASSET_NAME: 'sn_agent_asset_name',
  SYS_ATTACHMENT: 'sys_attachment',
  SYS_ATTACHMENT_DOC: 'sys_attachment_doc',

  initialize: function(newUpdateSetName, logger, tracker) {
      this.updateSetName = newUpdateSetName;
      this.logger = logger;
  	this.tracker = tracker;
      this.api = new UpdateSetAPI();
      if (newUpdateSetName !== null && newUpdateSetName !== undefined) {
          this.originUpdateSetId = this.api.getCurrentUpdateSetID();
          this.api.insertUpdateSetAsCurrent(newUpdateSetName);
          this.logger.log('UpdateSet: ' + newUpdateSetName + ' set as current');
      }

      this.isForcePublish = false;
      this.manager = new GlideUpdateManager2();
      this.countOfPublishedRecords = 0;
      this.updateSetId = this.api.getCurrentUpdateSetID();

      this.updateSetArray = {};
      this.updateSetArray['global'] = this.updateSetId;
  },

  complete: function() {
      this.api.completeUpdateSet(this.updateSetId);
  },

  accomplish: function() {

      if (this.originUpdateSetId !== undefined) {
          /* Restore the previous UpdateSet to be a current*/
          new GlideUpdateSet().set(this.originUpdateSetId);
          this.logger.log('Original UpdateSet is set to current');
      } else {
          this.logger.error('Failed to set original UpdateSet as current');
      }
  },

  getUpdateSetId: function() {
      return this.updateSetId;
  },

  publishMultiple: function(tables, skipLog, isReference, aRef, bRef) {
      for (var currentTableIndex in tables) {
          var currentTable = tables[currentTableIndex];
          this.publishSingle(currentTable, skipLog, isReference, aRef, bRef);
      }
  },

  publishSingle: function(table, skipLog, isReference, aRef, bRef) {
      this._publish(table, skipLog, isReference, aRef, bRef);
  },

  _publish: function(gr, skipLog, isReference, aRef, bRef) {
      if (gr === null)
          return;
      var tableName = gr.getTableName();

      while (gr.next()) {
          if (!this._isRecordExist(gr) && !this.isForcePublish) {
              this.manager.saveRecord(gr);
              if (skipLog === undefined || (skipLog !== undefined && skipLog === false)) {
                  if (isReference === undefined || (isReference !== undefined && isReference === false))
                      this.logger.log('Exporting record: [' + tableName + '] ' + gr.getDisplayValue());
                  else
                      this.logger.log('Exporting record: [' + tableName + '] Reference: ' + gr.getElement(aRef).getDisplayValue() + '->' + gr.getElement(bRef).getDisplayValue());
              }

              this.countOfPublishedRecords++;
          } else if (this._isRecordExist(gr)) {
              if (skipLog === undefined || (skipLog !== undefined && skipLog === false)) {
                  if (isReference === undefined || (isReference !== undefined && isReference === false))
                      this.logger.log('Record exists in updateset: [' + tableName + '] ' + gr.getDisplayValue());
                  else
                      this.logger.log('Record exists in updateset: [' + tableName + '] Reference: ' + gr.getElement(aRef).getDisplayValue() + '->' + gr.getElement(bRef).getDisplayValue());
              }
          }
      }
  },

  _isRecordExist: function(gr) {
      var upGr = new GlideRecord('sys_update_xml');
      upGr.addQuery('name', gr.getTableName() + '_' + gr.sys_id);
      upGr.addQuery('update_set', this.updateSetId);
      upGr.query();
      return upGr.hasNext();
  },

  getCountOfPublishedRecords: function() {
      return this.countOfPublishedRecords;
  },

  // Utility function for adding virtual records to Exported updateset.
  // You can override the update_set field by adding it to the fieldValuePairsArray
  addVirtualRecordToUpdateset: function(fieldValuePairs) {
      var gr = new GlideRecord('sys_update_xml');
      gr.initialize();
      gr.setValue('update_set', this.updateSetId);
      for (var i in Object.keys(fieldValuePairs)) {
          var key = Object.keys(fieldValuePairs)[i];
          gr.setValue(key, fieldValuePairs[key]);
      }
      gr.insert();
  },

  // Utility function for getting a global scope GlideRecord from App scope.
  // The GlideRecord will not be accessible in App Scope, but we will be able to pass it through to global scope functions.
  getGlobalScopeRecords: function(table, queryFieldValuePairs) {
      var gr = new GlideRecord(table);
      for (var i in Object.keys(queryFieldValuePairs)) {
          var field = Object.keys(queryFieldValuePairs)[i];
          var value = queryFieldValuePairs[field];
          gr.addQuery(field, value);
      }
      gr.query();
      return gr;
  },

  __publish: function(gr) {
      var upGr = new GlideRecord('sys_update_xml');
      upGr.addQuery('name', this.manager.getUpdateName(gr));
      upGr.addQuery('update_set', this.updateSetId);
      upGr.query();
      if (upGr.hasNext())
          return;
      upGr.initialize();
      upGr.setValue('category', 'customer');
      upGr.setValue('name', this.manager.getUpdateName(gr));
      upGr.setValue('update_domain', 'global');
      var targetName;
      if (gr.name)
          targetName = gr.name;
      else
          targetName = gr.sys_id;

      upGr.setValue('target_name', targetName);
      upGr.setValue('update_set', updateSetId);
      upGr.setValue('payload', gs.unloadRecordToXML(gr, false));
      upGr.setValue('action', 'INSERT_OR_UPDATE');
      var descriptor = GlideTableDescriptor.get(gr.getTableName());
      upGr.setValue('type', descriptor.getLabel());
      upGr.insert();
  },

  splitUpdateSetScopes: function() {
      var updatesetGr = new GlideRecord('sys_update_xml');
      updatesetGr.addQuery('update_set', this.updateSetId);
      updatesetGr.query();
      while (updatesetGr.next()) {
          var application = updatesetGr.application;
          if (application == 'global')
              continue;
          this.createUpdateSetIfNotExist(this.updateSetName, application);
          updatesetGr.setValue('update_set', this.updateSetArray[application]);
          updatesetGr.update();
      }
  },

  createUpdateSetIfNotExist: function(name, appId) {
      if (gs.nil(this.updateSetArray[appId])) {
          var gr = new GlideRecord('sys_update_set');
          gr.initialize();
          gr.name = name + '_' + appId;
          gr.application = appId;
          gr.parent = this.updateSetArray['global'];
          var sysID = gr.insert();
          this.updateSetArray[appId] = sysID;
      }
  },

  //For each deleted record related to the exported policy in sys_update_xml, we create a duplicate record
  //and assign in to the exported updateset. This prevents the loss of records from this table post export.
  addDeleteRecordsToGlobalUpdateset: function(gr) {
      while (gr.next()) {
          gr.insert();
          gr.setWorkflow(false);
          gr.setValue('update_set', this.updateSetArray['global']);
          gr.update();
          this.logger.log('Adding DELETE record: ' + gr.getValue('name'));
      }
  },

  getAttachments: function(nameIds) {
      var assetGr = this.getAssets(nameIds);
      var assetIds = [];
      while (assetGr.next()) {
          if (assetIds.indexOf(assetGr.getValue('sys_id')) == -1)
              assetIds.push(assetGr.getValue('sys_id'));
      }
      var attachGr = new GlideRecord(this.SYS_ATTACHMENT);
      attachGr.addQuery('table_name', this.SN_AGENT_ASSET);
      attachGr.addQuery('table_sys_id', assetIds);
      attachGr.query();
      return attachGr;
  },

  //depracted, here only to support old ACC scoped apps, use getAttachmentDocArr instead and don't access SYS_ATTACHMENT_DOC table directly...
  getAttachmentDocs: function(nameIds) {
      var attachIds = [];
      var attachGr = this.getAttachments(nameIds);
      while (attachGr.next()) {
          if (attachIds.indexOf(attachGr.getValue('sys_id')) == -1)
              attachIds.push(attachGr.getValue('sys_id'));
      }
      var attachDocsGr = new GlideRecord(this.SYS_ATTACHMENT_DOC);
      attachDocsGr.addQuery('sys_attachment', attachIds);
      attachDocsGr.query();
      return attachDocsGr;
  },

  getAttachmentDocsArr: function(nameIds) {
  	var result = [];
  	var sysAttachmentUtil = new GlideSysAttachment();
  	var attachGr = this.getAttachments(nameIds);
  	while (attachGr.next()) {
  		result.push(sysAttachmentUtil.getAttachmentParts(attachGr.getValue('sys_id')));		
  	}
  	return result;
  },
  
  getAssets: function(nameIds) {
      var asGr = new GlideRecord(this.SN_AGENT_ASSET_NAME);
      asGr.addQuery('sys_id', nameIds);
      asGr.query();
      var names = [];
      while (asGr.next()) {
          if (names.indexOf(asGr.getValue('name')) == -1)
              names.push(asGr.getValue('name'));
      }
      var assetGr1 = new GlideRecord(this.SN_AGENT_ASSET);
      assetGr1.addQuery('name', names);
      assetGr1.query();
      var assetUpdatedSysIds = [];
      // Need to filter this query to match which records based on name were updated (using sys_update_xml)
      // The check for what sn_agent_asset records are not OOB is determined by querying on Agent Client Collector Plugin
      // and the 'name' of the record. If the person who updated it is not system, then it is not OOB.
      while (assetGr1.next()) {
          var updateGr = new GlideRecord('sys_update_xml');
          updateGr.addQuery('type', 'Agent Client Collector Plugin');
          updateGr.addQuery('name', assetGr1.getValue('sys_update_name'));
          updateGr.orderByDesc('sys_updated_on');
          updateGr.query();
          if (updateGr.next()) {
              if (updateGr.getValue('sys_updated_by') != 'system') {
                  assetUpdatedSysIds.push(assetGr1.getUniqueValue());
              }
          }
      }
      var assetGr2 = new GlideRecord(this.SN_AGENT_ASSET);
      assetGr2.addQuery('sys_id', assetUpdatedSysIds);
      assetGr2.query();
      //Clear parent in order to avoid orphan records. parent field will repopulate by BR on sn_agent_asset table.
      assetGr2.setValue('parent', 'NULL');
      assetGr2.setWorkflow(false);
      assetGr2.updateMultiple();
      var assetGr3 = new GlideRecord(this.SN_AGENT_ASSET);
      assetGr3.addQuery('sys_id', assetUpdatedSysIds);
      assetGr3.query();
      return assetGr3;
  },
  
  updateTracker: function(intervalPercent){
  	this.tracker.incrementPercentComplete(intervalPercent);
  },

  type: 'AccUpdateSetPublisher'
};


/*Static function for delete */
AccUpdateSetPublisher.deleteAllUpdateSets = function(baseUpdatesetSysId) {
  var updateSetList = [];
  var ugr = new GlideRecord("sys_remote_update_set");
  ugr.addQuery("sys_id", baseUpdatesetSysId);
  ugr.query();
  if (ugr.next()) {
      //remote_sys_id and remote_base_sys_id provide the necessary references to parent and child update sets in the batch.
      updateSetList.push(ugr.remote_sys_id);
      updateSetList.push(ugr.remote_base_update_set);
  }

  var gr = new GlideRecord('sys_update_xml');
  gr.addQuery('update_set', updateSetList);
  gr.setWorkflow(false);
  gr.deleteMultiple();

  var gr2 = new GlideRecord('sys_remote_update_set');
  gr2.addQuery('remote_base_update_set', updateSetList);
  gr2.query();
  gr2.setWorkflow(false);
  gr2.deleteMultiple();

  var gr3 = new GlideRecord('sys_update_set');
  gr3.addQuery('base_update_set', updateSetList);
  gr3.query();
  gr3.setWorkflow(false);
  gr3.deleteMultiple();
};

Sys ID

4f79780ab735d010c3608129ce11a987

Offical Documentation

Official Docs: