在Groovy中解析包含multipart/form-data的APIGatewayProxyRequestEvent

vhipe2zx  于 8个月前  发布在  Pig
关注(0)|答案(1)|浏览(122)

我正在尝试将我的命令行应用程序(用于清理CSV/Excel文件)转换为AWS Lambda函数。
我能够将其上传到AWS Lambda,但我在一些依赖项上遇到了一些问题。

有问题的测试和代码

为了测试这一点,我决定编写一个单元测试(在Spock中)来测试函数代码中的违规部分。

测试本身

package com.mikebuyshouses.dncscrubber.awsServices

import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent
import com.mikebuyshouses.dncscrubber.awsServices.providers.TestPathProvider
import com.mikebuyshouses.dncscrubber.utils.FileUtils
import spock.lang.Specification

class ApiRequestHandlerTest extends Specification {
    def "parseRequestEvent should actually write the input file from the request event"() {
        setup:
        def stubRequestEvent = Stub(APIGatewayProxyRequestEvent)
        stubRequestEvent.getHeaders() >> ["Content-Type": "multipart/form-data;boundary=YRPyKRi1Bb3sIDcW"]
        stubRequestEvent.getIsBase64Encoded() >> true;
        stubRequestEvent.getBody() >> """
------WebKitFormBoundaryYRPyKRi1Bb3sIDcW\r
Content-Disposition: form-data; name="inputFile"; filename="test.csv"\r
Content-Type: text/csv\r
\r
Number,Sale Date,Address,City,State,Zip,Parcel,Township,Removed,Removed Date,Bankruptcy #,Redemption Days,Cause #,Receive Date,Receive Time,Total Judgement,Plaintiff,Et al,Attorney,Phone,User Fee,Sheriff Fee,Ad Cost,Delinquent Tax,Total Fees,Defendant,Judgement,Interest 1,Interest 2,Additional Charges,Lien Holder 1,Lien Holder 1 Judgement,Lien Holder 1 Interest 1,Lien Holder 1 Interest 2,Lien Holder 1 Additional Charges,Lien Holder 2,Lien Holder 2 Judgement,Lien Holder 2 Interest 1,Lien Holder 2 Interest 2,Lien Holder 2 Additional Charges,Lien Holder 3,Lien Holder 3 Judgement,Lien Holder 3 Interest 1,Lien Holder 3 Interest 2,Lien Holder 3 Additional Charges,Lien Holder 4,Lien Holder 4 Judgement,Lien Holder 4 Interest 1,Lien Holder 4 Interest 2,Lien Holder 4 Additional Charges,Lien Holder 5,Lien Holder 5 Judgement,Lien Holder 5 Interest 1,Lien Holder 5 Interest 2,Lien Holder 5 Additional Charges,Lien Holder 6,Lien Holder 6 Judgement,Lien Holder 6 Interest 1,Lien Holder 6 Interest 2,Lien Holder 6 Additional Charges,Lien Holder 7,Lien Holder 7 Judgement,Lien Holder 7 Interest 1,Lien Holder 7 Interest 2,Lien Holder 7 Additional Charges,Lien Holder 8,Lien Holder 8 Judgement,Lien Holder 8 Interest 1,Lien Holder 8 Interest 2,Lien Holder 8 Additional Charges,Lien Holder 9,Lien Holder 9 Judgement,Lien Holder 9 Interest 1,Lien Holder 9 Interest 2,Lien Holder 9 Additional Charges,,Grand Total\r
1,09/15/2023,1001 Main Street,Indianapolis,IN,46220,,BRO,N,,,,123456789MF123456,07/14/2023,,44202.67,FAKE BANK,,CARLISLE,(216) 555-1234,300,66,345.42,0,711.42,DOUGLAS H LOPEZ,44202.67,0,0,0,,0,0,0,0,,0,0,0,0,,0,0,0,0,,0,0,0,0,,0,0,0,0,,0,0,0,0,,0,0,0,0,,0,0,0,0,,0,0,0,0,,44914.09\r
\r
------WebKitFormBoundaryYRPyKRi1Bb3sIDcW--\r
""".bytes.encodeBase64()

        ApiRequestHandler apiRequestHandler = new ApiRequestHandler().with { ApiRequestHandler handler ->
            handler.pathProvider = new TestPathProvider();

            return handler;
        }

        when:
        apiRequestHandler.parseRequestEvent(stubRequestEvent)

        then:
        new File("${FileUtils.TestDirectoryPath}/${FileUtils.InputPathPart}/test.csv").exists()

        cleanup:
        new File("${FileUtils.TestDirectoryPath}/${FileUtils.InputPathPart}/test.csv").delete()
    }

}

测试代码

这段代码测试了下面的方法:

