I have created a FIFO SQS queue.
When sending a message to the queue using the below params,
var params= {
MessageBody: payload,
QueueUrl: sqsURL + body.device + ".fifo"
}
sqs.sendMessage(params, function(err, res) {
err ? callback(err) : callback(null, res);
});
I get a warning that says "missing parameter messagegroupid"
I then proceed to add in MessageGroupId into my params.
var params= {
MessageBody: payload,
MessageGroupId: "posts",
QueueUrl: sqsURL + body.device + ".fifo"
}
sqs.sendMessage(params, function(err, res) {
err ? callback(err) : callback(null, res);
});
SQS then throws me "UnexpectedParameter: Unexpected key 'MessageGroupId' found in params".
Am confused by this set of conflicting instructions.
I'm using the same SDK region in both my createQueue and sendMessage command.
var sqs= new aws.SQS({ region: "us-east-2" });
I ran into this same error using Lambda (hence finding your post). Wondering if they forgot to refresh the native SDK, I uploaded the latest version of the SDK(2.7.7) with my function and the error went away.
Since uploading the SDK removes the ability to edit in Lambda, I then deleted it and re-uploaded the function the error came back :(.
So for now, if you want to use it with Lambda, you have to include the SDK with your deployment package.
You've missed passing "MessageGroupId" parameter. You should pass Message group id as a parameter. It is mandatory for FIFO.
Please refer the below-mentioned link,
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sqs-2012-11-05.html#sendmessage
Related
On Cloudwatch I'm having an error that says:
HTTP/1.1" 500 35 ZHTFXgWBoAYEQ4a= The Lambda function returned the following error: "Unhandled". Check your Lambda function code and try again.
I'm trying to build the new HTTP API Gateway with a simple lambda function.
This is my lambda function:
const AWS = require("aws-sdk");
const dynamodb = new AWS.DynamoDB({
region: "us-east-1",
apiVersion: "2012-08-10"
});
exports.handler = (event, context, callback) => {
const params = {
Key: {
id: {
S: event.id
}
},
TableName: "todos"
};
dynamodb.getItem(params, (err, data) => {
if (err) {
console.log(err);
callback(err);
} else {
callback(null, {
id: data.Item.id.S,
title: data.Item.title.S,
watchHref: data.Item.watchHref.S,
authorId: data.Item.authorId.S,
length: data.Item.length.S,
category: data.Item.category.S
});
}
});
};
This is how the data is structured:
This is how I'm invoking it and the JSON response I get:
What am I doing wrong?
EDIT:
Here's a more detailed log:
"ValidationException: Supplied AttributeValue is empty, must contain exactly one of the supported datatypes",
But I'm giving it the right values, or not?
The detailed error log you found points to a validation error. This means that in your request to Dynamo, the object you're using (params) is invalid. The shape looks correct according to the docs, so it must mean that your event.id is an empty string or null when it hits your function. You're sending the ID from Postman as a query parameter, are you mapping it somewhere else? If not you'll want to use event.queryStringParameters.id and the proxy integration as explained here.
Lambda response should be of specific format for API Gateway to recognize and respond correctly
Actual Api Response should be converted to String and passed to body.
Entire JSON with statusCode, body, headers, isBase64Encoded should be pass as response from Lambda.
For success callback(null, responseObject)
For Failures callback(responseObject)
here is an example of responseObject:
{
"statusCode": 200,
"body": "{\"id\":\"1\",\"title\":\"My Title\"}",
"isBase64Encoded": false,
"headers": {
"Content-Type": "application/json"
}
}
I have a SeedIndicatorInformationSQS-dev.fifo queue (FiFo) that connects to a SeedIndicatorInformationSQS-dev-d13dfe0 lambda. I'd like to send a message within the SeedIndicatorInformationSQS-dev-d13dfe0 lambda to the EvaluationConfigSQS-dev standard queue. But no messages are being sent/received. Whereas if I try sending it from a non-SQS connected lambda (via AppSync) it works.
The SeedIndicatorInformationSQS-dev-d13dfe0 lambda has the following permissions:
I have checked:
That the lambda has the right access to send SQS messages (you can see it there).
That the EvaluationConfigSQS-devstandard queue is correctly configured as I've successfully sent messages to it from another lambda (non-SQS).
That the SQS URL is correct.
That no errors are shown in the console.
That async/await are correctly placed (I've tried both with and without them)
Here's the CloudWatch log for the SeedIndicatorInformationSQS-dev-d13dfe0lambda trying to dispatch the content: Successfully sent to the right URL, JSON parsed to string, but nothing.
Here's the CloudWatch Log: You can see. SeedIndicatorInformationSQS-dev-d13dfe0 successfully receives the message from another lambda function and processes it, but no further messages are sent.
No errors reported within SeedIndicatorInformationSQS-dev-d13dfe0
No logs within EvaluationConfigSQS-dev
But, if I try to send it within a non-SQS lambda, it works.
Received event:
This is the classes-dev-eefa2af lambda that sends successfully to EvaluationConfigSQS-dev (and coincidentally is the one which triggers the SeedIndicatorInfromationSQS-dev.fifo SQS.
Here are the permissions for EvaluationConfigSQS-dev-6da8b90 (lambda that the EvaluationConfigSQS-dev standard queue triggers)
By any chance, do I need to add special permissions to the SeedIndicatorInformatioNSQS-dev.fifo queue?
Here's the JS that gets dispatched (I'm using a mediator pattern, and it's successfully getting dispatched, you can see it in the logs above "Dispatching CREATED_INSTITUTION_CLASS". I have also managed to print the URL and verified that it's actually the one that corresponds to it.
export async function institutionClassCreatedEventHandler(
evt: InstitutionClassCreatedEvent
) {
const json = JSON.stringify({
...evt,
type: "CLASS_CREATED",
});
sqsDispatchMessage(
"InstitutionClassCreatedEvent",
evt.tenantId + evt.subject.id,
json,
Config.SQS.evaluationConfigSQS.url,
false
);
}
Here's the sqsDispatchMessage function. As you can see, there's a catch block that will print me whenever there's an error (and it works). But so far, no error has been recorded.
export async function sqsDispatchMessage(
eventName: string,
uniqueId: string,
jsonObjStringifiedToSend: string,
sqsURL: string,
isFifoQueue: boolean = true
) {
try {
await sqs
.sendMessage({
MessageAttributes: {
EventName: {
DataType: "String",
StringValue: eventName,
},
},
...(isFifoQueue && { MessageGroupId: eventName }),
MessageBody: jsonObjStringifiedToSend,
QueueUrl: sqsURL,
...(isFifoQueue && { MessageDeduplicationId: uniqueId }),
})
.promise();
} catch (e) {
console.error(`Error While Sending the ${eventName}`);
console.error(e.message);
console.log(jsonObjStringifiedToSend);
}
}
Any ideas? Is it even possible?
The problem was in my dispatcher:
It used to be like this:
export async function dispatchOfEvents({
type,
evtArgs,
}: MediatorEvents): Promise<void> {
logTime(type);
(events as any)[type].forEach((evt: Function) => {
evt(evtArgs);
});
}
I changed it to:
export async function dispatchOfEvents({
type,
evtArgs,
}: MediatorEvents): Promise<void> {
logTime(type);
const evts: Promise<any>[] = [];
for (const evt of (events as any)[type]) {
evts.push(evt(evtArgs));
}
await Promise.all(evts);
}
I am using AWS Websocket api-gateway. I am sending message to connected client by aws:execute-api:region:account-id:api-id/stage-name/POST/#connections.However, the message is getting delayed somehow and the UI won't be able to receive the chat message immediately. I don't why any suggestion where getting something wrong????
One thing very exceptional, when I am sending message, last message getting time.
Example : If I sent one message that take much time. If I send 1st message, as I sent second message, First message will received to client immediately but now 2nd second message take much time. SO basically when I am sending nth message, then every nth message will deliver to client when (n+1)th message sent and (n+1)th messages takes much time to deliver.
Your help much appreciated!!!
This is only Code Snippet which I have
import * as AWS from 'aws-sdk';
export class AWSWebsocketGateway {
websocketInstance;
constructor() {
AWS.config.update({
accessKeyId: <accessKeyId>,
secretAccessKey: <secretAccessKey>,
region: <region>
});
this.websocketInstance = new AWS.ApiGatewayManagementApi({
endpoint: <webSocketDomainName> + <webSocketStage>
});
}
sendMessage(connection, messageObject, callback: Function) {
messageObject = JSON.stringify(messageObject);
this.websocketInstance.postToConnection({ ConnectionId: connection, Data: JSON.stringify(messageObject) }, function (error, data) {
console.log('Error', error, 'Send Message...', data);
return callback(error, data);
});
}
}
I retrieving connection Id from DB in one query and calling this function in loop to send message.
For anyone else who get's bitten by this one ->
You need to wait for the API call to return it's result before finishing the lambda's execution.
E.g. this won't work
module.exports.ping = async (event) => {
... //setting up api gateway, etc
apig.postToConnection({ ConnectionId: connectionId, Data: JSON.stringify(message) }, (err, res) => {})
return {
statusCode: 200
}
}
But this will:
module.exports.ping = async (event) => {
... //setting up api gateway, etc
await apig.postToConnection({ ConnectionId: connectionId, Data: JSON.stringify(message) }).promise();
return {
statusCode: 200
}
}
Any async code that is executing after the return of the lambda appears to be paused til that handler is run again, which is why you see the delayed n+ issue you outlined above.
I just created this function in AWS Lambda to start multiple instances. However when i run the test, it only starts one of the instances instead all the instances in the array. Is this a problem with how i have my array defined in the function? Lambda did not throw a json error so i assumed all was well. I am using the Node.js 4.3 runtime format.
var AWS = require('aws-sdk');
exports.handler = function(event, context) {
var ec2 = new AWS.EC2({region: 'us-west-1'});
ec2.startInstances({InstanceIds : (['i-a11111'],['i-a22222'],['i-a33333'],['i-a44444']) },function (err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
context.done(err,data);
});
};
From the AWS JavaScript SDK documentation, the InstanceIds parameter is supposed to be an array of strings:
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/EC2.html#startInstances-property
This should be the correct format:
{ InstanceIds : ['i-a11111','i-a22222','i-a33333','i-a44444'] }
When attempting to send a message to sqs I get a missing config credentials warning. If switch to just displaying my accesskey and password I can send the message to sqs just fine. I've included the code I'm using and the errors I get from the browser below.
Code below:
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'xxxxxx',
});
var params = {
MessageBody: 'some random message',
QueueUrl: 'xxxxxx'
};
AWS.config.credentials.get(function(err) {
if (err) console.log(err);
else console.log(AWS.config.credentials);
});
var sqs = new AWS.SQS();
sqs.sendMessage(params, function (err, data) {
if (!err) {
console.log('Message sent.');
} else {
console.log(err);
}
});
Errors from console.log:
Error: Missing region in config
at null. (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:5:10470)
at r.SequentialExecutor.r.util.inherit.callListeners (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:6:27635)
at r.SequentialExecutor.r.util.inherit.emit (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:6:27431)
at n.Request.o.emitEvent (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:6:15837)
at e (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:6:12148)
at r.runTo (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:7:23197)
at n.Request.o.runTo (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:6:13657)
at n.Request.o.send (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:6:13550)
at t.Service.i.makeUnauthenticatedRequest (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:6:30572)
at t.util.update.getId (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:7:2224)
index.html:57 Error: Missing credentials in config
at null. (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:5:10470)
at r.SequentialExecutor.r.util.inherit.callListeners (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:6:27635)
at r.SequentialExecutor.r.util.inherit.emit (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:6:27431)
at n.Request.o.emitEvent (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:6:15837)
at e (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:6:12148)
at r.runTo (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:7:23197)
at n.Request.o.runTo (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:6:13657)
at n.Request.o.send (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:6:13550)
at t.Service.i.makeUnauthenticatedRequest (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:6:30572)
at t.util.update.getId (https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js:7:2224)
Take note that I've tried adding region various different ways.
I don't see anything in your posted code that sets the region.
[Following copied from the Configuring the SDK in Node.js documentation]
The AWS SDK for Node.js doesn't select the region by default. You can choose a region similarly to setting credentials by either loading from disk or using AWS.config.update():
AWS.config.update({region: 'us-west-1'});