Azure Functions for Java Preview Release
この度、San Francisco で開催された JavaOne 2017 で、Microsoft は Azure Functions の Java 版を Preview 版として公開しました。本エントリーでは、ちょとだけ試してみましたので、その内容をご紹介します。
Mac OS/X の環境で Azure Functions を動作させるためには下記の環境が必要です。環境が整っていない場合、インストール・実行が正しくできない場合があります。必要な環境にご注意ください。
- OS X 10.12 or latest
- Java SE Development Kit 8 Downloads
- Azure CLI
- Apache Maven, version 3.0 or above.
- .NET Core, latest version.
- Node.js, version 8.6 or higher.
Azure Functions のローカル実行環境のインストール
Local Execution Environment Install
$ sudo npm i -g azure-functions-core-tools@core --unsafe-perm Password: > azure-functions-core-tools@2.0.1-beta.18 uninstall /Users/tyoshio2002/.nodebrew/node/v8.6.0/lib/node_modules/azure-functions-core-tools > node lib/uninstall.js deleting /Users/tyoshio2002/.azurefunctions/bin /Users/tyoshio2002/.nodebrew/node/v8.6.0/bin/func -> /Users/tyoshio2002/.nodebrew/node/v8.6.0/lib/node_modules/azure-functions-core-tools/lib/main.js /Users/tyoshio2002/.nodebrew/node/v8.6.0/bin/azfun -> /Users/tyoshio2002/.nodebrew/node/v8.6.0/lib/node_modules/azure-functions-core-tools/lib/main.js /Users/tyoshio2002/.nodebrew/node/v8.6.0/bin/azurefunctions -> /Users/tyoshio2002/.nodebrew/node/v8.6.0/lib/node_modules/azure-functions-core-tools/lib/main.js > azure-functions-core-tools@2.0.1-beta.18 postinstall /Users/tyoshio2002/.nodebrew/node/v8.6.0/lib/node_modules/azure-functions-core-tools > node lib/install.js + azure-functions-core-tools@2.0.1-beta.18 updated 1 package in 112.93s
次に、Maven コマンドで Azure Functions のプロジェクトを作成します。
$ mvn archetype:generate -DgroupId=com.yoshio3 -DinteractiveMode=false -DartifactId=AzureFunctionTest Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8 [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Maven Stub Project (No POM) 1 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] >>> maven-archetype-plugin:2.4:generate (default-cli) > generate-sources @ standalone-pom >>> [INFO] [INFO] <<< maven-archetype-plugin:2.4:generate (default-cli) < generate-sources @ standalone-pom <<< [INFO] [INFO] [INFO] --- maven-archetype-plugin:2.4:generate (default-cli) @ standalone-pom --- [INFO] Generating project in Batch mode [INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0) [INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.0 [INFO] ---------------------------------------------------------------------------- [INFO] Parameter: basedir, Value: /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test2 [INFO] Parameter: package, Value: com.yoshio3 [INFO] Parameter: groupId, Value: com.yoshio3 [INFO] Parameter: artifactId, Value: AzureFunctionTest [INFO] Parameter: packageName, Value: com.yoshio3 [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] project created from Old (1.x) Archetype in dir: /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test2/AzureFunctionTest [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 6.258 s [INFO] Finished at: 2017-10-28T13:24:07+09:00 [INFO] Final Memory: 15M/223M [INFO] ------------------------------------------------------------------------
プロンプト無しで Maven プロジェクトを作成したい場合の実行例:
mvn archetype:generate -DinteractiveMode=false -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DgroupId=com.yoshio3 -DartifactId=Java-Azure-Functions -Dversion=1.0-SNAPSHOT -Dpackage=com.yoshio3 -DappName=Java-Azure-Functions -DappRegion=westus2
デフォルトで Hello World のコードが生成されます。
package yoshio3.com; import com.microsoft.azure.serverless.functions.annotation.*; import com.microsoft.azure.serverless.functions.ExecutionContext; import java.util.logging.Level; /** * Hello function with HTTP Trigger. */ public class Function { @FunctionName("hello") public String hello(@HttpTrigger(name = "req", methods = {"get", "post"}, authLevel = AuthorizationLevel.ANONYMOUS) String req, ExecutionContext context) { return String.format("Hello, %s!", req); }
このサンプル・コードをビルドします。
$ mvn clean package Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8 [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Azure Java Functions 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ azure-functions-test --- [INFO] Deleting /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/target [INFO] [INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ azure-functions-test --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/src/main/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ azure-functions-test --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/target/classes [INFO] [INFO] --- maven-resources-plugin:3.0.2:testResources (default-testResources) @ azure-functions-test --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ azure-functions-test --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/target/test-classes [INFO] [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ azure-functions-test --- [INFO] Surefire report directory: /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/target/surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8 Running yoshio3.com.FunctionTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.117 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ azure-functions-test --- [INFO] Building jar: /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/target/azure-functions-test-1.0-SNAPSHOT.jar [INFO] [INFO] --- azure-functions-maven-plugin:0.1.4:package (package-functions) @ azure-functions-test --- AI: INFO 06-10-2017 12:00, 1: Configuration file has been successfully found as resource AI: INFO 06-10-2017 12:00, 1: Configuration file has been successfully found as resource [INFO] [INFO] Step 1 of 6: Searching for Azure Function entry points [INFO] Reflections took 101 ms to scan 1 urls, producing 1 keys and 2 values [INFO] 2 Azure Function entry point(s) found. [INFO] [INFO] Step 2 of 6: Generating Azure Function configurations [INFO] Generation done. [INFO] [INFO] Step 3 of 6: Validating generated configurations [INFO] Validation done. [INFO] [INFO] Step 4 of 6: Saving empty host.json [INFO] Successfully saved to /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/target/azure-functions/function-test-java/host.json [INFO] [INFO] Step 5 of 6: Saving configurations to function.json [INFO] Starting processing function: Timer [INFO] Successfully saved to /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/target/azure-functions/function-test-java/Timer/function.json [INFO] Starting processing function: hello [INFO] Successfully saved to /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/target/azure-functions/function-test-java/hello/function.json [INFO] [INFO] Step 6 of 6: Copying JARs to staging directory /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/target/azure-functions/function-test-java [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource to /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/target/azure-functions/function-test-java [INFO] Copied successfully. [INFO] Successfully built Azure Functions. [INFO] [INFO] --- maven-resources-plugin:3.0.2:copy-resources (copy-resources) @ azure-functions-test --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 2 resources [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 33.243 s [INFO] Finished at: 2017-10-06T12:01:07-07:00 [INFO] Final Memory: 39M/564M [INFO] ------------------------------------------------------------------------
ローカルで実行します。
$ mvn azure-functions:run Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8 [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Azure Java Functions 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- azure-functions-maven-plugin:0.1.4:run (default-cli) @ azure-functions-test --- AI: INFO 06-10-2017 09:13, 1: Configuration file has been successfully found as resource AI: INFO 06-10-2017 09:14, 1: Configuration file has been successfully found as resource [INFO] Azure Functions stage directory found at: /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/target/azure-functions/function-test-java [INFO] Azure Functions Core Tools found. [INFO] Starting running Azure Functions... %%%%%% %%%%%% @ %%%%%% @ @@ %%%%%% @@ @@@ %%%%%%%%%%% @@@ @@ %%%%%%%%%% @@ @@ %%%% @@ @@ %%% @@ @@ %% @@ %% % [2017/10/06 16:14:30] Reading host configuration file '/Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/target/azure-functions/function-test-java/host.json' [2017/10/06 16:14:31] Host configuration file read: [2017/10/06 16:14:31] { [2017/10/06 16:14:31] } [2017/10/06 16:14:31] info: Worker.Java.c26685f3-cbd5-4bff-bbea-d3e9e00d08ed[0] Start Process: /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/bin/java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 "/Users/tyoshio2002/.azurefunctions/bin/workers/Java/azure-functions-java-worker.jar" --host 127.0.0.1 --port 56034 --workerId c26685f3-cbd5-4bff-bbea-d3e9e00d08ed --requestId 4270cbeb-361f-422a-872a-c0ec946199c5 [2017/10/06 16:14:32] Generating 1 job function(s) info: Worker.Java.c26685f3-cbd5-4bff-bbea-d3e9e00d08ed[0] Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8 [2017/10/06 16:14:32] Starting Host (HostId=yoshionomacbookpro-1392184404, Version=2.0.11308.0, ProcessId=65522, Debug=False, Attempt=0) Listening on http://localhost:7071/ Hit CTRL-C to exit... Http Functions: hello: http://localhost:7071/api/hello info: Worker.Java.c26685f3-cbd5-4bff-bbea-d3e9e00d08ed[0] Listening for transport dt_socket at address: 5005 info: Worker.Java.c26685f3-cbd5-4bff-bbea-d3e9e00d08ed[0] Microsoft Azure Functions Java Runtime [build 1.1-SNAPSHOT] [2017/10/06 16:14:32] Found the following functions: [2017/10/06 16:14:32] Host.Functions.hello [2017/10/06 16:14:32] [2017/10/06 16:14:32] Job host started info: Worker.Java.c26685f3-cbd5-4bff-bbea-d3e9e00d08ed[0] [INFO] {com.microsoft.azure.webjobs.script.handler.MessageHandler.handle}: message generated by "class com.microsoft.azure.webjobs.script.rpc.messages.StartStream$Builder" info: Worker.Java.c26685f3-cbd5-4bff-bbea-d3e9e00d08ed[0] Worker initialized info: Worker.Java.c26685f3-cbd5-4bff-bbea-d3e9e00d08ed[0] 94978bb8-3f21-47c7-961d-5d9caecc0136 - "/Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/target/azure-functions/function-test-java/azure-functions-test-1.0-SNAPSHOT.jar"::"yoshio3.com.Function.hello" loaded [2017/10/06 16:16:27] Function started (Id=a529fffb-fd7b-43d4-bd53-3283808f68ce) [2017/10/06 16:16:27] Executing 'Functions.hello' (Reason='This function was programmatically called via the host APIs.', Id=a529fffb-fd7b-43d4-bd53-3283808f68ce) [2017/10/06 16:16:27] Function "94978bb8-3f21-47c7-961d-5d9caecc0136" executed [2017/10/06 16:16:27] Function completed (Success, Id=a529fffb-fd7b-43d4-bd53-3283808f68ce, Duration=444ms) [2017/10/06 16:16:27] Executed 'Functions.hello' (Succeeded, Id=a529fffb-fd7b-43d4-bd53-3283808f68ce)
起動が完了したら、curl コマンドなどでアクセスしてみてください。
$ curl http://localhost:7071/api/hello -d "Java World" Hello, Java World!
上記は、簡単な Hello World ですが他のトリガーを利用する場合は、下記のように local.settings.json ファイルに、AzureWebJobsStorage のアクセスキーを入力する必要があります。どうご注意ください。
local.settings.json { "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=fileup;AccountKey=*******;EndpointSuffix=core.windows.net", "AzureWebJobsDashboard": "" } }
たとえば、タイマーをトリガーに何らかの処理をしたい場合、下記のようなコードを書きます。
@FunctionName("Timer") public String functionHandler(@TimerTrigger(name = "timerInfo", schedule = "*/30 * * * * *") String timerInfo, final ExecutionContext executionContext) { executionContext.getLogger().log(Level.INFO, "Timer trigger input: {0}", timerInfo); return "From timer: \"" + timerInfo + "\""; }
ローカルで検証が終わったので、Microsoft Azure へデプロイします。
$ mvn azure-functions:deploy Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8 [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Azure Java Functions 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- azure-functions-maven-plugin:0.1.4:deploy (default-cli) @ azure-functions-test --- AI: INFO 06-10-2017 12:31, 1: Configuration file has been successfully found as resource AI: INFO 06-10-2017 12:31, 1: Configuration file has been successfully found as resource [INFO] Starting deploying to Function App function-test-java... [INFO] Authenticate with Azure CLI 2.0 [INFO] --> POST https://login.microsoftonline.com/********-****-****-****-**********/oauth2/token [INFO] 1178-byte body: client_id=04b07795******* [INFO] --> END POST [INFO] <-- 200 OK https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47/oauth2/token (833 ms, 2907-byte body) [INFO] Cache-Control: no-cache, no-store [INFO] Content-Length: 2907 [INFO] Content-Type: application/json; charset=utf-8 [INFO] Date: Fri, 06 Oct 2017 19:31:31 GMT [INFO] Expires: -1 [INFO] P3P: CP="DSP CUR OTPi IND OTRi ONL FIN" [INFO] Pragma: no-cache [INFO] Server: Microsoft-IIS/8.5 [INFO] Set-Cookie: esctx=AQABAAAAAAABlDrqfEFlSaui6xnRjX5E6ugjSSC5bAEQSJ1V_VvTv2HB9o-5-******;; domain=.login.microsoftonline.com; path=/; secure; HttpOnly, x-ms-gateway-slice=004; path=/; secure; HttpOnly, stsservicecookie=ests; path=/; secure; HttpOnly [INFO] Strict-Transport-Security: max-age=31536000; includeSubDomains [INFO] X-Content-Type-Options: nosniff [INFO] x-ms-request-id: 4813f784-046f-414e-8d9e-29a4e43e3c00 [INFO] X-Powered-By: ASP.NET [INFO] 2907-byte body: {"token_type":"Bearer","scope":"user_impersonation","expires_in":"3599","ext_expires_in":"0","expires_on":"1507321891","not_before":"1507317991","resource":"https://management.core.windows.net/","access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IkhIQnlLVS0wRHFBcU1aaDZaRlBkMlZXYU90ZyIsImtpZCI6IkhIQnlLVS********* [INFO] <-- END HTTP [INFO] Target Function App does not exist. Creating a new Function App ... [INFO] Successfully created Function App function-test-java [INFO] [INFO] Step 1 of 4: Creating ZIP package... [INFO] Successfully saved ZIP package at /Users/tyoshio2002/NetBeansProjects/Azure-Function-Test1/azure-functions-test/target/azure-functions/function-test-java.zip [INFO] [INFO] Step 2 of 4: Uploading ZIP package to Azure Storage... [INFO] Successfully uploaded ZIP package to https://d0a43c4e4c4a435d9f25.blob.core.windows.net/java-functions-deployment-packages/function-test-java.20171006123210784.zip [INFO] [INFO] Step 3 of 4: Deploying Function App with package... [INFO] Azure Resource Manager read/write per hour limit reached. Will retry in: 5 seconds [INFO] Successfully deployed Function App with package. [INFO] [INFO] Step 4 of 4: Deleting deployment package from Azure Storage... [INFO] Successfully deleted deployment package function-test-java.20171006123210784.zip [INFO] Successfully deployed Function App at https://function-test-java.azurewebsites.net [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 02:01 min [INFO] Finished at: 2017-10-06T12:33:00-07:00 [INFO] Final Memory: 42M/488M [INFO] ------------------------------------------------------------------------
デプロイが完了したのち、Azure の Portal 画面を確認して正しくデプロイされている事、そしてアクセスするための URL を確認します。
Azure にデプロイした URL へアクセスしてみます。
$ curl https://function-test-java.azurewebsites.net/api/hello -d "Java World" Hello, Java World!
ローカルで実行したのと同様に、正しく実行する事ができました。
より詳細な情報は、Azure Functions Java developer guide
に記載されています。
ぜひ、みなさまお試しください!!
Entry filed under: Microsoft Azure. Tags: Azure, Functions, Java.