#chiroito ’s blog

Java を中心とした趣味の技術について

Java でファンクションを開発する @Fn Project

Fn Project + Java の組み合わせでファンクションを開発するチュートリアルを紹介します。 原文(英語)は以下にあります。
fn/examples/tutorial/hello/java at master · fnproject/fn · GitHub

Fn サーバや Dashboard の作り方は以下をご覧下さい。
関数プラットフォーム Fn Project を試す - #chiroito ’s blog

テンプレートの作成

カレントディレクトリにテンプレートとなるファイルを作成します。IDE を使ってカレントディレクトリをプロジェクトとして読込むことで開発できます。

>fn init --name hello-java --runtime java

        ______
       / ____/___
      / /_  / __ \
     / __/ / / / /
    /_/   /_/ /_/

Runtime: java
Function boilerplate generated.
func.yaml created.

カレントディレクトリに以下のファイルが生成されます。

>dir /B
func.yaml
pom.xml
src

設定ファイルであるfunc.yamlは以下のようになります。

>type func.yaml
name: hello-java
version: 0.0.1
runtime: java
cmd: com.example.fn.HelloFunction::handleRequest

ファンクションとして動くcom.example.fn.HelloFunctionクラスの実装は以下です。

package com.example.fn;

public class HelloFunction {

    public String handleRequest(String input) {
        String name = (input == null || input.isEmpty()) ? "world"  : input;

        return "Hello, " + name + "!";
    }

}

テスト

言語問わずfn runでテストをします。Java ではMavenが使われています。

>fn run
Building image hello-java:0.0.1
Sending build context to Docker daemon  14.85kB
Step 1/11 : FROM fnproject/fn-java-fdk-build:jdk9-latest as build-stage
jdk9-latest: Pulling from fnproject/fn-java-fdk-build
(略)
Digest: sha256:c80b4fc0350630e437489429008fa2eba26d6763855e895b255f8d459550b5c4
Status: Downloaded newer image for fnproject/fn-java-fdk-build:jdk9-latest
 ---> f320c1ada1f8
Step 2/11 : WORKDIR /function
 ---> cb3814ff8a3b
Removing intermediate container 8fa5fbe797f4
Step 3/11 : ENV MAVEN_OPTS -Dhttp.proxyHost= -Dhttp.proxyPort= -Dhttps.proxyHost= -Dhttps.proxyPort= -Dhttp.nonProxyHosts= -Dmaven.repo.local=/usr/share/maven/ref/repository
 ---> Running in 53cd0802a884
 ---> 4150549ea57d
Removing intermediate container 53cd0802a884
Step 4/11 : ADD pom.xml /function/pom.xml
 ---> 4ae25ff41202
Removing intermediate container 614d3f13655e
Step 5/11 : RUN mvn package dependency:copy-dependencies -DincludeScope=runtime -DskipTests=true -Dmdep.prependGroupId=true -DoutputDirectory=target --fail-never
 ---> Running in 3d0d00c6745a
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building hello 1.0.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /function/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.3:compile (default-compile) @ hello ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ hello ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /function/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.3:testCompile (default-testCompile) @ hello ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ hello ---
[INFO] Tests are skipped.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hello ---
[WARNING] JAR will be empty - no content was marked for inclusion!
[INFO] Building jar: /function/target/hello-1.0.0.jar
[INFO]
[INFO] --- maven-dependency-plugin:2.8:copy-dependencies (default-cli) @ hello ---
[INFO] Copying api-1.0.42.jar to /function/target/com.fnproject.fn.api-1.0.42.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9.272 s
[INFO] Finished at: 2017-10-10T13:28:35Z
[INFO] Final Memory: 19M/62M
[INFO] ------------------------------------------------------------------------
 ---> cd1a994ec9a6
Removing intermediate container 3d0d00c6745a
Step 6/11 : ADD src /function/src
 ---> 041b4f93d96f
Removing intermediate container 1ce357aad06d
Step 7/11 : RUN mvn package
 ---> Running in 0e90596faf9b
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building hello 1.0.0
[INFO] ------------------------------------------------------------------------
(略)

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.example.fn.HelloFunctionTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.515 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hello ---
[INFO] Building jar: /function/target/hello-1.0.0.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.669 s
[INFO] Finished at: 2017-10-10T13:28:53Z
[INFO] Final Memory: 13M/46M
[INFO] ------------------------------------------------------------------------
 ---> cee9eb5635eb
