Name

sn_em_connector.CustomConnectorUtil

Description

This API will perform the following action 1. Create custom connector definition without script 2. Update image into sn_em_ai_hob_definition table 3. Create connector instance

Script

var CustomConnectorUtil = Class.create();
CustomConnectorUtil.prototype = {
  initialize: function() {},
  createDefinitionAndInstance: function(rawEvent) {
      try {
          // UI will send a parsed data but when this api is called from backend, there is possiblity that the data is not parsed and it is json string
          // Parsing it if the type of rawEvent is string
          var requestBody = (typeof rawEvent === 'string') ? JSON.parse(rawEvent) : rawEvent;

          var definition = new GlideRecord('sn_em_connector_listener');
          definition.initialize();
          var definitionName = requestBody.name;
          var custom_mid_server = requestBody.mid_server;
          var definitionSource = requestBody.event_source_label;
          if (!definitionName || !definitionSource) {
              throw "Custom Definition Name and Source Can't be Empty!! "
          }
          // Setting the custom definition Name, description, source
          // header name will be user-agent and header value and URL parameter value will be extracted from Source value
          definition.name = definitionName;
          definition.event_source_label = definitionSource;
          definition.description = requestBody.description;
          definition.active = false;

           // if type is coming as Integer value 10: Custom Instance and 11: Custom Mid
          var definitionType = requestBody.type;
          definitionType = parseInt(definitionType);
  		if(definitionType == null){
  			throw "Custom connector defintion can not be null";
  		}
          var customizedSourceValue = definitionSource.replaceAll(' ', '');
          if (!this.checkSpecialCharacters(customizedSourceValue)) {
              throw "Special Characters cant be used in the Source field";
          } else {
              if (definitionType == 10) {
                  definition.type = "1";
                  definition.header_name = 'user-agent';
  				definition.header_value = customizedSourceValue.toLowerCase();
  				definition.source = customizedSourceValue.toLowerCase();
              } else if (definitionType == 11) {
                  if (custom_mid_server == null || custom_mid_server == '') {
                      throw "Mid server is required to create Mid type custom connector!! Hence aborting the action!!";
                  }
                  definition.type = "2";
                  definition.header_name = 'Transform';
  				definition.header_value = 'TransformEvents_' + customizedSourceValue;
  				// creating MID script Include
                  var mid_script_mediator = new global.EvtMgmtConnectorMediator();
                  var mid_script_sys_id = mid_script_mediator.createCustomMidScriptInclude('TransformEvents_' + customizedSourceValue, requestBody.description, '');
                  definition.active = true;
                  definition.mid_server_script_include = mid_script_sys_id;
              }
          }
          // we cant activate the definition until user click on activate button while configuring the custom connector
          // will support a new function to activate the definition and connector instance
          var sysid = definition.insert();

          //  UI will the send the image_sys_id attribite for image sys_id
          var db_image = requestBody.image_sys_id;

          // Update the record into sn_em_ai_hob_definition table
          this.updateHealthOnboardingDefinitionRecord(sysid, db_image, definitionType);

          // Create connector instance

          var connector_instance = new GlideRecord('sn_em_connector_push_instance');
          connector_instance.initialize();
          connector_instance.name = definitionName;
          connector_instance.push_connector_definition = sysid;
          connector_instance.description = requestBody.description;
          if (definitionType == "11") {
              connector_instance.mid_server = custom_mid_server;
          }
          // Here, we can't activate while creating the connector instance, the connector instance will be activated once the user will click on Activate.
          var connector_sysid = connector_instance.insert();
          var url = connector_instance.getValue('url');

          var instance_tags = requestBody.instance_tags;
          var current_step = requestBody.current_step;
          // Set connector tags and current step in instance details table.
          this.updateHealthOnboardingInstanceRecord(connector_sysid, instance_tags, current_step);

          // UI team will get the information in a sequence
          return [sysid, connector_sysid, url];
      } catch (e) {
          gs.error(e);
          throw "Creating Custom is failed due to: " + e;
      }
  },
  updateHealthOnboardingDefinitionRecord: function(connectorSysid, db_image_id, custom_type) {
  // UI wants to set the html instruction for all custom connector
  var html_instruction = "<p>Integrate the custom connector with Event Management by adding a standard webhook in the custom connector console. Set up the custom connector by copying the displayed URL value to the clipboard and using it to configure the webhook on the custom connector console.</p>\n\
<p><strong>Before you begin</strong></p>\n\
<p>Ensure that the Event Management Connectors (sn_em_connector) plugin is installed on the Now Platform instance.</p>\n\
<p>Ensure that configuration items for the hosts managed by your custom connector exist in the Now Platform instance. These CIs can be physical or virtual and can be either manually created or discovered via IP discovery or Cloud Discovery.</p>\n\
<p><strong>Roles required: </strong>evt_mgmt_integration</p>\n\
<p><strong>About this task</strong></p>\n\
<p>Configure the Event Management environment for the collection of events from your custom connector by authenticating the custom connector as a data source. In your custom connector console, set your Now Platform instance as the rest endpoint using a standard webhook.</p>\n\
<p><strong>Procedure</strong></p>\n\
<ol style='list-style-position: inside;'><li>Copy the displayed URL value to the clipboard and use it to configure the webhook on the custom connector console to send events to ServiceNow instance.</li><li>Enter the username and password of the relevant user.</li></ol>\n\
<p><strong>Note</strong>: Ensure the evt_mgmt_integration role is assigned to the selected user. To ensure proper authentication, use the least privileged user with the evt_mgmt_integration role, rather than a highly privileged user.</p>\n\
<p><strong>Result</strong></p>\n\
<p>Events start flowing from your custom connector console into the ServiceNow Instance. The plugin extracts information from the original custom connector event message to populate the required event fields and inserts the event into the database. In your Now Platform instance, navigate to <strong>All Events</strong> to see the events.</p>\n";
      try {
          var hobRecord = new GlideRecord('sn_em_ai_hob_definition_details');
          hobRecord.get('reference_id', connectorSysid);
          if (db_image_id != null && db_image_id != "") {
              hobRecord.setValue('image', db_image_id);
          } else {
              // If user doesn't provide any image, in that case we have to take the custom image for custom connector
              hobRecord.setValue('image', '2cf1592a532121109472ddeeff7b12a2');
          }
          hobRecord.setValue('type', custom_type.toString());
          hobRecord.setValue('instructions', html_instruction);
          hobRecord.setValue('visible_in_launchpad', false);
          hobRecord.update();
      } catch (e) {
          throw e;
      }
  },
  updateHealthOnboardingInstanceRecord: function(connectorSysid, instance_tags, current_step) {

      if (!instance_tags && !current_step)
          return;

      try {
          var hobInstanceRecord = new GlideRecord('sn_itom_integ_app_instance_details');
          if (hobInstanceRecord.get('instance_reference_id', connectorSysid)) {

              if (current_step) {
                  hobInstanceRecord.setValue('current_step', current_step);
              }

              if (instance_tags) {
                  // In case the instance_tags comes as json object, stringify it before setting to instance_tag field.
                  hobInstanceRecord.setValue('instance_tags', (typeof instance_tags !== 'string') ? JSON.stringify(instance_tags) : instance_tags);
              }

              hobInstanceRecord.update();
          }
      } catch (e) {
          throw e;
      }
  },
  checkSpecialCharacters: function(string) {
      var format = /[!@#$%^&*()+\=\[\]{};'~:"\\|,.<>\/?]+/;
      if (string.match(format)) {
          return false;
      } else {
          return true;
      }
  },

  // To activate the connector instance and definition
  activateInstanceAndDefinition: function(connector_instance_sysid) {
      var connector_instance = new GlideRecord('sn_em_connector_push_instance');
      connector_instance.get(connector_instance_sysid);
      if (connector_instance.isValidRecord()) {
          connector_instance.setValue('active', true);
          var connector_definition = connector_instance.getValue('push_connector_definition');
          var connector_definition_record = new GlideRecord('sn_em_connector_listener');
          connector_definition_record.get(connector_definition);

          if (connector_definition_record.isValidRecord()) {
              connector_definition_record.setValue('active', true);
              connector_definition_record.update();
          } else {
              throw "There is no valid connector definition attached to this connector!! ";
          }
          connector_instance.update();
      } else {
          throw " There is no valid connector instance available for given sys_id : " + connector_instance_sysid;
      }
  },
  // To De-activate the connector instance and definition
  deactivateInstanceAndDefinition: function(connector_instance_sysid) {
      var connector_instance = new GlideRecord('sn_em_connector_push_instance');
      connector_instance.get(connector_instance_sysid);
      if (connector_instance.isValidRecord()) {
          connector_instance.setValue('active', false);
          connector_instance.update();
          var connector_definition = connector_instance.getValue('push_connector_definition');
          var connector_definition_record = new GlideRecord('sn_em_connector_listener');
          connector_definition_record.get(connector_definition);

          if (connector_definition_record.isValidRecord()) {
              connector_definition_record.setValue('active', false);
              connector_definition_record.update();
          } else {
              throw "There is no valid connector definition attached to this connector!! ";
          }
      } else {
          throw "There is no valid connector instance available for given sys_id : " + connector_instance_sysid;
      }
  },
  // this function can be call from definition and instance to update the definition and instance fields
  updateInstanceAndDefinitionFields: function(rawEvent) {
      try {
          // As Ui is sending the parsed data, No need to parse it here.
          var requestBody = rawEvent;

          var instance_sysid = requestBody.sys_id;
          if (instance_sysid == null && instance_sysid == "") {
              throw " Connector instance's sysid can not be null!! ";
          }

          var instance_description = requestBody.description;
          var instance_tags = requestBody.instance_tags;
          var current_step = requestBody.current_step;
          var definition_source = requestBody.event_source_label;
          var instance_name = requestBody.name;
          var db_image = requestBody.image_sys_id;
          // if type is coming as Integer value 10: Custom Instance and 11: Custom Mid
          var definitionType = requestBody.type;
          var custom_hob_record_type = definitionType;

          var instance_record = new GlideRecord('sn_em_connector_push_instance');
          instance_record.get(instance_sysid);
          if (instance_record.isValidRecord()) {
              instance_record.setValue('name', instance_name);
              instance_record.setValue('description', instance_description);

              var definition_sysid = instance_record.getValue('push_connector_definition');
              // we can not update the instance here, if we do that, URL will not be changed becuase it will take the non updated value of definition
              // so first we update the definition then instance

              if (definition_sysid != null && definition_sysid != "") {
                  var definition_record = new GlideRecord('sn_em_connector_listener');
                  definition_record.get(definition_sysid);
                  if (definition_record.isValidRecord()) {
                      var existing_type = definition_record.getValue('type');
                      if (definitionType != null && definitionType != '') {
                          if (definitionType == "10") {
                              definitionType = "1";
                          } else if (definitionType == "11") {
                              definitionType = "2";
                          }
                      }
                      if(definitionType != existing_type){
  						this.deleteInstanceAndDefinition(instance_sysid);
  						return this.createDefinitionAndInstance(rawEvent);
  					}
                      definition_record.setValue('name', instance_name);
                      definition_record.setValue('event_source_label', definition_source);
                      definition_record.setValue('description', instance_description);
                      var customizedSourceValue = definition_source.replaceAll(' ', '');
                      if (!this.checkSpecialCharacters(customizedSourceValue)) {
                          throw "Special Characters cant be used in the Source field";
                      } else {
                          if (definitionType == "1") {
                              definition_record.setValue('header_value', customizedSourceValue.toLowerCase());
                              definition_record.setValue('source', customizedSourceValue.toLowerCase());
                          } else if (definitionType == "2") {
                              definition_record.setValue('header_value', 'TransformEvents_' + customizedSourceValue);
                              var mid_server_script_include = definition_record.getValue('mid_server_script_include');
  							var mid_script_mediator = new global.EvtMgmtConnectorMediator();
  							mid_script_mediator.updateCustomMidScriptInclude('TransformEvents_' + customizedSourceValue, instance_description, mid_server_script_include, '');
                          }
                      }

                      definition_record.update();
                  } else {
                      throw " There is no valid connector definition available for sysid : " + definition_sysid;
                  }
              } else {
                  throw " Connector Definition sysid can not be null for connector instance: " + instance_name;
              }
              // updating the instance
              instance_record.update();
              if (db_image != null && db_image != '') {
                  this.updateHealthOnboardingDefinitionRecord(definition_sysid, db_image, custom_hob_record_type);
              }
              // set instance_tags and current_step to instance details table
              this.updateHealthOnboardingInstanceRecord(instance_sysid, instance_tags, current_step);

          } else {
              throw " There is no valid connector instance available for given sys_id : " + instance_sysid;
          }
      } catch (e) {
          gs.info(e);
          throw "Connector instance Update is failed due to " + e;
      }
  },
  // calling this function will delete the instance and definition
  deleteInstanceAndDefinition: function(sys_id) {
      var connector_instance = new GlideRecord('sn_em_connector_push_instance');
      connector_instance.get(sys_id);
      if (connector_instance.isValidRecord()) {
          var connector_definition = connector_instance.getValue('push_connector_definition');
          var connector_definition_record = new GlideRecord('sn_em_connector_listener');
          connector_definition_record.get(connector_definition);
  		var type = connector_definition_record.getValue('type');
  		// delete mid script include if type is mid
  		if(type == '2'){
  		    var mid_server_script_include = connector_definition_record.getValue('mid_server_script_include');
              var mid_script_mediator = new global.EvtMgmtConnectorMediator();
              mid_script_mediator.deleteCustomMidScriptInclude(mid_server_script_include);
  		}
          connector_definition_record.deleteRecord();
      } else {
          throw ' There is no valid connector instance available for the given sys_id : ' + sys_id;
      }
  },
  type: 'CustomConnectorUtil'
};

Sys ID

56f1eab85331e1109472ddeeff7b124e

Offical Documentation

Official Docs: