I'm working with serverless, porting two functions, one (call it generator) that is currently a long-running node process and the other (call it checker) triggered by cron, so that they both would be lambdas, checker triggered by a schedule, and generator by receiving an SQS notification. I'm also a big fan of being able to do local dev, so added serverless-offline and serverless-offline-sqs (backed by ElasticMQ).
Ported the generator, and it deploys and runs just fine locally. Here's the function as defined in serverless.yml:
reportGenerator:
handler: src/reportGenerator.handleReportRequest
events:
- sqs:
arn:
Fn::GetAtt:
- ReportRequestQueue
- Arn
I can use the AWS CLI to trigger messages through ElasticMQ (aws account # obfuscated):
$ aws sqs send-message --queue-url https://sqs.us-west-1.amazonaws.com/000000000000/local-report-request --message-body file://./test/reportGenerator/simple_payload.json --endpoint-url http://localhost:9324
{
"MD5OfMessageBody": "267bd9129a76e3f48c26903664824c13",
"MessageId": "12034cd8-3783-403a-92eb-a5935c8759ae"
}
$
And the message is received fine, the generator lambda triggers:
{
"requestId": "ckokpja2e0001nbyocufzdrxk",
"function": "src/reportGenerator.js::exports:14",
"level": "info",
"message": "Found 0 waiting report request(s)"
}
offline: (λ: reportGenerator) RequestId: ckokpja2e0001nbyocufzdrxk Duration: 214.53 ms Billed Duration: 215 ms
Now I want to do that SQS send programmatically for the second function, which is pretty much the only real change to that existing (non-lambda) function. It is also deployed/launched just fine, but the aws-sdk library function to send the same message isn't working.
Here's the function definition in serverless.yml. Note that I commented out the normal cron schedule, since that isn't supported by serverless-offline, and just used the 10 minute rate for testing:
reportChecker:
handler: src/reportScheduler.check
environment:
REPORT_REQUEST_QUEUE_URL: "https://sqs.us-west-1.amazonaws.com/${self:custom.awsAccountId}/${opt:stage, self:custom.defaultStage}-report-request"
events:
# note that cron does not work for offline. Comment these out, and uncomment the rate to test locally
# - schedule:
# rate: cron(0 11 ? * 3 *)
# input:
# reportType: weekly
# - schedule:
# rate: cron(0 11 2 * ? *)
# input:
# reportType: monthly
- schedule:
rate: rate(10 minutes)
input:
reportType: weekly
Here's what I added to the rest of the function as the node version of the above command line:
const AWS = require('aws-sdk');
AWS.config.update({region: process.env.AWS_REGION});
...
try {
const sqs = new AWS.SQS({endpoint: 'http://localhost:9324'});
logger.debug('SQS info', {queueUrl: process.env.REPORT_REQUEST_QUEUE_URL, endpoint: sqs.endpoint});
await sqs.sendMessage({
QueueUrl: process.env.REPORT_REQUEST_QUEUE_URL,
MessageBody: `{"reportType":${checkType}}`
})
.promise();
}
catch(err) {
logger.error('SQS failed to send', {error: err});
}
The output from those logger statements is
{
"requestId": "ckokpulxw0002nbyo19sj87g2",
"function": "src/reportScheduler.js::exports:100",
"data": {
"queueUrl": "https://sqs.us-west-1.amazonaws.com/000000000000/local-report-request",
"endpoint": {
"protocol": "http:",
"host": "localhost:9324",
"port": 9324,
"hostname": "localhost",
"pathname": "/",
"path": "/",
"href": "http://localhost:9324/"
}
},
"level": "debug",
"message": "SQS info"
}
{
"requestId": "ckokpulxw0002nbyo19sj87g2",
"function": "src/reportScheduler.js::exports:109",
"data": {
"error": {
"message": "The specified queue does not exist for this wsdl version.",
"code": "AWS.SimpleQueueService.NonExistentQueue",
"time": "2021-05-12T00:20:00.497Z",
"requestId": "e55124c3-248e-5afd-acce-7dd605fe1fe5",
"statusCode": 400,
"retryable": false,
"retryDelay": 95.52839314049268
}
},
"level": "error",
"message": "SQS failed to send"
}
offline: (λ: reportChecker) RequestId: ckokpulxw0002nbyo19sj87g2 Duration: 477.95 ms Billed Duration: 478 ms
It sure looks to me like the code is using all the same values as the command line, but it just isn't working. Hoping someone else can see something obvious here.
Thanks.
Shouldn't the env variable REPORT_REQUEST_QUEUE_URL locally point to ElasticMQ? E.g. http://0.0.0.0:9324/queue/local-report-request.