How to invoke Nodejs lambda from Java based Lambda in AWS - amazon-web-services

I was trying to invoke Nodejs based lambda from Java-Based lambda. It is invoking the lambda but the payload is not being sent to Nodejs based lambda.
Here is the code for both lambdas:
Nodejs based lambda:
module.exports.handler = async (event, context, callback) => {
console.log('event ', event) // Payload not coming here either event or context
console.log('context', context)
const body = JSON.parse(event);
//Processing and return response
}
Java-based lambda:
AWSLambda client = AWSLambdaClient.builder().withRegion(region).build();
InvokeRequest().withFunctionName("nodejslambda").withPayload(payload);
InvokeResult result = client.invoke(req);
Your help would be greatly appricated.

You must provide additional information like
Are you able to see the node function invoked and what is the response body when you call the invoke method.
Check the node lambda logs if you see the function invoked.
Try to test the function on the console by sending the same payload as test.

Related

Trigger a lambda function after a rest api is accessed

I have a rest API in aws api gateway that access's an external http endpoint and returns some data.
Every time this rest api is accessed and returns data, i need to trigger a lambda function that uses the data returned by the rest api. How can i achieve that ?
Tried looking for answers on this and all of them point to how to trigger a lambda function using a rest api.
You can do this in 2 ways.
When a request is sent to api gateway, invoke a lambda, inside this lambda access your external http endpoint and whatever the result comes, invoke another lambda.
something like this.
const invoke = async (funcName, payload) => {
const client = createClientForDefaultRegion(LambdaClient);
const command = new InvokeCommand({
FunctionName: funcName,
Payload: JSON.stringify(payload),
LogType: LogType.Tail,
});
const { Payload, LogResult } = await client.send(command);
const result = Buffer.from(Payload).toString();
const logs = Buffer.from(LogResult, "base64").toString();
return { logs, result };
};
Use stepfunctions with api gateway ( which would be similar to 1st operation)

Issue while Invoking a Lambda function from another Lambda function

I have created a Parent Lambda function from which I am invoking a child Lambda function. I want to invoke the child function asynchronously so I am using Invocation type as 'Event'. I am using API gateway to call the Parent Lambda function. When I try to send a single or 2-3 requests to the API endpoint, I see the logs in the Parent Lambda function only and not in the child lambda function(i.e. it is not able to invoke the child function). It is not able to invoke child function when I hit fewer requests. However if I hit 10-15 requests at a time then it starts reflecting the logs in both parent and child Lambda function. Whereas the ideal behavior should be even if I invoke it once it should reflect in both the function logs.
var AWS = require('aws-sdk');
AWS.config.region = 'us-west-2';
var lambda = new AWS.Lambda();
exports.handler = async (event, context) => {
const function1 = {
FunctionName: 'child_lambda',
InvocationType: 'Event',
Payload: JSON.stringify(event)
};
lambda.invoke(function1).promise();
}
Here I have mentioned the code snippet I am using to invoke the child Lambda function.
What about adding this in the end ?
return await lambda.invoke(function1).promise();

Why lambda does not stop execution

Im building a lambda that calls another lambda in nodejs with aws. The problem is that my lambdas should run synchrony and I cant finish it after I call return callback function. Im using also context.callbackWaitsForEmptyEventLoop == false.
My code gets a list on firebase and executes this list, If lambda timeout reaches 60 secounds or more, it calls another lambda and returns the callback function.
Like that:
return callback(null, {
statusCode: 400,
headers: {'Content-Type': 'text/plain'},
body: JSON.stringify(result)
})
How can I solve this problem?
thanks.
Lambda supports both sync and async invocation type , you can specify invocation type as RequestResponse.
Please refer this documentation

Invoke AWS Lambda and return response to API Gateway asyncronously

