怒Mは思いつきでモノを言う

やったことメモなどなど

Fn Project Server API v2 にアップデートされたようです。①

2018/11/29に以下の記事でv2をリリースしたことが報告されています。
オープンソース化されて1年が経ったんですね。
読んだ記事の内容を簡単にメモします。(間違っている点や補足があれば教えて欲しいです。)
慣れない英語のため、全文を読み切るのに時間がかかるため2回に分ける予定です。

medium.com

現時点では、Client version 0.5.37Server version 0.3.638です。

非推奨・削除された内容

route が削除された

チュートリアルをやっただけなので、コマンドの挙動は知りません。 FunctionとTriggerの組み合わせで実装されていたようで、無駄だったということでしょうか。 v2からは削除されています。

非同期 Functions

v1 でも非同期に呼び出せていましたが、 実装がイケてないため v2 の Triggers APIを使った実装にする様です。 2018年11月時点では非同期呼び出しは実装されていない様ですが、 実装に向けて取り組んでいるとのことです。

Logs API

v1からv2で変わりはないようですが、近いうちに削除され、 Fnが提供するSysLog機能を使うことになるようです。

func.yamlの項目formatの削除

これまではJSON、HTTP、CloudEventを定義し利用していましたが、FDKでプロトコルによる相互作用の部分は隠蔽されているため、開発者にはあまり関係がない部分でした。 現在、サポートされている形式はhttp-streamのみであるため、 formatは不要となるため、削除されました。

Java FDK

Java 9 → Java 11

記事にはなかったですが、Fn Java FDK はこれまで Java 9 までのサポートでしたが、 現時点では Java 11 がサポートされてました。
fn buildJava 11 でビルドされることになります。

次回は v2 の機能について

英語を読むのが難しいですが、翻訳機能や辞書を駆使して読んでみます。
お手数ですが、内容について誤りがあれば指摘をお願いします。

「JJUG CCC 2018 Fall」に参加してきた。

この記事はJava Advent Calendar 2018 - Qiita16日目も兼ねております。

はじめに

主にJJUG CCCのボランティア活動についての内容が多くなるかと思います。
後は、Youhei Shibata (@yangping0211) | Twitterのランチセッションに触発されて、どうやったらこういった場に来てもらえるだろうか、みたいなことを少し考えてみます。

JJUG CCC 2018 Fall(3回連続3回目の参加)

www.java-users.jp

今回も参加してきました。

2017の秋にCCC初参加&初ボランティから1年が経ちました。
そこから2018春と今回の2018秋で3回連続3回目のCCCボランティア参加。

やっぱり楽しいですねw

資料公開

恐らくですが、Githubの方でまとめられると思います。多分。

github.com

togetterに時系列でまとめています。
資料についてはそこからも拾えるかもしれません。

togetter.com

ボランティア参加について

興味がある人はやってみるといいですよ!
何が楽しいかというとお祭りに参加している実感がスゴイです。(語彙力)
他のボランティアの方々や幹事の方、参加者の皆さんの協力を得て成り立っているイベントだということを強く実感できます。

参加申し込み方法は募集サイトから申し込みできます。

jjug.doorkeeper.jp

本番の1週間前くらいにスタッフが集まって、やりたい作業などの調整や事前に作業の説明があります。 不明点がある場合はその場で質問をすれば教えてもらえます。
ボランティアスタッフ用のSlackチャンネルに招待されるので、その他不明点があれば質問してみてください。きっと誰かが答えてくれます。

ボランティアの仕事について

朝集合から開場までのお仕事

  • 各部屋の名前や入口/出口、セッションプログラムの貼紙
  • 順路形成のための一方通行、締切の貼紙
  • スポンサー様のパンフまとめ
  • 1Fでの会場への誘導

この辺の作業を朝のブリーフィングで説明していただき、みんなで作業スタートです。
ボランティア参加経験が多い人は、お仕事を見つけて集合時間前には色々仕事をし始めてますw

開場以降のお仕事

