AWS Lambda Javaをローカルで実行できる環境をSpring Bootベースで作ってみた

AWS Lambda Javaでアプリケーションを作成した際に、まずはローカルでデバッグしようとするとJUnitを書くことが普通かと思います。が、AWS Lambdaのテストのようなことをローカルでも簡単にできるようにしたい、で、デバッグをできるようにしたいと思い、今回ローカルでAWS Lambda Javaを実行できる環境を作ってみました。

ネット環境は悪いけど、ちょっと作ったAWS Lambda Javaの確認をしたい、という時にも使えるかと思います。

# 結果
現状だとhandleRequestメソッドの第一引数はString型とMap\<String, Object\>型に対応しています。とりあえずこれだけあればダイジョーブなはず。

https://github.com/kojiisd/aws-lambda-rest

# 使い方
大まかな流れは以下になります。

1. AWS Lambda Java（実行対象）のJarファイル作成
2. AWSLambdaRestへの適用
3. 実際に実行

## AWS Lambda Java（実行対象）のJarファイル作成
サンプルとしてこんな感じのAWS Lambda Javaを組んでみます。

```java:AWSLambdaExample.java
public class AwsLambdaExample  implements RequestHandler<String, Object> {

    public String handleRequest(String input, Context context) {
        context.getLogger().log("Input: " + input);

        return "Input result: " + input;
    }
}
```

pom.xmlにはこんな感じでjar-with-dependenciesを作れるように設定しておきます。

```xml:pom.xml
<dependencies>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-lambda-java-core</artifactId>
        <version>1.1.0</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </plugin>
    </plugins>
</build>
```

## AWSLambdaRestへの適用
作成したJarファイルをAWSLambdaRestに適用します。例ではextlibフォルダ配下にJarファイルを配置して、pom.xmlとapplication.ymlを編集します。

まずｐom.xmlには以下を記述します。

```xml:pom.xml
<dependency>
    <groupId>jp.gr.java_conf.kojiisd</groupId>
    <artifactId>aws-lambda-example</artifactId>
    <version>1.0-SNAPSHOT</version>
    <scope>system</scope>
    <systemPath>${basedir}/extlib/aws-lambda-example-1.0-SNAPSHOT.jar</systemPath>
</dependency>
```

application.ymlには実行させたいhandleRequestが所属するクラスを指定します。

```yaml:application.yml
lambda-rest:
  target: jp.gr.java_conf.kojiisd.AwsLambdaExample
```

## 実際に実行
上記まで実施できたら、実行してみます。Jarファイルを作成し、以下のコマンドを実行してください。

```
$ java -cp target/aws-lambda-local-rest-0.0.1-SNAPSHOT.jar jp.gr.java_conf.kojiisd.AwsLambdaLocalRestApplication
```

# 結果の確認
起動したら、実際に値を送付してみます。RestClientを利用して、以下のJSONコードを送付します。

```
"test"
```

通りましたね。

![スクリーンショット 2017-03-04 8.37.33.png](https://qiita-image-store.s3.amazonaws.com/0/102769/1f78bc14-c605-ff0f-4db4-9f37d20ed984.png)

ちなみに今回のサンプルでは、ログに入力値を出力する処理が書かれていますが、下記のような~~手抜きな~~実装のため、ログに出力する処理はコンソールに出力されます。

![スクリーンショット 2017-03-04 8.38.02.png](https://qiita-image-store.s3.amazonaws.com/0/102769/20bac14a-208f-1141-da41-6c2395185c43.png)


```java
            @Override
            public LambdaLogger getLogger() {
                return new LambdaLogger() {
                    @Override
                    public void log(String s) {
                        System.out.println(s);
                    }
                };
            }
```

もちろん今回利用したJarファイルは、そのままAWS Lambda Javaでも実行可能です。

# まとめ
今回ローカルでAWS Lambda Javaのシミュレートができる環境を作ってみました。まだ実行対象のメソッド特定を動的にできないなど改善点はありますが、ひとまずこれでやりたいことはできるようになりました。もちろんプルリク、大歓迎です。