Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capitalized fields with POJO Input Handlers for Java AWS Lambda

According to the documentation described here: http://docs.aws.amazon.com/lambda/latest/dg/java-programming-model-req-resp.html one can create its own POJO to serialise input and output for Java AWS Lambda.

However it appears that it doesn't properly work for input requests where fields are capitalised. For instance, the format of input for a custom resource lambda looks like:

{"RequestType":"Create", 
"ServiceToken":"arn:aws:lambda:....", 
"ResponseURL":"https://cloudformation-custom-resource-response-e...",
...}

This can be easily tested via this simple MCVE code:

package test;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class TestLambda implements RequestHandler<TestLambda.TestEvent, String> {

    private static final Logger logger = LogManager.getLogger(TestLambda.class);

    @Override
    public String handleRequest(TestEvent event, Context context) {
         logger.debug(event.toString());    
         return null;
    }

    public static final class TestEvent {
        private String key1;

        private String Key2;

        private String key3;

        public String getKey1() {
            return key1;
        }

        public void setKey1(String key1) {
            this.key1 = key1;
        }

        public String getKey2() {
            return Key2;
        }

        public void setKey2(String key2) {
            Key2 = key2;
        }

        public String getKey3() {
            return key3;
        }

        public void setKey3(String key3) {
            this.key3 = key3;
        }

        @Override
        public String toString() {
            return "TestEvent{" +
                    "key1='" + key1 + '\'' +
                    ", Key2='" + Key2 + '\'' +
                    ", key3='" + key3 + '\'' +
                    '}';
        }
    }
}

Then create a test in AWS Console for this lambda and pass there as a request the following json:

{
  "key3": "value3",
  "Key2": "value2",
  "Key1": "value1"
}

The result in logs will be:

2017-11-06 09:30:13 16849696-c2d5-11e7-80c3-150a37863c42 DEBUG TestLambda:15 - TestEvent{key1='null', Key2='null', key3='value3'}

Is there any way to deserialise this input without dealing with a raw byte stream as they suggest in that topic?

You shouldn't rely on any other features of serialization frameworks such as annotations. If you need to customize the serialization behavior, you can use the raw byte stream to use your own serialization.

This seems to me to be a great limitation of Java AWS Lambdas if we can not freely create a POJO for any type of event.

like image 923
Andremoniy Avatar asked Nov 06 '17 09:11

Andremoniy


1 Answers

In the pojo, make the fields public and exactly the same case as the json fields. This means you should have upper camel case fields e.g.,

public class TestEvent {
    public String Key1;

    public String Key2;

    public String key3;
}

I cannot explain why this works, but I just tried this today based on a work colleague's suggestion and it works. I know it doesn't look elegant. But at least it's fewer lines of code than deserializing streams.

like image 157
Kes115 Avatar answered Nov 07 '22 13:11

Kes115