部屋付きスタッフ

  • セッションのタイムキーパー
  • 参加者の人数カウント
  • 人が多い場合に適宜誘導や椅子の出し入れ
  • セッション始まりや終わりの時のアナウンス(通常は幹事さんが行います)

私はタイムキーパーの素質が皆無なので、いつも避けています。
部屋付きのいいところは、@yangping さんもランチセッションで言っていましたが、その部屋のセッションを聞いていられる点でしょう。
なので、聞きたいセッションがある場合は、部屋付きの作業を立候補するといいと思います。 アナウンスについては通常幹事さんが行ってくれますが、いない場合などはボランティアスタッフが行う必要があります。その場合はチートシートがあるのでそれ通りにアナウンスすれば大丈夫!コワクナイ

展示ブース付きスタッフ

  • コーヒーの販促
  • ブースLTの盛り上げ役?

コーヒーを配る人です。
コーヒーをガンガン飲ませましょう。
ふらりとスピーカーの方やスタッフの方が休憩にやってきますので、コミュニケーションを取るチャンスなので、色々会話してみると楽しいと思います。

遊撃スタッフ

  • 椅子を出したり入れたり
  • その他、必要な仕事全般

私が好きな遊撃です。主に力仕事が多いです。
部屋に椅子が足りなくなった場合に、椅子を持って行ったり、不要な椅子を片付けたりします。
午前中の場合は、朝の準備が終わりきっていなかったりするので、その続きをやったりもします。
後は適宜気づいた仕事をやりますw

スタッフ共通の仕事

  • 休憩時間中の一方通行の呼び掛け
  • 入場前の待機列の整理

休憩時間中は廊下やロビーに人がいっぱいいます。
そんな中を行ったり来たりすると混雑・混乱の元になるため、参加者の方々には一方通行で移動してもらうことをお願いしています。
セッション終了後にスタッフが呼び掛けている理由です。
人が大勢いる中で大声をはりあげる必要もありますが、ベテランスタッフの方が率先してくれます。
それに便乗してみましょう!すぐに慣れますw

作業担当時間以外は?

通常の参加者の同様にセッションを聞いています。
スタッフTシャツを着ている人も普通に椅子に座って聞いているのはそのためです。
サボりじゃないよ!!

ボランティアに参加していいこと

同じスタッフ同士、知り合いになれる!
その辺の詳しい内容はランチセッションの資料を読んでいただくの早いかと思います。

speakerdeck.com

会社の同僚などと一緒に参加する方法

この様な悩みを持つ人がいます。私もその1人です。

こんな楽しいイベントは1度は参加してみてほしい!と思い、社内で参加レポートを書いたりしたりしているのですが、中々来るまでには至らないケースが多いです。

じゃあどうするか?

個人的には楽しいと思うことを、楽しそうに発信(アウトプット)することだと思います。
このブログも楽しんで書いていますし。
面白そうなこと、楽しそうなことには惹かれることが多いと思うので、身近な人に発信していきたいです。 どんな勧誘活動しているのか、効果はあったのか?というのは聞いてみたいですね。

do-m-gatoru.hatenablog.com

最後に

話しかける勇気ってのは少しはつきましたけど、まだまだです。
話しかけてみたい人は何人もいるのですけど怖気付いてしまいます。
次のCCCまでにはこの辺を少しでも解決して、次回のCCCでは積極的に知らない人に話しかけようと思います。(ナイトセミナーの懇親会でも・・・)
そして、多分次回もボランティアとして参加するでしょうw

「Oracle Code One 2018 報告会」に行ってきた。

2018/11/17(土)に行われたOracle Code One 2018 報告会に行ってきました。

jjug.doorkeeper.jp

メモとか感想とかです。まとまっていません。

メモやTwitterまとめ

togetter

@yamadamnさんがまとめて下さいました。

ハッシュタグは「#oc1jp」を使うと追えます。

Code One Overview & Java in Container / いとうちひろさん (@chiroito)

