Sending a multipart form-data request to debug my AWS Lambda function, via AWS toolkit

0

I am developer of an AWS Lambda function, that I'm in the process of converting from a command-line app, written in Groovy.

I have the Function uploaded and set up on AWS Lambda console, complete with an API Gateway endpoint that, when POSTed to, will run the Function. This Function also is connected to an EFS file system.

However, when I hit that endpoint with a request from Postman, it doesn't work. I view the logs and get see an exception over a piece of code that is a file util method that works on a user's computer (assuming the app runs on, and writes files in the file system that is on, their computer), but doesn't seem to work on the EFS:

No such file or directory: java.io.IOException
java.io.IOException: No such file or directory
	at java.base/java.io.UnixFileSystem.createFileExclusively(Native Method)
	at java.base/java.io.File.createNewFile(Unknown Source)
	at java_io_File$createNewFile$2.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130)
	at com.mikebuyshouses.dncscrubber.utils.FileUtils.CreateFileIfNotExists(FileUtils.groovy:70)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
	at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite$StaticMetaMethodSiteNoUnwrap.invoke(StaticMetaMethodSite.java:131)
	at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.call(StaticMetaMethodSite.java:89)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)
	at com.mikebuyshouses.dncscrubber.awsServices.ApiRequestHandler$_parseRequestEvent_closure1.doCall(ApiRequestHandler.groovy:70)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:263)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1035)
	at groovy.lang.Closure.call(Closure.java:412)
	at groovy.lang.Closure.call(Closure.java:428)
	at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2331)
	at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2316)
	at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2357)
	at org.codehaus.groovy.runtime.dgm$202.invoke(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:247)
	at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)
	at com.mikebuyshouses.dncscrubber.awsServices.ApiRequestHandler.parseRequestEvent(ApiRequestHandler.groovy:67)
	at com.mikebuyshouses.dncscrubber.awsServices.ApiRequestHandler$parseRequestEvent.callCurrent(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:171)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:185)
	at com.mikebuyshouses.dncscrubber.awsServices.ApiRequestHandler.handleRequest(ApiRequestHandler.groovy:38)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)


The file utils method from my code base, that it is complaining about, that was otherwise working, is defined thus:

public static File CreateFileIfNotExists(String fileName) {
    File file = new File(fileName);
    if (!file.exists()) {
        File parentDirectory = file.getParentFile();
        if (parentDirectory == null)
            parentDirectory = new File('..')

        parentDirectory.mkdirs();
        file.createNewFile();
    }

    return file;
}

I installed AWS Toolkit to my IntelliJ IDEA, gave it all rights, and tried to use it to debug but to no avail.

I copy the multipart request that I copied from Postman, tried to send that request via the Toolkit, but it complained, as apparently it was expecting JSON request.

Here's the multipart request that I tried to send it (it was pieced together from multipart request I sent via Postman):

POST /test_1_0/lists HTTP/1.1
Host:[personal AWS Gateway subdomain here...].execute-api.us-east-2.amazonaws.com
Accept:*/*
Accept-Encoding:gzip, deflate, br
Cache-Control:no-cache
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryPHU848zA1KdI8ky9
Postman-Token:647fee68-fd6b-484f-aeed-6900905d5baa
User-Agent:PostmanRuntime/7.33.0
X-Amzn-Trace-Id:Root=1-652151b6-16c8e4a3065b346e48942950
X-Forwarded-For:[IP address]
X-Forwarded-Port:443
X-Forwarded-Proto:http

------WebKitFormBoundaryPHU848zA1KdI8ky9\r\nContent-Disposition: form-data; name="inputFile"; filename="test.csv"\r
Content-Type: text/csv\r
\r
[csv file contents here...]\r
\r------WebKitFormBoundaryPHU848zA1KdI8ky9\r\nContent-Disposition: form-data; name="outputFileExtension"\r\n\r\n"XLSX"\r\n------WebKitFormBoundaryPHU848zA1KdI8ky9--\r\n

Here's the error message I face when I hit OK:

Invoking Lambda function: dncScrbberLambda
Error invoking Lambda: Could not parse request body into json: Could not parse payload into json: Unrecognized token 'POST': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
 at [Source: (byte[])"POST /test_1_0/lists HTTP/1.1
[request details here...]

How am I supposed to send multipart/form-data request, so that I can debug the Lambda locally?

asked 7 months ago396 views
1 Answer
0

Did you add the media type to the api gateway in "API Settings" (on the left nav) > Binary media types ?

answered 6 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions