Multistage Synthetic New Relic Monitor

PHOTO EMBED

Thu Mar 11 2021 13:05:11 GMT+0000 (Coordinated Universal Time)

Saved by @Pixelartist #nodejs

// Script-wide timeout for wait and waitAndFind functions (in ms)
var startTime = new Date(),
  thisStep = 0,
  assert = require('assert'),
  Q = require('q'),
  ScriptTimeout = 0,
  MaintenanceMessage = "Script is running during maintenance window";

var log = function(msg) {
  if(typeof msg === "string")
  {
    var totalTimeElapsed = (new Date() - startTime);
    var elapsedSecs =  totalTimeElapsed / 1000;
    console.log('Step ' + thisStep + ': ' + elapsedSecs.toFixed(2) + 's: ' + msg);
    thisStep++;
    
    if(ScriptTimeout > 0 && totalTimeElapsed > ScriptTimeout)
    {
      throw Error('Script timed out. ' + totalTimeElapsed + 'ms is longer than script timeout threshold of ' + ScriptTimeout + 'ms.'); 
    }
  }
};

log("Initialising ...");

 // checks if this run is in within the maintenance window provided
 // @param {string} dayOfWeek - Monday, Tuesday, etc.
 // @param {string} startTime - UTC start time of window in 24hr format
 // @param {string} endTime - UTC end time of window in 24hr format
var checkInMaintenanceWindow = function(dayOfWeek, startTime, endTime)
{
  log("checkInMaintenanceWindow");
  var deferred = Q.defer();
  var daysOfWeek = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
  var now = new Date();
  var day = daysOfWeek[now.getUTCDay()];
  
  if(day != dayOfWeek)
  {
    log("Days do not match");
    deferred.resolve("Days do not match"); // not the specified day
  }
  else
  {
    log("Days match, checking times");
    startParts = startTime.split(":");
    var start = new Date(now);
    start.setUTCHours(parseInt(startParts[0]), parseInt(startParts[1]));

    endParts = endTime.split(":");
    var end = new Date(now);
    end.setUTCHours(parseInt(endParts[0]), parseInt(endParts[1]));

    // check if we are in the maintenance window
    if(now.getTime() >= start.getTime() && now.getTime() <= end.getTime())
    {
      log("In maintenance window");
      $http.get("http://www.google.co.uk"); // workaround for monitor produced no traffic error
      deferred.reject(MaintenanceMessage);
    }
    else
    {
      deferred.resolve("Times do not match");
    }
  }  
  return deferred.promise;
};

function shouldDisplayError(message)
{
  return !(typeof message != "undefined" && message !== null && message.length > 0);
}

var buildSecurityOptions = function()
{
  var deferred = Q.defer();
  log("Building security options");
  // build your security options here
  var options = {
    //Define endpoint URL.
    //url: "https://webhook.site/ddb04be2-8961-4771-b934-6dddfa40ab57",
    url: "https://login.salesforce.com/services/oauth2/token",
    //Define body of POST request.
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    form: {
      grant_type: 'password',
      client_id: 'client ID',
      client_secret: 'Client Secret',
      username: 'username',
      password: 'password'
    }
  };
  
  deferred.resolve(options); //fulfills the promise with options as the value
  return deferred.promise; //promise is returned
};

var getSecurityToken = function(options){
  var deferred = Q.defer();
  log("Retrieving Security Token");
  $http.post(options, function(error, response, body)
  {
    if (error)
    {
      log(error);
      deferred.reject(error); //rejects the promise with `error` as the reason
    }
    else
    {
      //Verify endpoint returns 200 (OK) response code.
      assert.ok(response.statusCode == 200, 'Expected 200 OK response, actual:' + response.statusCode);
      deferred.resolve(body); //fulfills the promise with body as the value
    }    
  });
  return deferred.promise; //promise is returned
};

var extractSecurityToken = function(data){
  log("Extracting Security Token");
  var deferred = Q.defer();
  //Parse JSON received from Insights into variable.
  var info = JSON.parse(data);
  log("Security token retrieved successfully");
  deferred.resolve(info.access_token);
  return deferred.promise;
};

var buildApiOptions = function(securityToken){
  var deferred = Q.defer();
  log("Building API options");
  // build your api options here
  var options = {
    //Define endpoint URL.
    //url: "https://webhook.site/ddb04be2-8961-4771-b934-6dddfa40ab57",
    url: "http://url.com",
    //Define body of PATCH request.
    headers: {'Content-Type': 'application/json',
              'Authorization': 'Bearer ' + securityToken},
    body: {
      "Description": "fooba3r"
    },
    json: true

  };
  deferred.resolve(options); //fulfills the promise with options as the value
  return deferred.promise; //promise is returned
};

var makeApiCall = function(options){
  var deferred = Q.defer();
  log("Making API call");

  //Make PATCH request, passing in options and callback.
  $http.patch(options, function(error, response, body){
    if (error)
    {
      log(error);
      deferred.reject(error); //rejects the promise with `error` as the reason
    }
    else
    {
      //Verify endpoint returns 204 (No Content) response code.
      assert.ok(response.statusCode == 204, 'Expected 204 OK response, actual:' + response.statusCode);
      deferred.resolve(body); //fulfills the promise with body as the value
    }
  });
  return deferred.promise; //promise is returned
};

var validateApiCall = function(body){
  log("Validating Api Call");
  var deferred = Q.defer();
  //Parse JSON received from Insights into variable.
  //var info = JSON.parse(body);
  //assert.ok(shouldDisplayError(info.ErrorMessage), "Error Message: " + info.ErrorMessage);
	
  // perform any other validation here
  log("Completed successfully");
  deferred.resolve();
  return deferred.promise;
};

checkInMaintenanceWindow("Friday", "00:00", "01:30")
.then(function(){
  return buildSecurityOptions()
  .then(getSecurityToken)
  .then(extractSecurityToken)
  .then(buildApiOptions)
  .then(makeApiCall)
  .then(validateApiCall);
},
function(message){
  if(message != MaintenanceMessage)
  {
    throw new Error(MaintenanceMessage);
  }
  else
  {
    log(message);
  }
})
.done();
content_copyCOPY

New Relic synth monitor