Micronaut now supports Microsoft Azure Functions !!
去年、こんなLTをしました。
www.slideshare.net
当時はまだ Azure Functions がサポートされておらず、Web App として動かしてみたよって話だったんですが、ついに Azure Functions に正式対応されたので、動かすところまでやってみました。
プロジェクト作成
なんと、Web 上で自分好みの雛形プロジェクトを作ってダウンロードできます。これめっちゃいいです。
こんなかんじで構成を選択して、最初のプロジェクトを生成することができます。
Azure Functions 用の雛形の作り方は、
- Application Type を「Serverless Function」
- Java Version を「8」
- +FEATURES で「azure-function」を追加
でいけます。
そのほかはお好みで。今回は Groovy 縛りで行きます(Groovy / Gradle / Spock)。
「PREVIEW」を押すと中のコードも確認できます。
「GENERATE PROJECT」を押すと zip が落ちてきます。
最初のとっかかりとしては非常にわかりやすく、とてもいいですね。
開いてみる
適当なフォルダに zip の中身を解凍して開いてみます。
今回は IntelliJ IDEA Ultimate を使ってみます。フォルダを開いたら起動の設定。
右上の「Add Configuration...」から
「Templates」→ 「Gradle」で以下のように設定し、ダイアログ右上の「Create configuration」→「OK」
右上の▶︎ボタンから実行できるようになったのでここをクリックでローカル実行します。
なお、IDE を使わない場合は、Gradle コマンドを使って実行します(雛形の README にも実行手順が書いてあります)。
ところが、このまま実行すると「Cannot package functions due to error: Azure Functions entry point not found, plugin will exit.」というエラーが出ました。
なんで??と思ったんですが、エラー内容の通りで関数のエントリーポイントがないんですね。アノテーションで関数名を指定する、あれです。
こちらのドキュメントの記載を参考に、@FunctionName('echo')
をメソッドに追加します。
さらに、String req
のバインドもうまくいかないようだったので、同じくドキュメントと同じ形式に修正。
ついでに
- ログ出力の行も Groovy っぽくなかったので修正
return
も消しつつ(Groovy では不要)body
の中身をそのまま返すよう修正
しました。
Before:
package dev.himanago; import com.microsoft.azure.functions.annotation.* import com.microsoft.azure.functions.* import io.micronaut.azure.function.AzureFunction /** * Azure Functions with HTTP Trigger. */ class Function extends AzureFunction { String echo( @HttpTrigger(name = "req", methods = HttpMethod.POST, authLevel = AuthorizationLevel.ANONYMOUS) String req, ExecutionContext context) { context?.getLogger()?.info("Executing Function: ${getClass().getName()}"); return String.format(req) } }
After:
package dev.himanago; import com.microsoft.azure.functions.annotation.* import com.microsoft.azure.functions.* import io.micronaut.azure.function.AzureFunction /** * Azure Functions with HTTP Trigger. */ class Function extends AzureFunction { @FunctionName('echo') String echo( @HttpTrigger(name = "req", methods = HttpMethod.POST, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request, ExecutionContext context) { context?.logger?.info "Executing Function: ${this.class.name}" request.body.get() } }
これで無事ローカル実行できました。
<補足追記>
ローカル環境に Azure Functions Core Tools、Gradle を入れておく必要があります。
また、JDK は 8 じゃないと正しく動かないので、java -version
で 1.8 が出るようにしておく必要があります。
Azure にデプロイ
今度は Azure にデプロイして動かしてみましょう。
デプロイの設定は、build.gradle に書きます。最初から書いてあるので、これを自分の環境に合わせて書き換えれば OK です。
azurefunctions { resourceGroup = 'java-functions-group' appName = 'demo' pricingTier = 'Consumption' region = 'westus' runtime { os = 'windows' } localDebug = "transport=dt_socket,server=y,suspend=n,address=5005" }
Terminal から az login
→ az account set -s <subscription id>
を実行して、gradle azureFunctionsDeploy
すればデプロイできます(gradle コマンドは IDE で実行しても OK)。
Function App のリソースが Azure 上にない場合は作成してくれます。
できあがった Function App をポータルから開いてテストしてみると、ちゃんと実行できました!
ちょっと苦戦しましたがとりあえずいけそうです。
今後いろいろ試してみて、よさそうなら実戦投入も視野に入れていこうかなと思います!