RequestBodyModel parseRequestEvent(APIGatewayProxyRequestEvent request) {
    byte[] bodyBytes = request.getBody().getBytes("UTF-8");
    if (request.getIsBase64Encoded())
        bodyBytes = Base64.getDecoder().decode(bodyBytes);

    RequestBodyModel model = new RequestBodyModel();

    FileUpload.parse(bodyBytes, request.getHeaders().get('Content-Type'))
        .each { FileItem fileItem ->
            if (fileItem.getFieldName().equals("inputFile")) {
                File inputFile = FileUtils.CreateFileIfNotExists("${this.pathProvider.getBaseInputPath()}/${fileItem.getName()}");
                fileItem.write(inputFile);
                model.inputFile = inputFile;
                return;
            }

            if (fileItem.getFieldName().equals("outputFileExtension")) {
                model.outputFileExtension = fileItem.getString();
                return;
            }

            if (fileItem.getFieldName().equals("shouldExportDncRecords")) {
                model.shouldExportDncRecords = Boolean.valueOf(fileItem.getString());
                return;
            }
        }

    return model;
}

正在构建的模型RequestBodyModel定义为:

class RequestBodyModel {
    File inputFile;
    boolean shouldExportDncRecords;
    String outputFileExtension;
}

运行测试时会发生什么

无法找到该文件,并且当我调试项目(包括FileUpload.parse())时,没有返回FileItem

使用的库

  • delight-fileupload,它使用...
  • . Apache Commons FileUpload
  • AWS Lambda Java活动
  • Spock(用于单元测试)

烧题

如何使用FileUpload(或类似的东西)解析上面测试中定义的multipart/form-data请求?我想和FileItem一起工作...

cl25kdpy

cl25kdpy1#

找到了答案:
是我的界限不对。
我将存根请求逻辑调整为:

setup:
        String multipartBoundary = "----WebKitFormBoundaryYRPyKRi1Bb3sIDcW";
        def stubRequestEvent = Stub(APIGatewayProxyRequestEvent)
        stubRequestEvent.getHeaders() >> ["Content-Type": "multipart/form-data;boundary=${multipartBoundary}"]
        stubRequestEvent.getIsBase64Encoded() >> true;
        stubRequestEvent.getBody() >> """
--${multipartBoundary}\r
Content-Disposition: form-data; name="inputFile"; filename="test.csv"\r
Content-Type: text/csv\r
\r
Number,Sale Date,Address,City,State,Zip,Parcel,Township,Removed,Removed Date,Bankruptcy #,Redemption Days,Cause #,Receive Date,Receive Time,Total Judgement,Plaintiff,Et al,Attorney,Phone,User Fee,Sheriff Fee,Ad Cost,Delinquent Tax,Total Fees,Defendant,Judgement,Interest 1,Interest 2,Additional Charges,Lien Holder 1,Lien Holder 1 Judgement,Lien Holder 1 Interest 1,Lien Holder 1 Interest 2,Lien Holder 1 Additional Charges,Lien Holder 2,Lien Holder 2 Judgement,Lien Holder 2 Interest 1,Lien Holder 2 Interest 2,Lien Holder 2 Additional Charges,Lien Holder 3,Lien Holder 3 Judgement,Lien Holder 3 Interest 1,Lien Holder 3 Interest 2,Lien Holder 3 Additional Charges,Lien Holder 4,Lien Holder 4 Judgement,Lien Holder 4 Interest 1,Lien Holder 4 Interest 2,Lien Holder 4 Additional Charges,Lien Holder 5,Lien Holder 5 Judgement,Lien Holder 5 Interest 1,Lien Holder 5 Interest 2,Lien Holder 5 Additional Charges,Lien Holder 6,Lien Holder 6 Judgement,Lien Holder 6 Interest 1,Lien Holder 6 Interest 2,Lien Holder 6 Additional Charges,Lien Holder 7,Lien Holder 7 Judgement,Lien Holder 7 Interest 1,Lien Holder 7 Interest 2,Lien Holder 7 Additional Charges,Lien Holder 8,Lien Holder 8 Judgement,Lien Holder 8 Interest 1,Lien Holder 8 Interest 2,Lien Holder 8 Additional Charges,Lien Holder 9,Lien Holder 9 Judgement,Lien Holder 9 Interest 1,Lien Holder 9 Interest 2,Lien Holder 9 Additional Charges,,Grand Total\r
1,09/15/2023,1001 Main Street,Indianapolis,IN,46220,,BRO,N,,,,123456789MF123456,07/14/2023,,44202.67,FAKE BANK,,CARLISLE,(216) 555-1234,300,66,345.42,0,711.42,DOUGLAS H LOPEZ,44202.67,0,0,0,,0,0,0,0,,0,0,0,0,,0,0,0,0,,0,0,0,0,,0,0,0,0,,0,0,0,0,,0,0,0,0,,0,0,0,0,,0,0,0,0,,44914.09\r
\r
--${multipartBoundary}--\r
""".bytes.encodeBase64()

重新运行测试用例,它通过了!

相关问题