7

I am new to AWS lambda I have created a lambda function with handler

example.Orders::orderHandler

And this is the custom handler, now I want to invoke this from my Java program how do I need to this.

6 Answers 6

11

The 2 methods in this class should be able to help you. One is for if you need to pass in a payload, the other if the payload is null.

However, you need to bear one thing in mind: the function name may not be the same as the handler (the latter here is example.Orders::orderHandler). The handler name is not used when invoking its function.

So, if you have a function with the function name 'myFunction' that behind the scenes call your example.Orders::orderHandler handler, then this is what you would pass into the run methods below.

import com.amazonaws.regions.Regions;
import com.amazonaws.services.lambda.AWSLambdaAsyncClient;
import com.amazonaws.services.lambda.model.InvokeRequest;
import com.amazonaws.services.lambda.model.InvokeResult;

class LambdaInvoker {

    public void runWithoutPayload(String region, String functionName) {
        runWithPayload(region, functionName, null);
    }

    public void runWithPayload(String region, String functionName, String payload) {
        AWSLambdaAsyncClient client = new AWSLambdaAsyncClient();
        client.withRegion(Regions.fromName(region));

        InvokeRequest request = new InvokeRequest();
        request.withFunctionName(functionName).withPayload(payload);
        InvokeResult invoke = client.invoke(request);
        System.out.println("Result invoking " + functionName + ": " + invoke);
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

What if the payload is a complex java object? Do we convert that to a json string??
This approach makes use of several deprecated functions.
deprecated? like which ones?
9

Use this LATEST code to invoke a Lambda Function Synchronously:

    final String AWS_ACCESS_KEY_ID = "xx";
    final String AWS_SECRET_ACCESS_KEY = "xx";

    AWSCredentials credentials = new BasicAWSCredentials(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY);

    // ARN
    String functionName = "XXXX";

    //This will convert object to JSON String
    String inputJSON = new Gson().toJson(userActivity);

    InvokeRequest lmbRequest = new InvokeRequest()
            .withFunctionName(functionName)
            .withPayload(inputJSON);

    lmbRequest.setInvocationType(InvocationType.RequestResponse);

    AWSLambda lambda = AWSLambdaClientBuilder.standard()
            .withRegion(Regions.US_EAST_1)
            .withCredentials(new AWSStaticCredentialsProvider(credentials)).build();

    InvokeResult lmbResult = lambda.invoke(lmbRequest);

    String resultJSON = new String(lmbResult.getPayload().array(), Charset.forName("UTF-8"));

    System.out.println(resultJSON);

Use these dependencies to avoid any errors:

    <dependency>
        <groupId>org.codehaus.janino</groupId>
        <artifactId>janino</artifactId>
        <version>2.6.1</version>
    </dependency>

    //Required by BeanstalkDeploy.groovy at runtime
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.2</version>
        <scope>runtime</scope>
    </dependency>

    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-lambda</artifactId>
        <version>1.11.207</version>
    </dependency>

Comments

3

As a sidenote, when creating an AWS Lambda Java project in Eclipse, one must also add

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-lambda</artifactId>
    <version>1.11.411</version>
</dependency>

to the pom.xml otherwise these imports will fail:

import com.amazonaws.services.lambda.AWSLambdaAsyncClient;
import com.amazonaws.services.lambda.model.InvokeRequest;
import com.amazonaws.services.lambda.model.InvokeResult;

Comments

2

You define the handler when you deploy the Lambda function. Only the AWS Lambda service needs to know what your custom handler is. So the handler has no relevance in the Java code that is invoking the function. Anything invoking the Lambda function only needs to know the Lambda function name, not the handler name.

In Java you would invoke the Lambda function via the AWSLambdaClient.invoke() method documented here.

Comments

2

I followed the following code and just printed the response from the Lambda

AWSLambdaAsyncClient lambdaClient = new AWSLambdaAsyncClient();
    lambdaClient.withRegion(Region.getRegion(Regions.US_WEST_2));
    InvokeRequest invokeRequest = new InvokeRequest();
    invokeRequest.setInvocationType("RequestResponse"); // ENUM RequestResponse or Event
    invokeRequest.withFunctionName("FUNCTION NAME").withPayload(payload);
    InvokeResult invoke = lambdaClient.invoke(invokeRequest);
    try {
        // PRINT THE RESPONSE
        String val = new String(invoke.getPayload().array(), "UTF-8");
        System.out.println("Response==> " + val);
    } catch (Exception e) {
        System.out.println("error");
    }

Comments

1

AWS often updates its implementation. For anyone wanting/using the latest (2022) SDK you can use the following.

Add

 <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>lambda</artifactId>
            <version>2.17.293</version>
</dependency>

Then you can just configure your bean.

    @Bean
    public LambdaClient lambdaClient() {
        AwsCredentials credentials = AwsBasicCredentials.create("secretKey", "AccessKey");
        return LambdaClient
                .builder()
                .region(Region.AF_SOUTH_1)
                .credentialsProvider(StaticCredentialsProvider.create(credentials))
                .build();
    }

Then calling can consuming it basically stayed the same but in a nutshell.

 @Autowired
 LambdaClient lambdaClient;


public String invokeFunction(Object requestPayload) {

        InvokeResponse res = null;
        try {
            ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
            String json = ow.writeValueAsString(requestPayload);
            SdkBytes payload = SdkBytes.fromUtf8String(json);

            // Setup an InvokeRequest.
            InvokeRequest request = InvokeRequest.builder()
                    .functionName("your lambda arn goes here")
                    .payload(payload)
                    .build();

            res = lambdaClient.invoke(request);
            return res.payload().asUtf8String();

        } catch (LambdaException e) {
            log.error(e.getMessage());

        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        throw new IllegalStateException("Lambda response is null");
    }

Also important to note, the user you are executing with requires the correct permissions to execute a lambda.

You can just use the Predefined policies and attached them to the calling user. In IAM in the Aws Console the policy name is "AWSLambdaRole"

1 Comment

This above answer is very useful. Thank you very much

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.