原文はこちら。
https://blogs.oracle.com/developers/introducing-application-cache-client-java-sdk-for-oracle-cloud
Oracle Application Container Cloud (ACCS) のApplication Cacheは(名前が示す通り)アプリケーションのキャッシュ機能を提供します。
この動画では背後にあるすばらしいエンジンについて説明していますが、メイントピックに戻ることにしましょう。
この図はApplication Container Cloudにデプロイした際のサンプルの構造を図示したものです。クライアントはUserアプリケーションにRESTでアクセスすると、ACCSロードバランサーによってルーティングされます。この図で、アプリケーションを2インスタンスにスケールアウトしています。'MyCache' Application Cache もまた3インスタンスにスケールアウトして、高可用性構成を提供し、全データがメモリ上で安全であることを保証します。任意の1個のキャッシュインスタンスがなくなった場合でも、データの消失はありません。Userアプリケーションはステートレスであり、Javaクライアントライブラリを使って、ACCS内部オーバーレイ・ネットワーク上のキャッシュと対話します。様々なワークロードを処理するためにUserアプリケーションインスタンスの個数がスケールアップしたりスケールダウンしたりしても、データは引き続き安全にキャッシュに格納されます。
https://blogs.oracle.com/developers/introducing-application-cache-client-java-sdk-for-oracle-cloud
Oracle Application Container Cloud (ACCS) のApplication Cacheは(名前が示す通り)アプリケーションのキャッシュ機能を提供します。
Application Container Cloud ServiceMike LehmannによるCaching with Oracle Application Container Cloudと題したエントリで説明した通り、Cacheに使いたいメモリのサイズと基本的な開発・検証環境用非HAキャッシュもしくは本番環境用の信頼性の高いキャッシュを指定するだけで、適切なインフラストラクチャを自動的にプロビジョニングします。
https://cloud.oracle.com/ja_JP/acc
Caching with Oracle Application Container Cloud
https://blogs.oracle.com/developers/caching-with-oracle-application-container-cloud
Under the Hood
ACCS Application Cacheは高パフォーマンスかつスケーラブルなOracle Coherenceインメモリデータグリッド上に構築されています。Oracle Coherenceはトレーディングやその他メモリやレイテンシの要求に厳しいアプリケーションを長年支えているコンポーネントです。Oracle CoherenceACCS Application CacheではCoherence実装は公開されていませんが、インメモリ・データグリッドクラウドサービスを必要とする場合には、心配する必要はありません。Oracleがまさにそれをやっています。この間、Coherenceチームは継続して革新を続けています。例えば、以下の動画はOracle CodeでのBrian Oliverによる分散ストリームに関するセッションです。
http://www.oracle.com/technetwork/jp/middleware/coherence/overview/index.html
この動画では背後にあるすばらしいエンジンについて説明していますが、メイントピックに戻ることにしましょう。
Java Caching
Application Cacheは、最初は言語に依存しないREST APIでリリースされましたが、Javaアプリケーションが容易にキャッシュを利用できるよう、新たにネイティブJavaクライアントライブラリが作成されました。Javaからのキャッシュ使用を簡素化するのに加え、キャッシュとクライアント間の効率的なデータ転送を実現するためのgRPCのオプションもライブラリに追加されています。gRPCクライアントライブラリはオープンソースフレームワークで、GitHubでホストされており、バイナリは、Maven Centralから直接ダウンロードすることも利用することもできます。
http://www.grpc.io/
Application Container Cloud Service Application Cache Java APIJavaクライアントライブラリを紹介するため、簡単な例で使用方法の基礎を説明し、そのサンプルコードをApplication Container Cloudにデプロイする方法を紹介します。
https://github.com/oracle/accs-caching-java-sdk
Background
読者の皆さんが、Application Cacheの機能をご存知であることを前提として、今回はJavaクライアントライブラリに焦点を当てています。ACCS Application Cacheをご存知ない場合は、以下のリソースで詳細を説明しています。- Oracle® Cloud Using Caches in Oracle Application Container Cloud Service http://docs.oracle.com/en/cloud/paas/app-container-cloud/cache/index.html
- Tutorial: Creating a Java Application Using the Caching REST API in Oracle Application Container Cloud Service
http://www.oracle.com/webfolder/technetwork/tutorials/obe/cloud/apaas/java/java-accs-caching-basic/java-accs-caching-basic.html - Tutorial: Creating a Node.js Application Using the Caching REST API in Oracle Application Container Cloud Service
http://www.oracle.com/webfolder/technetwork/tutorials/obe/cloud/apaas/node/node-accs-caching-basic/node-accs-caching-basic.html
Cache API Basics
数ステップの簡単な手順でJavaクライアントライブラリを使ってキャッシュにアクセスすることができます。- 名前(
MyCache
など)と目的のトランスポートプロトコルをサポートするポート(gRPCの場合は1444、RESTの場合は8080)をURLとして指定し、以前に作成したApplication Cache用のSessionProvider
を作成します。RESTを使用する場合、キャッシュのホスト名の後に "/ ccs"が続きます。SessionProvider sessionProvider = new RemoteSessionProvider("http://MyCache:1444");
- 指定したポートで利用可能なトランスポートを指定し、
SessionProvider
からSession
を取得します。Session cacheSession = sessionProvider.createSession(Transport.grpc());
- SessionからCacheオブジェクトを取得します。キャッシュがない場合には作成されます。
Cache<Users> users = cacheSession.getCache("users");
Using A Cache
キャッシュは(Key-Valueペアの)アイテムのget、put、replace、removeをサポートします。 各操作はJava Sparkフレームワークを使う非常にシンプルなUser管理RESTサービスを提供するサンプルに含まれています。Spark Framework: A tiny Java web frameworkサンプルのバックエンドでは、
http://sparkjava.com/
UserService
がUserの create/update/delete 操作を提供しており、この操作はApplication Cache Javaクライアントライブラリを使って実装されています。例えば、UserオブジェクトをそのIDを使ってusers
キャッシュに入れるコードは以下のようです。キャッシュからの削除はusers.put(user.getId(),user);
users.remove(id)
だけで、とても簡単ですが、キャッシュはローカルにないので、remove APIはパフォーマンス最適化オプションを提供しています。JDKの java.util.Map
インターフェースは(もしあれば)削除されたオブジェクトとしてremove()メソッドの戻り値を定義していますが、キャッシュを扱う場合、単にオブジェクトを削除したいだけで、キャッシュから削除されたオブジェクトをクライアントに返すコストをかけたくないかもしれません。そんなわけで、Javaクライアントライブラリの Cache.remove()
メソッドでは、削除されたオブジェクトを返すかどうかを指定します。デフォルトでは、削除されたオブジェクトを返さず、メソッドはNullを返します。以下は削除されたオブジェクトを必要とするためにReturn.OLD_VALUEオプションを指定しています。User user = users.remove(id, Return.OLD_VALUE);
Cache.replace()
でユーザーを更新する場合のように、remove()メソッドはネットワーク越しに通信するデータ量を制御する機能を提供しています。今回の場合、置換対照のオブジェクトの詳細に興味がないので、デフォルトの挙動のまま、指定したキーに対する以前のオブジェクトを転送しないようにしているので、nullが返ります。users.replace(id, user);
この図はApplication Container Cloudにデプロイした際のサンプルの構造を図示したものです。クライアントはUserアプリケーションにRESTでアクセスすると、ACCSロードバランサーによってルーティングされます。この図で、アプリケーションを2インスタンスにスケールアウトしています。'MyCache' Application Cache もまた3インスタンスにスケールアウトして、高可用性構成を提供し、全データがメモリ上で安全であることを保証します。任意の1個のキャッシュインスタンスがなくなった場合でも、データの消失はありません。Userアプリケーションはステートレスであり、Javaクライアントライブラリを使って、ACCS内部オーバーレイ・ネットワーク上のキャッシュと対話します。様々なワークロードを処理するためにUserアプリケーションインスタンスの個数がスケールアップしたりスケールダウンしたりしても、データは引き続き安全にキャッシュに格納されます。
Deploying the Example
ではこれらを踏まえて、サンプルをデプロイし、試すことにしましょう。- 1GBのストレージを持つ、MyCacheというApplication CacheをBasicタイプで作成します。この構成では、キャッシュデータのメモリの安全性を保証しませんが、サンプルのためにはこれでOKです。以下のチュートリアルの "Creating a Cache"の手順に従って作成します。
Oracle® Cloud Using Caches in Oracle Application Container Cloud Service
Creating a Cache Service
http://docs.oracle.com/en/cloud/paas/app-container-cloud/cache/creating-cache-service.html - このサンプルのGitリポジトリをローカルに複製します。
- サンプルをビルドして、デプロイ可能なアプリケーション・アーカイブを生成します。複製したGitリポジトリのcache-client-examples/appcache-example フォルダ内で、mvn clean packageを実行します。このコマンドを実行すると、”fat”なJarファイルが生成されます。このファイルにはアプリケーションコードと、Javaクライアントライブラリを含む、アプリケーションが依存している全てのライブラリが含まれています。Mavenビルドによって、ACCSアプリケーションアーカイブファイルも生成されます。このファイルにはfat Jarファイルがmanifest.jsonファイルと共にパッケージされています。
- ACCSサービスコンソールに移動し、”Create Application”をクリックして、Java SEをランタイムとして選択します。
- アプリケーション名を付けて、”Upload”を選択し、Mavenが生成したtargetフォルダから
appcache-example-1.0-dist.zip
アプリケーションアーカイブを選択します。 MyCache
を関連付けられたApplication Cacheとして選択します。Application Cacheが未作成もしくは現在プロビジョニング中である場合には、キャッシュの選択ドロップダウンリストが現れないことにご注意ください。deployement.jsonファイルでサービスバインディングを使うことでApplication Cacheとアプリケーションの関連付けをすることもできます。Oracle® Cloud Using Caches in Oracle Application Container Cloud Service
Creating Metadata Files
http://docs.oracle.com/en/cloud/paas/app-container-cloud/dvcjv/creating-meta-data-files.html- 'Create'をクリックして、アプリケーションアーカイブをアップロードし、サンプルのインスタンスをデプロイします。これでおしまいです。
REST API for Managing Applications
http://docs.oracle.com/en/cloud/paas/app-container-cloud/apcsr/index.html
Using the Example
アプリケーションを実行したら、そのURLをApplicationsリストならびにアプリケーションの詳細ページで把握できます。デプロイされたアプリケーションを試すために、このURLが必要です。Creating a User
単純化するため、cURLを使ってデプロイ済みのサンプルと対話することにします。Userを作成するためには、POSTを実行する必要があります。UserControllerクラスのPOSTエンドポイントは以下のようです。これから、post("/users", (req, res) -> userService.createUser(
req.queryParams("name"),
req.queryParams("email")
), json());
name
とemail
という2個のクエリパラメータを渡す必要があることがわかります。ターミナルから、ご自身のアプリケーションのURLを使って、以下のように実行してください。実行すると、作成され、キャッシュに配置されたUserオブジェクトがJSONデータを伴い200で返ってきます。$ curl -i -X POST https://CacheDemo-paas104.apaas.us2.oraclecloud.com/users?name=mark\&email=twain@riverboat.org
作成の成功を確認するため、POSTの結果返ってきたidを使ってユーザーに対するGETを実行することができます。HTTP/1.1 200 OK
Server: Jetty(9.3.z-SNAPSHOT)
Date: Mon, 01 May 2017 20:18:15 GMT
Content-type: application/json Via: 1.1 net-apaasotd
Proxy-agent: Oracle-Traffic-Director/11.1.1.9
Transfer-encoding: chunked{
"id":"92e7d5f0-6919-4f72-9f85-e8b01dedc770",
"name":"mark",
"email":"twain@riverboat.org"
}
いい感じですね。ユーザーがキャッシュにあります。$ curl -i -X GET https://CacheDemo-paas104.apaas.us2.oraclecloud.com/users/92e7d5f0-6919-4f72-9f85-e8b01dedc770
HTTP/1.1 200 OK
Server: Jetty(9.3.z-SNAPSHOT)
Date: Mon, 01 May 2017 20:18:50 GMT
Content-type: application/json
Via: 1.1 net-apaasotd
Proxy-agent: Oracle-Traffic-Director/11.1.1.9
Transfer-encoding: chunked{
"id":"92e7d5f0-6919-4f72-9f85-e8b01dedc770",
"name":"mark",
"email":"twain@riverboat.org"
}
Updating a User
作成したユーザーの名前と電子メールを更新するには、以下のように(作成したユーザーのIDに置き換えて)実行してください(これは簡単な例ですので、あまり洗練されていません)。200が返ってきて、更新されたユーザーが表示されます。$ curl -i -X PUT https://CacheDemo-paas104.apaas.us2.oraclecloud.com/users/92e7d5f0-6919-4f72-9f85-e8b01dedc770?name=luke\&email=luke@rebellion.org
HTTP/1.1 200 OK
Server: Jetty(9.3.z-SNAPSHOT)
Date: Mon, 01 May 2017 20:21:04 GMT
Content-type: application/json
Via: 1.1 net-apaasotd
Proxy-agent: Oracle-Traffic-Director/11.1.1.9
Transfer-encoding: chunked{
"id":"92e7d5f0-6919-4f72-9f85-e8b01dedc770",
"name":"luke",
"email":"luke@rebellion.org"
}
Deleting a User
キャッシュからユーザーをDELETE しましょう(削除されたUserオブジェクトが返ります)。削除を確認するため、UserをGETしましょう。$ curl -i -X DELETE https://CacheDemo-paas104.apaas.us2.oraclecloud.com/users/92e7d5f0-6919-4f72-9f85-e8b01dedc770
HTTP/1.1 200 OK
Server: Jetty(9.3.z-SNAPSHOT)
Date: Mon, 01 May 2017 20:23:07 GMT
Content-type: application/json
Via: 1.1 net-apaasotd
Proxy-agent: Oracle-Traffic-Director/11.1.1.9
Transfer-encoding: chunked{
"id":"92e7d5f0-6919-4f72-9f85-e8b01dedc770",
"name":"luke",
"email":"luke@rebellion.org"
}
404が返ってくるので、キャッシュにはもう存在しないことがわかります。$ curl -i -X GET https://CacheDemo-paas104.apaas.us2.oraclecloud.com/users/92e7d5f0-6919-4f72-9f85-e8b01dedc770
HTTP/1.1 404 Not Found
Server: Jetty(9.3.z-SNAPSHOT)
Date: Mon, 01 May 2017 20:23:12 GMT
Content-type: application/json
Via: 1.1 net-apaasotd
Proxy-agent: Oracle-Traffic-Director/11.1.1.9
Transfer-encoding: chunked{
"message":"No user with id \u002792e7d5f0-6919-4f72-9f85-e8b01dedc770\u0027 found"
}
Developing Locally
Application Cacheを使うアプリケーションの開発、テスト、デバッグを容易にするため、JavaキャッシュクライアントライブラリはLocalSessionをサポートしています。ACCSにデプロイする際に利用するRemoteSessionと全く同じAPIを提供していますが、インプロセスで実行します。LocalSessionを使うLocalUserServiceクラスの例をご覧ください。LocalMainクラスを実行すると、リモートの共有キャッシュではなく、ローカルのインプロセスキャッシュでサンプルアプリケーションを開始できます。お手軽ですね。Obtaining the Application Cache Java Client Library
Javaキャッシュクライアントライブラリを入手する方法は複数ありますので、お好きな方法でどうぞ。- 一つ目は、Maven Centralを使う方法です。依存性を解決するため、pom.xmlに以下を追加します。
<dependency>
<groupId>com.oracle.cloud.caching</groupId>
<artifactId>cache-client-api</artifactId>
<version>1.0.0</version>
</dependency> - 2番目は、Oracle Technology NetworkのCloud Downloadページから入手する方法です。
Oracle Cloud Downloads
Jarファイル、javadoc、ソースが入ったZipファイルをダウンロードできます。
http://www.oracle.com/technetwork/topics/cloud/downloads/index.htmlApplication Container Cloud Service Downloads
http://www.oracle.com/technetwork/topics/cloud/downloads/app-cloud-service-3707850.html - 最後に、クライアントライブラリのソースが格納されているGitHubからソースを入手することができます。
Application Container Cloud Service Application Cache Java API
https://github.com/oracle/accs-caching-java-sdk
Acknowledgements
今回のサンプルは、Michael ScharhagがJava Sparkフレームワークを紹介したブログ記事のコードに基づいています。元のコードはApache 2.0ライセンスに基づいており、今回かなりの変更を加えています。mscharhag/blog-examples is licensed under the Apache License 2.0特に、元のインメモリUser HashMapをACCS Application Cacheに置き換えました。Michaelのブログエントリにオリジナルのエントリとそれに関連するコードが掲載されています。
https://github.com/mscharhag/blog-examples/blob/master/LICENSE
Building a simple RESTful API with Spark
http://www.mscharhag.com/java/building-rest-api-with-spark