全体の日程や、有志で安全な場所や美味しい店などのマッピングについて共有されていました。 Oracle Code Oneでは初級から上級まで様々なセッションが行われているようです。
メッセージとして、 「Oracle evileと言われているけど、Javaには投資しているんだよ。 Javaは今後もOpen and Free。」

後は、各種Java開発のプロジェクトについての紹介と、David Buckさんの発表の再演とZGCについての紹介でした。初めて伊藤さんの発表を聞いたと思うのですが、聴きやすかったです。

以下の資料、動画は発表に関連しそうな参考として貼っているので、当日発表の資料ではありません。

www.slideshare.net

youtu.be

Vector API from Project Panama / 吉田 真也さん(@bitter_fox)

ベクトル演算とか直積とか数年ぶりに見ました。中々興味深かったです。

  • SIMD/SISD/MISD/MIMD
  • S:Single
  • M:Multi
  • I:instruction
  • D:Data

GraalVMについて / きしだなおきさん (@kis)

www.slideshare.net

Jakarta EE and Microservices / 西川 彰広さん [日本オラクル]

全然メモってなかった・・・
Helidonの話とかあった。

(この辺からメモが雑に・・・)

JDKライセンスモデルの変更(三たび) / 伊藤 敬さん

www.slideshare.net

Twitter4j: Duke's choice Award 2018受賞記念セッション / 山本 ユースケさん (@yusuke)

メモが「過剰包装」のみ・・・

ゆるふわ! Comminity Activities @ OC1 / JJUG幹事

docs.google.com

以下、印象に残った話し。 * Technovation Challenge
* 世界規模の女学生向けシステムコンペ
* アプリ開発、ビジネスプラン、ピッチdemoのビデオ
* 日本が2チーム出ていた。
* 2019年に向けて開始している。
* mentor募集中。

これは知らなかったなー。

technovationchallenge.org

  • women bringing the tech chasm
  • アンカンファレンス形式
  • 参加者のお悩みを聞く座談会
  • 「女性らしさ」についての議論に火が付いて会場を追い出されるまで議論が続く

南米の昭和感は意外だった。日本はマシになった方ですね。
けど、色々まだ足りてないと感じています。
新入社員で女性も入ってくるけど、どうしたら楽しく働けるのか。
産休・育休などの制度はあるし使われている方だと思うけど。(弊社)

その他Oracle Code One関連

@zinbeさんのレポート記事

gihyo.jp

動画。全てのセッションではないですが、一部は公開されています。
Fn Project関連のセッションもあったので観てみようと探したのですが、ありませんでした。残念。

2018 Oracle Code One - Java - YouTube

Oracle Code One 2018 - YouTube

LT大会

メモは一つもありませんw
togetterを追っていただければと思います。

@nishino_chekhovのLT資料は以下です。

www.slideshare.net

感想

楽しそうだなーと言うのが率直な感想。「とりあえず行っとけ!」と楽しんでいる人は言っていましたので、来年は行ってみようかなーと貯金を始めます。会社を利用できれば利用してみようw

Fn Projectについて調べて見た。④

Introduction to Fn with Javaの最後です。

前回はfn invokeが成功したところまで。

do-m-gatoru.hatenablog.com

まずは、Fn Projectの更新。

  1. brew upgrade fn でFn CLIを更新
  2. fn update server でFn Serverを更新

2018/11/26時点で、fn version 0.5.29Fn Server v0.3.624です。

Tutorialのコードを確認。

これまで動かしていたコードは以下です。

package com.example.fn;

public class HelloFunction {

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

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

}

テストコードは以下。

package com.example.fn;

import com.fnproject.fn.testing.*;
import org.junit.*;

import static org.junit.Assert.*;

public class HelloFunctionTest {

    @Rule
    public final FnTestingRule testing = FnTestingRule.createDefault();

    @Test
    public void shouldReturnGreeting() {
        testing.givenEvent().enqueue();
        testing.thenRun(HelloFunction.class, "handleRequest");

        FnResult result = testing.getOnlyResult();
        assertEquals("Hello, world!", result.getBodyAsString());
    }