Removing intermediate container 0e90596faf9b
Step 8/11 : FROM fnproject/fn-java-fdk:jdk9-latest
jdk9-latest: Pulling from fnproject/fn-java-fdk
(略)
Digest: sha256:9c6e8f8330f356ea2bcedea295eb63631a29cfddf4fa839bcff509eb934b9eca
Status: Downloaded newer image for fnproject/fn-java-fdk:jdk9-latest
 ---> d7674a04217c
Step 9/11 : WORKDIR /function
 ---> 7636064c79f6
Removing intermediate container 730925f8aab0
Step 10/11 : COPY --from=build-stage /function/target/*.jar /function/app/
 ---> c0cd69107cbb
Removing intermediate container 6982b08cbeb1
Step 11/11 : CMD com.example.fn.HelloFunction::handleRequest
 ---> Running in b475319b7a89
 ---> 43f086bbfb5a
Removing intermediate container b475319b7a89
[Warning] One or more build-args [HTTPS_PROXY HTTP_PROXY] were not consumed
Successfully built 43f086bbfb5a
Successfully tagged hello-java:0.0.1
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
Hello, world!

デプロイ

アプリケーションをデプロイします。こちらも言語を問わずfn deployです。当然ですが、テスト同様にMavenを使用しています。

>fn deploy --app myapp_java
Deploying hello-java to app: myapp_java at path: /fn_tutorial_java
Bumped to version 0.0.2
Building image hello-java:0.0.2
Sending build context to Docker daemon  14.85kB
Step 1/11 : FROM fnproject/fn-java-fdk-build:jdk9-latest as build-stage
 ---> f320c1ada1f8
Step 2/11 : WORKDIR /function
 ---> Using cache
 ---> cb3814ff8a3b
Step 3/11 : ENV MAVEN_OPTS -Dhttp.proxyHost= -Dhttp.proxyPort= -Dhttps.proxyHost= -Dhttps.proxyPort= -Dhttp.nonProxyHosts= -Dmaven.repo.local=/usr/share/maven/ref/repository
 ---> Using cache
 ---> 4150549ea57d
Step 4/11 : ADD pom.xml /function/pom.xml
 ---> Using cache
 ---> 4ae25ff41202
Step 5/11 : RUN mvn package dependency:copy-dependencies -DincludeScope=runtime -DskipTests=true -Dmdep.prependGroupId=true -DoutputDirectory=target --fail-never
 ---> Using cache
 ---> cd1a994ec9a6
Step 6/11 : ADD src /function/src
 ---> Using cache
 ---> 041b4f93d96f
Step 7/11 : RUN mvn package
 ---> Using cache
 ---> cee9eb5635eb
Step 8/11 : FROM fnproject/fn-java-fdk:jdk9-latest
 ---> d7674a04217c
Step 9/11 : WORKDIR /function
 ---> Using cache
 ---> 7636064c79f6
Step 10/11 : COPY --from=build-stage /function/target/*.jar /function/app/
 ---> Using cache
 ---> c0cd69107cbb
Step 11/11 : CMD com.example.fn.HelloFunction::handleRequest
 ---> Using cache
 ---> 43f086bbfb5a
[Warning] One or more build-args [HTTPS_PROXY HTTP_PROXY] were not consumed
Successfully built 43f086bbfb5a
Successfully tagged hello-java:0.0.2
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
Pushing chiroito/hello-java:0.0.3 to docker registry...The push refers to a repository [docker.io/chiroito/hello-java]
e9baab9f300b: Pushed
767129f9b082: Mounted from fnproject/fn-java-fdk
6b54c3ae8b59: Mounted from fnproject/fn-java-fdk
287c77afb428: Mounted from fnproject/fn-java-fdk
96ce914d196a: Mounted from fnproject/fn-java-fdk
d4e76937d1d7: Mounted from fnproject/fn-java-fdk
b3dc563c0524: Mounted from fnproject/fn-java-fdk
0ca9138ba0fe: Mounted from fnproject/fn-java-fdk
0.0.2: digest: sha256:7097b5fb049967baa9070362a32dec43190289c1c107a7e2d918266bc139cac6 size: 1997
Updating route /fn_tutorial_java using image chiroito/hello-java:0.0.2...

ファンクションを実行する

ファンクションの実行も言語を問わずfn callです。

>fn call myapp_java /fn_tutorial_java
Hello, world!