Archive for 2017年10月7日

Azure Functions for Java Preview Release

この度、San Francisco で開催された JavaOne 2017 で、Microsoft は Azure Functions の Java 版を Preview 版として公開しました。本エントリーでは、ちょとだけ試してみましたので、その内容をご紹介します。

Mac OS/X の環境で Azure Functions を動作させるためには下記の環境が必要です。環境が整っていない場合、インストール・実行が正しくできない場合があります。必要な環境にご注意ください。

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
に記載されています。

ぜひ、みなさまお試しください!!

2017年10月7日 at 4:46 午前


Java Champion & Evangelist

Translate

ご注意

このエントリは個人の見解であり、所属する会社の公式見解ではありません

カレンダー

2017年10月
 1
2345678
9101112131415
16171819202122
23242526272829
3031  

カテゴリー

clustermap

ブログ統計情報

  • 1,267,804 hits

RSSフィード

アーカイブ