himanago

Azure・C#などのMS系技術やLINE関連技術など、好きな技術について書くブログ

Micronaut for Azure Functions 試してみた(2020年版)

Micronaut now supports Microsoft Azure Functions !!

去年、こんなLTをしました。

www.slideshare.net

当時はまだ Azure Functions がサポートされておらず、Web App として動かしてみたよって話だったんですが、ついに Azure Functions に正式対応されたので、動かすところまでやってみました。

プロジェクト作成

なんと、Web 上で自分好みの雛形プロジェクトを作ってダウンロードできます。これめっちゃいいです。

micronaut.io

こんなかんじで構成を選択して、最初のプロジェクトを生成することができます。

f:id:himanago:20200803122348p:plain
Azure Functions 用に生成

Azure Functions 用の雛形の作り方は、

  • Application Type を「Serverless Function」
  • Java Version を「8」
  • +FEATURES で「azure-function」を追加

でいけます。

そのほかはお好みで。今回は Groovy 縛りで行きます(Groovy / Gradle / Spock)。

PREVIEW」を押すと中のコードも確認できます。

f:id:himanago:20200803122513p:plain
プレビュー

「GENERATE PROJECT」を押すと zip が落ちてきます。

最初のとっかかりとしては非常にわかりやすく、とてもいいですね。

開いてみる

適当なフォルダに zip の中身を解凍して開いてみます。

今回は IntelliJ IDEA Ultimate を使ってみます。フォルダを開いたら起動の設定。

右上の「Add Configuration...」から f:id:himanago:20200803194210p:plain

「Templates」→ 「Gradle」で以下のように設定し、ダイアログ右上の「Create configuration」→「OK」 f:id:himanago:20200803195142p:plain

右上の▶︎ボタンから実行できるようになったのでここをクリックでローカル実行します。 f:id:himanago:20200803194448p:plain

なお、IDE を使わない場合は、Gradle コマンドを使って実行します(雛形の README にも実行手順が書いてあります)。

ところが、このまま実行すると「Cannot package functions due to error: Azure Functions entry point not found, plugin will exit.」というエラーが出ました。

なんで??と思ったんですが、エラー内容の通りで関数のエントリーポイントがないんですね。アノテーションで関数名を指定する、あれです。

こちらのドキュメントの記載を参考に、@FunctionName('echo') をメソッドに追加します。

Micronaut Azure

さらに、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()
    }
}

これで無事ローカル実行できました。

f:id:himanago:20200804230751p:plain
Postmanでの実行結果

<補足追記>

ローカル環境に 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 loginaz account set -s <subscription id> を実行して、gradle azureFunctionsDeploy すればデプロイできます(gradle コマンドは IDE で実行しても OK)。

Function App のリソースが Azure 上にない場合は作成してくれます。

できあがった Function App をポータルから開いてテストしてみると、ちゃんと実行できました!

f:id:himanago:20200805001827p:plain
Azureポータルでの実行結果

ちょっと苦戦しましたがとりあえずいけそうです。

今後いろいろ試してみて、よさそうなら実戦投入も視野に入れていこうかなと思います!