    @Test
    public void shouldReturnWithInput() {
        testing.givenEvent().withBody("Bob").enqueue();
        testing.thenRun(HelloFunction.class, "handleRequest");

        FnResult result = testing.getOnlyResult();
        assertEquals("Hello, Bob!", result.getBodyAsString());
    }
}

JSONで入出力する。

コードを書き換えます。

package com.example.fn;

public class HelloFunction {

    public static class Input {
        public String name;
    }

    public static class Result {
        public String salutation;
    }

    public Result handleRequest(Input input) {
        Result result = new Result();
        result.salutation = "Hello " + input.name;

        return result;
    }

}

この状態で、fn deployします。

$ fn --verbose deploy --app myapp --local
Deploying fntest to app: myapp
Bumped to version 0.0.18
Building image fntest:0.0.18 

(中略)

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.example.fn.HelloFunctionTest
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.829 sec <<< FAILURE!
shouldReturnGreeting(com.example.fn.HelloFunctionTest)  Time elapsed: 0.472 sec  <<< FAILURE!
org.junit.ComparisonFailure: expected:<{"salutation":"[Hello ]Bob"}> but was:<{"salutation":"[]Bob"}>
    at org.junit.Assert.assertEquals(Assert.java:115)
    at org.junit.Assert.assertEquals(Assert.java:144)
    at com.example.fn.HelloFunctionTest.shouldReturnGreeting(HelloFunctionTest.java:19)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)


Results :

Failed tests:   shouldReturnGreeting(com.example.fn.HelloFunctionTest): expected:<{"salutation":"[Hello ]Bob"}> but was:<{"salutation":"[]Bob"}>

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

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.544 s
[INFO] Finished at: 2018-11-25T16:51:12Z
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test) on project hello: There are test failures.
[ERROR] 
[ERROR] Please refer to /function/target/surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
The command 'mvn package' returned a non-zero code: 1


Fn: error running docker build: exit status 1

See 'fn <command> --help' for more information. Client version: 0.5.29

失敗しました。テストを書き換えてないから当然です、と言うことで書き換えます。

package com.example.fn;

import com.fnproject.fn.testing.*;
import org.junit.*;

import static org.junit.Assert.*;

public class HelloFunctionTest {

    @Rule
    public final FnTestingRule testing = FnTestingRule.createDefault();

    @Test
    public void shouldReturnGreeting() {
        testing.givenEvent().withBody("{\"name\":\"Bob\"}").enqueue();
        testing.thenRun(HelloFunction.class, "handleRequest");

        FnResult result = testing.getOnlyResult();
        assertEquals("{\"salutation\":\"Hello Bob\"}", result.getBodyAsString());
    }
}

再度、fn deployをしてみます。

$ fn --verbose deploy --app myapp --local
Deploying fntest to app: myapp
Bumped to version 0.0.19
Building image fntest:0.0.19 

(中略)

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.example.fn.HelloFunctionTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.859 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: 3.896 s
[INFO] Finished at: 2018-11-25T16:54:27Z
[INFO] ------------------------------------------------------------------------
Removing intermediate container 3e81cb813926
 ---> 2ffe6ce2f4c3
Step 8/11 : FROM fnproject/fn-java-fdk:jdk9-1.0.72
 ---> d23b2ab9ca0a
Step 9/11 : WORKDIR /function
 ---> Using cache
 ---> 2484b72ee70d
