I have a API canary setup for testing the availability of APIs. The statusCode of the API is tracked in cloudwatch logs. I am fetching files from S3. Those requests are coming with 200 statusCode as the same available in cloudwatch Logs. But in case of my API testing, in cloudwatch logs the statuscode prints as 200. But in Canary page it comes as failed. Please find the attached canary page image
The first two request are S3 requests, others are my API requests.
Also I attached the cloudwatch logs screenshot
And my API canary script is,
var synthetics = require('Synthetics');
const log = require('SyntheticsLogger');
const https = require('https');
const http = require('http');
const syntheticsConfiguration = synthetics.getConfiguration();
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const apiCanaryBlueprint = async function () {
const verifyRequest = async function (res) {
return new Promise((resolve, reject) => {
log.info("status: " res.statusCode ' ' res);
if (res.statusCode !== 200 && res.statusCode !== 201) {
log.info("Failed: " res.statusCode ' ' res.statusMessage);
throw res.statusCode ' ' res.statusMessage;
}
let responseBody = '';
res.on('data', (d) => {
responseBody = d;
responseBody = d; // tried in this way as well
log.info("Response2: " responseBody);
resolve();
});
res.on('end', () => {
resolve();
});
});
}
const getS3Certificate = async function (){
const certificate = {
Bucket : 'bucket',
Key : 'key',
};
const certificates3 = await s3.getObject(certificate).promise()
return certificates3.Body;
}
const getS3Key = async function(){
const key = {
Bucket : 'bucket',
Key : 'key',
};
const keys3 = await s3.getObject(key).promise()
return keys3.Body;
}
const S3Certificate = await getS3Certificate()
const S3Key = await getS3Key()
let projectId = Math.floor(Math.random()*1E16);
let applicationID = Math.floor(Math.random()*1E16);
projectId = projectId.toString().match(/.{1,4}/g).join('-');
let subscribedCount = Math.round(Math.random()*1E4);
let requestData = [
{
hostname: 'hostname.com',
method: 'get',
path: `/api/v1.0/project/123`,
port: 443,
protocol: 'https:',
key:S3Key,
cert:S3Certificate,
headers:{"header1":"a"}
},
{
hostname: 'hostname.com',
method: 'POST',
path: `/api/v1.0/project/${projectId}`,
port: 443,
key:S3Key,
cert:S3Certificate,
headers:{"header1":"a"},
body:JSON.stringify({ "isActive": true, "licenseItems": [...licenseItemsDetails] })
},
{
hostname: 'hostname.com',
method: 'PUT',
path: '/api/v1.0/project/canary/licenses',
port: 443,
key:S3Key,
cert:S3Certificate,
headers:{"header1":"a"},
body:JSON.stringify({"licenseItems": [...licenseItemsDetails]})
},
{
hostname: 'hostname.com',
method: 'DELETE',
path: '/api/v1.0/project/canary/canaryapp_001',
port: 443,
key:S3Key,
cert:S3Certificate,
headers:{"header1":"a"}
},
{
hostname: 'hostname.com',
method: 'PUT',
path: '/api/v1.0/project/canary/state',
port: 443,
key:S3Key,
cert:S3Certificate,
headers:{"header1":"a"},
body:JSON.stringify({"isActive": true})
},
{
hostname: 'hostname.com',
method: 'DELETE',
path: `/api/v1.0/project/${projectId}`,
port: 443,
key:S3key,
cert:S3Cert,
headers:{"header1":"a"}
},
]
requestData.forEach(async (request) => {
request['headers']['User-Agent'] = [synthetics.getCanaryUserAgentString(), request['headers']['User-Agent']].join(' ');
// await verifyRequest(request);
let stepConfig = {
includeRequestHeaders: true,
includeResponseHeaders: true,
restrictedHeaders: ['X-Amz-Security-Token', 'Authorization'],
includeRequestBody: true,
includeResponseBody: true
};
await synthetics.executeHttpStep('Verify LMS APIs', request, verifyRequest, stepConfig);
})
};
exports.handler = async () => {
return await apiCanaryBlueprint();
};
CodePudding user response:
In the verifyRequest method, the request data is sent in an array to the method. This is causing a problem. Even though I put await on every call, I am not getting expected data(responseBody becomes empty string) on res.on('end' => {callback})
So I changed my code with separate request and separate await function, this fixed the problem.
let requestOptionsStep8 = {
hostname: 'hostname.com',
method: 'DELETE',
path: `/api/v1.0/project/projectId`,
port: 443,
key:key,
cert:cert,
headers:{'Content-Type':'application/json','ALE-LMS-Operation-Id':'a','Accept':'*/*'}
}
let requestOptionsStep9 = {
hostname: 'hostname.com',
method: 'PATCH',
path: `/api/v1.0/project/canary3/canary1`,
port: 443,
key:key,
cert:cert,
headers:{'Content-Type':'application/json','ALE-LMS-Operation-Id':'a','Accept':'*/*'},
body:JSON.stringify({JSON body})
}
requestOptionsStep['headers']['User-Agent'] =
[synthetics.getCanaryUserAgentString(), requestOptionsStep['headers']['User-Agent']].join(' ');
requestOptionsStep1['headers']['User-Agent'] =
[synthetics.getCanaryUserAgentString(), requestOptionsStep1['headers']['User-Agent']].join(' ');
let stepConfig1 = {
includeRequestHeaders: true,
includeResponseHeaders: true,
includeRequestBody: true,
includeResponseBody: true,
continueOnHttpStepFailure: true
};
await synthetics.executeHttpStep('Verify hostname.com', requestOptionsStep, validateSuccessful, stepConfig1);
await synthetics.executeHttpStep('Verify hostname.com', requestOptionsStep1, validateSuccessful, stepConfig1);