My use case is such that I'll have an AWS Lambda front ended with API Gateway.
My requirement is that once the Lambda is invoked it should return a 200 OK response back to API Gateway which get forwards this to the caller.
And then the Lambda should start its actual processing of the payload.
The reason for this is that the API Gateway caller service expects a response within 10 seconds else it times out. So I want to give the response before I start with the processing.
Is this possible?
With API Gateway's "Lambda Function" integration type, you can't do this with a single Lambda function -- that interface is specifically designed to be synchronous. The workaround, if you want to use the Lambda Function integration type is for the synchronous Lambda function, invoked by the gateway, to invoke a second, asynchronous, Lambda function through the Lambda API.
However, asynchronous invocations are possible without the workaround, using an AWS Service Proxy integration instead of a Lambda Function integration.
If your API makes only synchronous calls to Lambda functions in the back end, you should use the Lambda Function integration type. [...]
If your API makes asynchronous calls to Lambda functions, you must use the AWS Service Proxy integration type described in this section. The instructions apply to requests for synchronous Lambda function invocations as well. For the asynchronous invocation, you must explicitly add the X-Amz-Invocation-Type:Event header to the integration request.
http://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-lambda.html
Yes, simply create two Lambda functions. The first Lambda function will be called by the API Gateway and will simply invoke the second Lambda function and then immediately return successfully so that the API Gateway can respond with an HTTP 200 to the client. The second Lambda function will then take as long as long as it needs to complete.
If anyone is interested, here is the code you can use to do the two lambdas approach. The code below is the first lambda that you should setup which would then call the second, longer running, lambda. It takes well under a second to execute.
const Lambda = new (require('aws-sdk')).Lambda();
/**
* Note: Step Functions, which are called out in many answers online, do NOT actually work in this case. The reason
* being that if you use Sequential or even Parallel steps they both require everything to complete before a response
* is sent. That means that this one will execute quickly but Step Functions will still wait on the other one to
* complete, thus defeating the purpose.
*
* #param {Object} event The Event from Lambda
*/
exports.handler = async (event) => {
let params = {
FunctionName: "<YOUR FUNCTION NAME OR ARN>",
InvocationType: "Event", // <--- This is KEY as it tells Lambda to start execution but immediately return / not wait.
Payload: JSON.stringify( event )
};
// we have to wait for it to at least be submitted. Otherwise Lambda runs too fast and will return before
// the Lambda can be submitted to the backend queue for execution
await new Promise((resolve, reject) => {
Lambda.invoke(params, function(err, data) {
if (err) {
reject(err, err.stack);
}
else {
resolve('Lambda invoked: '+data) ;
}
});
});
// Always return 200 not matter what
return {
statusCode : 200,
body: "Event Handled"
};
};
Check the answer here on how to set up an Async Invoke to the Lambda function. This will return 200 immediately to the client, but the Lambda will process on it's own asynchronously.
https://stackoverflow.com/a/40982649/5679071

Invoke multiple aws lambda functions

How can we invoke multiple AWS Lambda functions one after the other ?For example if an AWS Lambda chain consists of 8 separate lambda functions and each simulate a 1 sec processing event and then invoke the next function in the chain.
I wouldn't recommend using direct invoke to launch your functions. Instead you should consider creating an SNS Topic and subscribing your Lambda functions to this topic. Once a message is published to your topic, all functions will fire at the same time. This solution is also easily scalable.
See more information at official documentation Invoking Lambda functions using Amazon SNS notifications
With python:
from boto3 import client as botoClient
import json
lambdas = botoClient("lambda")
def lambda_handler(event, context):
response1 = lambdas.invoke(FunctionName="myLambda1", InvocationType="RequestResponse", Payload=json.dumps(event));
response2 = lambdas.invoke(FunctionName="myLambda2", InvocationType="RequestResponse", Payload=json.dumps(event));
A simple way to do it is to use the AWS sdk to invoke the lambda function.
The solution would look different depending on what sdk you use. If using the Node sdk I would suggest promisifying the sdk with a Promise library like for example Bluebird.
The code would look something like:
const Promise = require('bluebird');
const AWS = require('aws-sdk');
const lambda = Promise.promisifyAll(new AWS.Lambda({ apiVersion: '2015-03-31' }));
lambda.invokeAsync({FunctionName: 'FirstLambdaFunction'})
.then(() => {
// handle successful response from first lambda
return lambda.invokeAsync({FunctionName: 'SecondLambdaFunction'});
})
.then(() => lambda.invokeAsync({FunctionName: 'ThirdLambdaFunction'}))
.catch(err => {
// Handle error response
);
The reason why I like this approach is that you own the context of all the lambdas and can decide to do whatever you like with the different responses.
Just call the next Lambda function at the end of each function?
Use http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda_20141111.html#invokeAsync-property if you are using Node.js/JavaScript.