Step 10/11 : COPY --from=build-stage /function/target/*.jar /function/app/
 ---> cf6f2b4d62e2
Step 11/11 : CMD ["com.example.fn.HelloFunction::handleRequest"]
 ---> Running in 3b7325fbd756
Removing intermediate container 3b7325fbd756
 ---> 435980547049
Successfully built 435980547049
Successfully tagged fntest:0.0.19

Updating function fntest using image fntest:0.0.19...

無事に成功しました。
動作確認します。期待通りの結果が返ってきます。

$ curl -H "Content-Type: application/json" -d '{"name":"Bob"}' http://localhost:8080/t/myapp/fntest-trigger
{"salutation":"Hello Bob"}

Tutorialでは想定通りにならないコマンドがあった。

$ curl -H "Content-Type: application/json" http://localhost:8080/t/myapp/fntest-trigger
{"message":"invalid function response"}

Tutorialでは{"salutation":"Hello World"}となるっぽいですが、なぜか上記のような結果に。 コードを書き換えてみました。

package com.example.fn;

public class HelloFunction {

    public static class Input {
        public String name = "World";
    }

    public static class Result {
        public String salutation;
    }

    public Result handleRequest(Input input) {
        Result result = new Result();
        result.salutation = "Hello " + input.name;

        return result;
    }
}

動作を確認します。

$ curl -H "Content-Type: application/json" http://localhost:8080/t/myapp/fntest-trigger
{"message":"invalid function response"}

$ curl -H "Content-Type: application/json" -d '{}' http://localhost:8080/t/myapp/fntest-trigger
{"salutation":"Hello World"}

$ curl -H "Content-Type: application/json" -d '{"name":"Bob"}' http://localhost:8080/t/myapp/fntest-trigger
{"salutation":"Hello Bob"}

Tutorialに書いている通りのコマンドだと当然失敗します。書き換えて空っぽのJSONを渡すとHello Worldが返りますが、そうじゃない感。
Tutorialの何かを見落としているか、Tutorialが間違っているか。

今後

Introductionが終わったので、引き続きTutorialを続けていきます。
Fn CLIのコマンドをまとめたいなー。

JJUGナイトセミナー「Oracle Groundbreakers APAC Tour in Tokyo」に行ってきた。

jjug.doorkeeper.jp

行ってきました。
何度も言っていますが英語はからっきしですので、内容が入ってくるかは不安でした。
案の定からっきしでしたが、メモれた内容は残しておこうと思います。

Java TrackとDevOps/DB Trackが行われていましたが、私はJava Trackのみを聞いていました。
誰かがレポート書くかな?

Oracle Groundbreakersとは?

community.oracle.com

twitter.com

コミュニティに貢献している開発者達という感じ?
世界各国を周って今回のようなセッションを行ってくれているようです。
※間違ってたら教えてください。

Serverless, the future of the Cloud (Bert Ertman)

www.slideshare.net

↑のスライドにはないですが、「Serverless removes 'R' from ComputeR」というのがありました。

computerの意味・使い方 - 英和辞典 Weblio辞書

computeの意味・使い方 - 英和辞典 Weblio辞書

多分説明してくれていたと思うんですけど、聞き取れていません。
「コンピューター」を意識することなく、「計算する」ことだけを意識できるようになる、と解釈しました。

landscape.cncf.io

上記のサイトを紹介していました。
Severlessに関わらずCloud Native Trail Mapとして参考になりそうです。
結構頻繁に更新されているようです。

デモでEclipseからAWSに連携していたようですが、そんなこともできるんですー。
今更ながらに知りました。

AWS Toolkit for Eclipse | AWS

あとは、Bert氏はSTAR WARSが好きそうだということは察しました。

Java in a World of Containers(David Buck)

日本語セッションでしたw
内容はJava Day Tokyo [JSE-1]と同じ感じでした。
仕事で使う機会は今のところ全くないのですが、jlinkについてはやはり、今後ちゃんと学ぶ必要がありますね。

DockerでJavaで動かす際にCPU、メモリをちゃんと割り当てられるようになりました。その内容はJDK8にバックポートされたとのことです。

@Mitsuyuki Shiibaさんが試されています。 bufferings.hatenablog.com

個人的にはDavid氏から聞けるちょっとした小ネタが好きです。

OpenJDK: Portola Project

今回はAlpineに関するProject Portolaが、
何で「Portola」になったかという話し。

www.google.com

地図を見ていただくと分かるのですが、Portolaという道がAlpineという道に合流しています。
「PortolaはAlpineに繋がっている」という意味のようですが、そのようにこじつけたらしいw

Microservices Gone Wrong! (Bert Ertman)

www.slideshare.net

Google翻訳をエディタとして、スライドでわからない単語や文章をひたすら打ち込んで、何の話をしているかを理解するのに費やしました。
リスニング云々ではなく、単語の意味が全くわからないのは、ダメすぎるなと実感しました。

Microservicesは聞いたこともあって、雰囲気はフワフワっと知っていましたが、基礎のような内容だったので、あとでじっくり見返してみたいと思います。

Fn Projectについて調べて見た。③

前回はfn invokeで失敗しまいました。

do-m-gatoru.hatenablog.com

原因はFn Serverのバージョンが古かった

調べても同じ様なバグ報告がなかったので、環境がおかしいと考えました。
Fn CLIbrewを使うことでアップデートできますが、Fn Serverのバージョンは7月にインストールした時点のバージョンから変わりません。
Fn CLIの内容を改めて確認しみました。

$ fn help
Fn Command Line Tool  -  Version 0.5.15
                                 
ENVIRONMENT VARIABLES
  FN_API_URL      Fn server address
  FN_REGISTRY     Docker registry to push images to, use username only to push to Docker Hub - [[registry.hub.docker.com/]USERNAME]
               
GENERAL COMMANDS
  version         Display Fn CLI and Fn Server versions
  help, h         Shows a list of commands or help for one command
  
DEVELOPMENT COMMANDS
  build, bu            Build function version
  bump, bm             Bump function version
  call, cl             Prompts for migration.
  deploy, dp           Deploys a function to the functions server (bumps, build, pushes and updates functions and/or triggers).
  init, in             Create a local func.yaml file
  invoke, iv           Invoke a remote function
  migrate, m           Migrate a local func.yaml file to the latest version
  push, p              Push function to docker registry
  
MANAGEMENT COMMANDS
  config, cf           Set configuration for an object
  create, c            Create a new object
  delete, d            Delete an object
  get, g               Get an object to retrieve its information
  inspect, i           Retrieve properties of an object
  list, ls             Return a list of created objects
  unset, un            Unset elements of a created object
  update, up           Update a created object
  use, u               Select context for further commands
  
SERVER COMMANDS
  build-server         Build custom Fn server
  start                Start a local Fn server
  stop                 Stop a function server
                
GLOBAL OPTIONS
  --context value      Use --context to select context configuration file
  --registry value     Use --registry to select registry
  --verbose, -v        Use --verbose to enable verbose mode for debugging
  --help, -h           show help
  --version            Display version
                         
FURTHER HELP:  See 'fn <command> --help' for more information about a command.
                       
LEARN MORE:    https://github.com/fnproject/fn

管理コマンドupdateというのがあるではないですか。
節穴でした。(この時点でServerは0.3.495)

$ fn update server
Using default tag: latest
latest: Pulling from fnproject/fnserver
〜中略〜
Status: Downloaded newer image for fnproject/fnserver:latest
2018/10/11 23:59:08 Process finished gracefully

$ fn version
Client version is latest version: 0.5.15
Server version:  0.3.595

無事に更新ができました。
fn startしてfn invokeを確認します。

$ fn deploy --app myapp --local
Deploying fntest to app: myapp
Bumped to version 0.0.15
Building image fntest:0.0.15 
Updating function fntest using image fntest:0.0.15...

$ fn invoke myapp fntest
Hello, world!

やっと出ました!嬉しい!

Fn の更新手順

Fnを更新する際は以下の順番で更新した方が良いです。

  1. brew upgrade fnでFn CLIを更新
  2. fn update serverで Fn Serverを更新

Fn Projectについて調べて見た。②

前回はInstall Fnまでやりました。
今回はJavaのIntroductionをやります。

まずは Fn CLI の更新

fn run を実行してもエラーになってしまいます。 そもそも何のコマンドだったか思い出せずGitHubを確認したら、runコマンドは壊れてるらしいです。

github.com

約3ヶ月ぶりなので、まずはFn CLIを更新します。
(2018/10/6時点でver0.5.8)

$ brew upgrade fn

Functionの作成

$ fn init --runtime java --trigger http fntest
Creating function at: /fntest
Function boilerplate generated.
func.yaml created.

実行後、以下の様にディレクトリ、ファイルが作成されます。

fntest
├── func.yaml
├── pom.xml
└── src
    ├── main
    │   └── java
    │       └── com
    │           └── example
    │               └── fn
    │                   └── HelloFunction.java
    └── test
        └── java
            └── com
                └── example
                    └── fn
                        └── HelloFunctionTest.java

func.yamlの中身

schema_version: 20180708
name: fntest
version: 0.0.1
runtime: java
build_image: fnproject/fn-java-fdk-build:jdk9-1.0.72
run_image: fnproject/fn-java-fdk:jdk9-1.0.72
cmd: com.example.fn.HelloFunction::handleRequest
format: http-stream
triggers:
- name: fntest-trigger
  type: http
  source: /fntest-trigger

yamlにはFunctionに関するメタデータが含まれています。

Fn Introductionより抜粋

  • schema_version–identifies the version of the schema for this function file.
  • version–the version of the function.
  • runtime–the language used for this function.
  • cmd–the cmd property is set to the fully qualified name of the function class and the method that should be invoked when your javafn function is called.
  • build_image–the image used to build your function’s image.
  • run_image–the image your function runs in.
  • format–the function uses JSON as its input/output method (see: Open Function Format).
  • triggers–identifies the automatically generated trigger name and source. For example, this function would be executed from the URL http://localhost:8080/t/appname/gofn-trigger. Where appname is the name of the app chosen for your function when it is deployed.

Functionのバージョンや言語のほか、Functionが呼び出された時に実行されるメソッドなどが記載されています。

FunctionをDeploy。しかし、失敗。

$ fn deploy --app myapp --local
Deploying fntest to app: myapp
Bumped to version 0.0.5
Building image fntest:0.0.5 
Updating function fntest using image fntest:0.0.5...

Fn: Invalid format on Fn

See 'fn <command> --help' for more information. Client version: 0.5.8

なぜかデプロイができません。
ビルドしてみます。

$ fn build
Building image fntest:0.0.5 
Function fntest:0.0.5 built successfully.

ビルドは成功します。

func.yamlで問題の切り分けをする。

以前(2018/7/2時点)のyamlとの違う点をいじってみました。 format http-streamの箇所をformat httpに変更しています。
(versionは試行錯誤の跡ですw)

schema_version: 20180708
name: fntest
version: 0.0.11
runtime: java
build_image: fnproject/fn-java-fdk-build:jdk9-1.0.72
run_image: fnproject/fn-java-fdk:jdk9-1.0.72
cmd: com.example.fn.HelloFunction::handleRequest
format: http
triggers:
- name: fntest-trigger
  type: http
  source: /fntest-trigger

デプロイしてみます。

$ fn deploy --app myapp --local
Deploying fntest to app: myapp
Bumped to version 0.0.11
Building image fntest:0.0.11 
Updating function fntest using image fntest:0.0.11...
Successfully created function: fntest with fntest:0.0.11
Successfully created trigger: fntest-trigger

成功しました。
format http-streamに問題があるのか、やり方やインストール時に問題があったのかはわかりません。 チュートリアル通りにfn initするとやはりformat http-streamfunc.yamlが作成されます。
(client ver0.5.15で再確認済み)

Functionを呼び出す。しかし、失敗。

$ fn invoke myapp fntest

Fn: Fn invoke url annotation not present, fnproject.io/fn/invokeEndpoint

See 'fn <command> --help' for more information. Client version: 0.5.15

なぜすんなり行かないのか。
7月上旬にチュートリアルを一通りやった時には、こんな困らなかったのですが。
ソース読んでエラー発生箇所は分かりましたが、どうしたらいいのかサッパリです。
もう少し調べます。

備忘

fn invoke
format http-stream