Вызвать лямбда-функцию Java из Node.js - PullRequest
0 голосов
/ 15 апреля 2019

У меня есть лямбда-функция, написанная на Java, которую я хотел бы вызвать из NodeJS.Это возможно?Я получаю следующую ошибку:

An error occurred during JSON parsing: java.lang.RuntimeException
java.lang.RuntimeException: An error occurred during JSON parsing
Caused by: java.io.UncheckedIOException: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
at [Source: lambdainternal.util.NativeMemoryAsInputStream@5dc0ff7d; line: 1, column: 1]
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
at [Source: lambdainternal.util.NativeMemoryAsInputStream@5dc0ff7d; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:857)
at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:62)
at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:11)
at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1511)
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1102)

Вот код моей лямбды:

public String handleRequest(String input, Context context) {
  context.getLogger().log("input: " + input + "\n");
  JSONObject obj = new JSONObject(input);
  String dest_key = obj.getString("key");
  context.getLogger().log("key: " + dest_key + "\n");

  ...
}

А вот мой JavaScript, вызывающий вышеуказанную лямбду:

const AWS = require('aws-sdk');

const payload = "{\"key\": \"slide.pptx\"}"

AWS.config.loadFromPath('./config.json');
const lambda = new AWS.Lambda({ region: "ap-south-1" });
const params = {
  FunctionName : 'slide-builder',
  InvocationType : 'RequestResponse',
  Payload: payload // I get the same error even without a payload
};

lambda.invoke(params, function(err, data) {
  if (err) console.log(err, err.stack);
  else console.log(JSON.stringify(data));
});

Ответы [ 2 ]

1 голос
/ 15 апреля 2019

У вас есть два варианта, которые будут работать лучше, чем у вас.Попытка получить строку никогда не работала для меня, так как Java Lambda пытается интерпретировать полезную нагрузку JSON, прежде чем вы ее получите.

Один из вариантов - исключить лямбду, пытающуюся выполнить какую-либо интерпретацию вашего входного объекта.Что-то вроде:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public void handleRequest(InputStream inputStream,
                          OutputStream outputStream,
                          Context context) throws IOException {

    ObjectMapper objectMapper = new ObjectMapper();
    JsonNode jsonNode = objectMapper.readTree(inputStream);
    String key= jsonNode.get("key").asText();
    // key will now be "slide.pptx"

    // create object to return...
    MyObject myObject = new MyObject();

    // create JSON string
    String jsonReturn = objectMapper.writeValueAsString(myObject);

    // "return" the string
    outputStream.write(jsonReturn .getBytes(Charset.forName("UTF-8")));
}

Что вы сделали, так это избежали «полезности» Java-лямбды, когда она пытается превратить входящие данные в нужный вам объект.Это работает очень хорошо, когда у вас есть полный объект, но вы не делаете то, что вам нужно.

Другой вариант - создать объект, который отражает ваш объект Node:

public class KeyObject {
    private String key;

    public String getKey() {
        return key;
    }
}

, а затемваша функция обработчика должна быть:

public String handleRequest(KeyObject key, Context context) {

    String fileName = key.getKey();

    // return as you're doing now.
}

Я считаю, что любой из них будет делать то, что вы хотите.

0 голосов
/ 16 апреля 2019

(из этого ответа)

public class LambdaFunctionHandler implements RequestHandler<Map<String,Object>, String> {
    public String handleRequest(Map<String,Object> input, Context context) {
        context.getLogger().log(input.get("key"));
        ...
    }
}

Мне не очень повезло с решением stdunbar, но у меня это сработало.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...