Name

sn_cmp.CloudEventSchedulerUtil

Description

No description available

Script

var CloudEventSchedulerUtil = Class.create();
CloudEventSchedulerUtil.prototype = {
  initialize: function() {
  },
  
  processEvent: function (pid) {
  	var eventGr = new GlideRecord('sn_cmp_cloud_event');
  	eventGr.addQuery('state','ready');
  	eventGr.addQuery('pid', pid);
  	eventGr.setLimit(500);
  	eventGr.orderBy('event_time_epoch');
  	eventGr.orderBy('sys_created_on');
  	eventGr.query();
  	var matchedEventHandlerGr = null;
  	while(eventGr.next()){
  		var mutex = new global.CMPMutex(eventGr.getUniqueValue(), 1000, 10);
  		if (!mutex.get())
  			continue;
  		try {
  			eventGr.state = 'processing';
  			eventGr.update();
  			if (matchedEventHandlerGr != null){
  				if (this.findMatchedEventHandler(matchedEventHandlerGr, eventGr)){
  					this.processEventWithHandler(matchedEventHandlerGr, eventGr);
  					continue;
  				}		
  				else
  					matchedEventHandlerGr = null;			
  			}
  			var eventHandlerGr = new GlideRecord('sn_cmp_cloud_event_handler');
  			eventHandlerGr.addActiveQuery();
  			eventHandlerGr.query();
  			while(eventHandlerGr.next()){
  				if (this.findMatchedEventHandler(eventHandlerGr, eventGr)){
  					matchedEventHandlerGr = eventHandlerGr;
  					this.processEventWithHandler(matchedEventHandlerGr, eventGr);
  					break;
  				}
  			}		
  			if (matchedEventHandlerGr == null)
  				this.handleUnmatachedEvent(eventGr);
  		} finally {
  			//catch the error so we can release mutex
  			mutex.release();
  		}		

  	}
  },
  
  findMatchedEventHandler: function(eventHandlerGr, eventGr){
  	var headerName = eventHandlerGr.getValue('header_name');
  	var headerValue = eventHandlerGr.getValue('header_value');
  	var handlersource = eventHandlerGr.getValue('source');
  	var headers = new global.JSON().decode(eventGr.headers);
  	if (!headers)
  		return false;

  	var queryParams = new global.JSON().decode(eventGr.query_params);

  	//find matched handler if headers has the header name and value starts with headerValue
  	if (headers.hasOwnProperty(headerName) && (gs.nil(headerValue) || headers[headerName].indexOf(headerValue) == 0)) {
  		//if the event has source, make sure it matches handler source
  		if (queryParams) {
  			var sources = queryParams.source;
  			if (sources) {
  				var source = sources[0];
  				if (handlersource != source)
  					return false;
  			}
  		}
  		return true;
  	}		
  	else
  		return false;
  },

  handleResponse: function(eventGr, response){
  	if (!response || (response.state != 'processed' && response.state != 'processing' && response.state != 'ready')){
  		if (response){
  			eventGr.state = response.state ? response.state : 'skipped';
  			eventGr.error_message = response.error_message ? response.error_message : gs.getMessage('Event handler returned state is not processed');
  			this.updateEventGr(eventGr, response);
  		}else{
  			eventGr.state = 'error';
  			eventGr.error_message = gs.getMessage('Error running event handler');
  		}
  		eventGr.processed = new GlideDateTime();	
  	}else{
  		eventGr.state = response.state;
  		if (response.state == 'ready') {
  			eventGr.update();
  			return;
  		}
  		if (response.state == 'processed') 
  			eventGr.processed = new GlideDateTime();
  		this.updateEventGr(eventGr, response);
  	}	
  	eventGr.update();
  },

handleUnmatachedEvent: function(eventGr){
  eventGr.source = 'unknown';
  eventGr.state = 'skipped';
  eventGr.error_message = gs.getMessage('No event handler found');
  eventGr.processed = new GlideDateTime();
  eventGr.update();
},

processEventWithHandler: function(handler, eventGr){
  var source = handler.getValue('source');
  eventGr.setValue('state','processing');
  eventGr.setValue('source', source);
  eventGr.update();
  var evaluator = new GlideScopedEvaluator();
  evaluator.putVariable('headersStr',eventGr.getValue('headers'));
  evaluator.putVariable('bodyStr',eventGr.getValue('payload'));
  evaluator.putVariable('queryParamsStr',eventGr.getValue('query_params'));
  evaluator.putVariable('eventId',eventGr.getUniqueValue());
  this.handleResponse(eventGr,evaluator.evaluateScript(handler, 'run_handler_script'));
},

updateEventGr : function(eventGr, response){
  eventGr.event_name = response.event_name ? response.event_name : null;
  eventGr.event_time = response.event_time ? response.event_time : null;
  eventGr.ci = response.ci ? response.ci : null;
  eventGr.resource_type = response.resource_type ? response.resource_type : null;
  eventGr.resource_block = response.resource_block ? response.resource_block : null;
  eventGr.resource_id = response.resource_id ? response.resource_id : null;
  eventGr.subject = response.subject ? response.subject : null;
  eventGr.discovery_status = response.discovery_status ? response.discovery_status : null;
  eventGr.sys_domain = response.sys_domain ? response.sys_domain : null;
},
  
  type: 'CloudEventSchedulerUtil'
};

Sys ID

2bf029d61b2e4d10efd8eb15624bcb6e

Offical Documentation

Official Docs: