Your data. Anywhere you go.

New Relic for iOS or Android


Download on the App Store    Android App on Google play


New Relic Insights App for iOS


Download on the App Store


Learn more

Close icon

API Synthetic monitoring

developer

#1

I’m new to Newrelic synthetic trying to implement monitoring for API gateway calls.
The requirement is that we call API gateway for user authorization with specific headers to be passed and get the auth token. We need to extract the auth token and pass the token along with the previous header parameters for the next corresponding services.

if there is any sample script will help me…


#2

Here is the sample test used for User authorization and not sure how to extract the auth token and pass it to next validation.

//Define your authentication credentials
var myAccountID = ‘{YOUR_ACCOUNT_ID}’;
var myQueryKey = ‘{YOUR_QUERY_KEY}’;
var options = {
//Define endpoint URI
uri: ‘https://api.welcome.com/userauthorization/login’,
//Define query key and expected data type.
headers: {
‘clientId’: ‘user’,
‘apikey’: ‘redacted’,
‘cb_session’: ‘redacted’,
‘ma_transaction_id’: ‘test1234’
}
};

//Define expected results using callback function.
function callback (err, response, body){
//Log JSON results from endpoint to Synthetics console.
console.log(JSON.parse(body));
//console.log(‘done with script’);
}

//Make GET request, passing in options and callback.
$http.get(options,callback);


#3

@stefan_garnham… Could you help me?


#4

Hi @yograj.patel - Have a look at my template for API synthetic with a maintenance window which has been written to consider the security authentication and response extraction.


#5

Hi @yograj.patel,

I just wanted to check in to see if you were able to get Stefan’s solution to work.

Let us know if you have any questions!


#6

Hi @cneff I couldn’t get the script work since it has more details on maintenance window and i’m confused since i’m new to API synthetics.

I’m trying the simple API call passing the headers for login authentication and it is working fine.

the next step would be from the authenticated header i need to extract the auth token and pass it an the header along with the previous headers for the next service .


#7

@yograj.patel

For this use case, using promises to perform these HTTP requests synchronously would help here. You can get the header values from the first response object and pass that along to the next request.

Here is an example of that pattern:

function getAuthKey(){
  return new Promise((resolve, reject) => {
    
    const options = {
      uri: 'https://your-auth-provider.com/auth',
      headers:{
        'test-api-key': 'test'
      }
    }

    $http.get(options, (error, response, body) => {
      if(error){
        console.log(error)
        throw new Error(error)
      } else {
        resolve(
          response.headers['auth-key']
        )
      }
    })
  })
}

function postToAPI(authKey){
  return new Promise((resolve, reject) => {
    const options = {
      uri: 'http://your-api.com/postData',
      headers:{
        'test-auth-key': authKey
      }
    }

    $http.post(options, (error, response, body) => {
      if(error){
        console.log(error)
        throw new Error(error)
      } else {
        resolve(
          {
            response: response,
            body: body
          }
        )
      }
    })
  })
}

getAuthKey()
.then((authKey) => {
  return postToAPI(authKey)
}).then((response) => {
  console.log(response.response.statusCode)
})

#8

Hi Michel,

Here is the sample script tired to extract the auth token which is failing.

function getAuthKey(){
return new Promise((resolve, reject) => {

const options = {
  uri: 'https://apigateway.stg.cox.com/cbma/userauthorization/services/loginprofiles/login',
  headers:{
    'apikey': '_redacted_'
    'clientID':'_redacted_'
    'cb_session':'_redacted_'
    'ma_transaction_id';'_redacted_'
  }
}

$http.get(options, (error, response, body) => {
  if(error){
    console.log(error)
    throw new Error(error)
  } else {
    resolve(
      response.headers['cbma_authtoken']
    )
  }
})

})
}


#9

@Michel_L
I tried the first half to just extract the auth token but failing with below error:

function getAuthKey(){
return new Promise((resolve, reject) => {

const options = {
  uri: 'https://apigateway.stg.cox.com/cbma/userauthorization/services/loginprofiles/login',
  headers:{
    'apikey': 'REDACTED'
	    'clientID': 'REDACTED'
	    'cb_session': 'REDACTED'
	    'ma_transaction_id': 'test1234'
  }
}

$http.get(options, (error, response, body) => {
  if(error){
    console.log(error)
    throw new Error(error)
  } else {
    resolve(
      response.headers['cbma_authtoken']
    )
  }
})

})
}

Error:

