Вызвать лямбда-обработчик функции Java - PullRequest
0 голосов
/ 25 октября 2019

У меня есть лямбда-функция, у которой есть обработчик, который имеет несколько маршрутизаторов. Каждый маршрутизатор соответствует API.

Я создал лямбда-клиент в Java и должен вызвать эти API. Чтобы вызвать эти API, мне нужно вызвать обработчик и передать полезную нагрузку клиенту вместе с ним. Ребята, можете ли вы помочь мне с синтаксисом для вызова обработчика и передачи полезной нагрузки.

1 Ответ

0 голосов
/ 04 ноября 2019

Если я правильно понимаю ваш вопрос, я сначала создал лямбду, которая выглядела как:

public class SampleHandler implements RequestStreamHandler {
    private static final Logger logger = LogManager.getLogger(SampleHandler.class);

    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        logger.info("handlingRequest");
        LambdaLogger lambdaLogger = context.getLogger();

        ObjectMapper objectMapper = new ObjectMapper();
        String inputString = new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.joining("\n"));
        JsonNode jsonNode = objectMapper.readTree(inputString);

        String route = jsonNode.get("route").asText();

        RouterResult routerResult = new RouterResult();

        switch( route ) {
            case "requestTypeA":
                RequestTypeA requestTypeA = objectMapper.readValue(inputString, RequestTypeA.class);
                routerResult.setResult(handleRequestTypeA(requestTypeA));
                break;

            case "requestTypeB":
                RequestTypeB requestTypeB = objectMapper.readValue(inputString, RequestTypeB.class);
                routerResult.setResult(handleRequestTypeB(requestTypeB));
                break;

            default:
                logger.error( "don't know how to handle route of type \"" + route + "\n" );
                routerResult.setResult("error");
        }

        outputStream.write(objectMapper.writeValueAsString(routerResult).getBytes(StandardCharsets.UTF_8));

       logger.info("done with run, remaining time in ms is " + context.getRemainingTimeInMillis() );
    }


    private String handleRequestTypeA(RequestTypeA requestTypeA) {
        logger.info("handling requestTypeA, requestTypeA.requestA is " + requestTypeA.getRequestA() );

        return "handled requestTypeA";
    }

    private String handleRequestTypeB(RequestTypeB requestTypeB) {
        logger.info("handling requestTypeB, requestTypeB.requestB is " + requestTypeB.getRequestB() );

         return "handled requestTypeB";
    }
}

с RouterRequest.java:

public class RouterRequest {
    protected String route;

    public String getRoute() {
        return route;
    }
}

и RequestTypeA.java:

public class RequestTypeA extends RouterRequest {
    private String requestA;

    public RequestTypeA() {
        route = "requestTypeA";
    }

    public String getRequestA() {
        return requestA;
    }

    public void setRequestA(String requestA) {
        this.requestA = requestA;
    }
}

и RequestTypeB.java

public class RequestTypeB extends RouterRequest {
    private String requestB;

    public RequestTypeB() {
        route = "requestTypeB";
    }

    public String getRequestB() {
        return requestB;
    }

    public void setRequestB(String requestB) {
        this.requestB = requestB;
    }
}

И класс результата, RouterResult.java:

public class RouterResult {
    private String result;

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    @Override
    public String toString() {
        return "RouterResult{" +
                "result='" + result + '\'' +
                '}';
    }
}

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

public class RouterRunner {
    private static final String AWS_ACCESS_KEY_ID = "<access key>";
    private static final String AWS_SECRET_ACCESS_KEY = "<access secret>";

    public static void main( String[] argv ) throws IOException {
        AWSCredentials credentials = new BasicAWSCredentials( AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY );
        AWSLambda lambda = AWSLambdaClientBuilder.standard()
                .withRegion(Regions.US_WEST_2)
                .withCredentials(new AWSStaticCredentialsProvider(credentials)).build();

        RequestTypeA requestTypeA = new RequestTypeA();
        requestTypeA.setRequestA("set from the runner, request type A");

        ObjectMapper objectMapper = new ObjectMapper();

        InvokeRequest invokeRequest = new InvokeRequest()
                .withFunctionName("lambda-router")
                .withPayload(objectMapper.writeValueAsString(requestTypeA));

        invokeRequest.setInvocationType(InvocationType.RequestResponse);

        InvokeResult invokeResult = lambda.invoke(invokeRequest);

        String resultJSON = new String(invokeResult.getPayload().array(), StandardCharsets.UTF_8);

        System.out.println( "result from lambda is " + resultJSON );

        RouterResult routerResult = objectMapper.readValue(resultJSON, RouterResult.class);

        System.out.println( "result.toString is " + routerResult.toString() );


        RequestTypeB requestTypeB = new RequestTypeB();
        requestTypeB.setRequestB("set from the runner, request type B");

        invokeRequest = new InvokeRequest()
                .withFunctionName("lambda-router")
                .withPayload(objectMapper.writeValueAsString(requestTypeB));

        invokeRequest.setInvocationType(InvocationType.RequestResponse);

        invokeResult = lambda.invoke(invokeRequest);

        resultJSON = new String(invokeResult.getPayload().array(), StandardCharsets.UTF_8);

        System.out.println( "result from lambda is " + resultJSON );

        routerResult = objectMapper.readValue(resultJSON, RouterResult.class);

        System.out.println( "result.toString is " + routerResult.toString() );
    }
}

Вероятно, необходимо улучшить обработку ошибок, и я уверен, что вы могли бы сделать это немного более эффективным. Но это общая идея. В конечном итоге на стороне Lambda я преобразую InputStream в строку и преобразую эту строку в некоторый объект на основе общего поля в типах запросов. На стороне клиента я преобразую объекты в JSON, отправляю их и преобразовываю результат обратно из строки JSON обратно в объект результата.

...