AWS Lambda: Как вызвать лямбда-функцию из простого класса java

Я создал простую функцию лямбда и upload для AWS Lambda.

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

public class Hello implements RequestHandler<String, String> {

    @Override
    public String handleRequest(String input, Context context) {
         String output = "Bonjour, " + input + "!";
         return output;
    }

}

}

Я хочу вызвать эту функцию Lambda из другого проекта, используя класс java. Я использую aws-java-sdk-lambda-1.10.22 для вызова функции. Но я не в состоянии преуспеть в этом.

Вот мой класс InvokeLambda, который является отдельным проектом.

import java.nio.ByteBuffer;
import java.nio.charset.Charset;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.lambda.AWSLambdaClient;
import com.amazonaws.services.lambda.model.InvokeRequest;

public class InvokeLambda {
    private static final Log logger = LogFactory.getLog(InvokeLambda.class);
    private static final String awsAccessKeyId = "XXXXXX";
    private static final String awsSecretAccessKey = "YYYY";
    private static final String regionName = "us-west-2";
    private static final String functionName = "Hello";
    private static Region region;
    private static AWSCredentials credentials;
    private static AWSLambdaClient lambdaClient;

    /**
     * The entry point into the AWS lambda function.
     */
    public static void main(String... args) {
        credentials = new BasicAWSCredentials(awsAccessKeyId,
                awsSecretAccessKey);

        lambdaClient = (credentials == null) ? new AWSLambdaClient()
                : new AWSLambdaClient(credentials);
        //lambdaClient.configureRegion(Regions.US_WEST_2);
        region = Region.getRegion(Regions.fromName(regionName));
        lambdaClient.setRegion(region);

        try {
            InvokeRequest invokeRequest = new InvokeRequest();
            invokeRequest.setFunctionName(functionName);
            invokeRequest.setPayload("\" AWS Lambda\"");
            System.out.println(byteBufferToString(
                    lambdaClient.invoke(invokeRequest).getPayload(),
                    Charset.forName("UTF-8")));
        } catch (Exception e) {
            logger.error(e.getMessage());
            // System.out.println(e.getMessage());

        }
    }

    public static String byteBufferToString(ByteBuffer buffer, Charset charset) {
        byte[] bytes;
        if (buffer.hasArray()) {
            bytes = buffer.array();
        } else {
            bytes = new byte[buffer.remaining()];
            buffer.get(bytes);
        }
        return new String(bytes, charset);
    }
}

Как вызвать функцию лямбда с помощью java?

Ответ 1

Учитывая информацию в вашем комментарии, ваш клиентский код для вызова функции в порядке. Проблема, похоже, связана с конфигурацией самой функции. В частности, AWS Lambda не может найти обработчик, который вы указали (com.aws.HelloLambda::handleRequest), потому что это не соответствует имени и пакету вашего класса обработчика (Hello) и имени вашего метода в этом классе (handleRequest).

Вы можете обновить имя обработчика функции через консоль AWS. Выберите свою функцию, затем вкладку конфигурации, а затем свойство Handler.

Вероятно, вы захотите изменить его с com.aws.HelloLambda::handleRequest на Hello::handleRequest.

пример того, как обновлять имя обработчика в консоли

Перед тестированием функции с вашего Java-клиента вы можете протестировать ее непосредственно через консоль, это поможет вам правильно настроить функцию.

Ответ 2

Другой способ вызвать lambda из java-кода - использовать LambdaInvokerFactory, и я нашел этот подход более чистым. Вам необходимо сделать следующее:

  • Определите интерфейс, представляющий вашу функцию и метод аннотации с помощью @LambdaFunction
  • Создайте реализацию вышеуказанного интерфейса с помощью LambdaInvokerFactory
  • Вызвать лямбда-функцию с помощью только что созданного прокси-объекта (реализация интерфейса)

    Более подробный пример можно найти здесь.