Job failed before completion (id: “undefined”): Unexpected token =>
SyntaxError: Unexpected token =>
at Function (native)
at JobResource.getScriptFn (/opt/runtimes/2.0.0/modules/synthetics-runner/lib/job-resource/index.js:76:19)
at ApiScriptRunner.Object.defineProperties.run.value [as run] (/opt/runtimes/2.0.0/modules/synthetics-runner/lib/runner/0.1.0/script-runner.js:63:44)
at Object. (/opt/runtimes/2.0.0/main.js:15:35)
at Module._compile (module.js:460:26)
at Object.Module._extensions…js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)


#10

@yograj.patel

The error Unexpected token => would indicate that the runtime environment this monitor is running in does not know es6 arrow function syntax, which my example uses. Runtime is determined both by the monitor API version (indicated in the general settings of the monitor), and if it is being executed on a Private Minion, whether that runtime was available for the minion at the time of build.

A 0.5.x API Version will support es6 syntax. The error stack you included indicates to me that this monitor maybe of a 0.4.x API Version

Moving forward you can approach this:

  • If the monitor is a 0.4.x API Version, make a new monitor with this script so the latest API version is utilized.
  • Replace arrow functions with standard anonymous function syntax. For example:

es6 syntax:

$http.get(options, (error, response, body) => {
  if(error){
    console.log(error)
    throw new Error(error)
  } else {
    resolve(
      response.headers['cbma_authtoken']
    )
  }
})

standard function syntax:

$http.get(options, function(error, response, body){
  if(error){
    console.log(error)
    throw new Error(error)
  } else {
    resolve(
      response.headers['cbma_authtoken']
    )
  }
})

#11

Getting the below error:

Job failed before completion (id: “undefined”): Unexpected string
SyntaxError: Unexpected string
at JobResource.getScriptFn (/opt/runtimes/3.0.0/modules/synthetics-runner/lib/job-resource/index.js:76:19)
at ApiScriptRunner.value [as run] (/opt/runtimes/3.0.0/modules/synthetics-runner/lib/runner/0.5.0/script-runner.js:67:44)
at Object. (/opt/runtimes/3.0.0/main.js:15:35)
at Module._compile (module.js:570:32)


#12

@yograj.patel as the error indicates Unexpected string SyntaxError: Unexpected string it seems to be indicating that their is a string value somewhere in your script that is unexpected in its syntax context. I would recommend reviewing your script for instances of this. For example, in the snippet you provided farther above

  headers:{
    'apikey': 'REDACTED'
	    'clientID': 'REDACTED'
	    'cb_session': 'REDACTED'
	    'ma_transaction_id': 'test1234'
  }

There are no commas separating those key values in that object. A comma would be expected, but a string was found.


#13

@Michel_L,

I tried the script with commas, the first part is working fine.

Need to extract the auth token form the first and pass the headers along with the auth token to the 2nd which is failing.

https://synthetics.newrelic.com/accounts/1175115/monitors/9015f31c-e1b8-4d9e-b7f2-9a1dd53964b6/script

Can you please help.


#14

Hi @yograj.patel,

Taking a look at the monitor you linked, it looks like there are a few syntax issues remaining. As Michel mentioned, the runtime environment this monitor is running in does not know es6 arrow function syntax, which my example uses. Runtime is determined both by the monitor API version (indicated in the general settings of the monitor), and if it is being executed on a Private Minion, whether that runtime was available for the minion at the time of build. So you’ll want to refer to his examples above to get those cleaned up.

I did some testing on the script using the correct syntax and the monitor validation received a 405 Method Not Allowed response. This error indicates that the request method is known by the server but is not supported by the target resource.

Without having knowledge of this specific endpoint, it’s hard to say exactly why it’s responding with a 405. Could you confirm that the method you’re attempting is supported by the endpoint?


#15

Hi Chance,

I have checked the API version being used and it is 0.5x and not sure why it is failing. tried different option to just use the 1st step to show the auth token in log. Now need to extract it and pass it as an argument for the next call.

https://synthetics.newrelic.com/accounts/1175115/monitors/a5d01ad7-2d6c-4770-874d-9662e43e0b75


#16

Hi @yograj.patel, I tried creating a new monitor with the same script and it recognised the ES6 arrow functions correctly, so might be worth a try. The only other thing to note is that you are missing a comma in the getToAPI(authKey) function:

'ma_transaction_id':'test1234',

Let me know if that helps :slight_smile: