[Java, Cloud] Introducing Application Cache Client Java SDK for Oracle Cloud

原文はこちら。
https://blogs.oracle.com/developers/introducing-application-cache-client-java-sdk-for-oracle-cloud

Oracle Application Container Cloud (ACCS) のApplication Cacheは(名前が示す通り)アプリケーションのキャッシュ機能を提供します。
Application Container Cloud Service
https://cloud.oracle.com/ja_JP/acc
Mike LehmannによるCaching with Oracle Application Container Cloudと題したエントリで説明した通り、Cacheに使いたいメモリのサイズと基本的な開発・検証環境用非HAキャッシュもしくは本番環境用の信頼性の高いキャッシュを指定するだけで、適切なインフラストラクチャを自動的にプロビジョニングします。
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 Coherence
http://www.oracle.com/technetwork/jp/middleware/coherence/overview/index.html
ACCS Application CacheではCoherence実装は公開されていませんが、インメモリ・データグリッドクラウドサービスを必要とする場合には、心配する必要はありません。Oracleがまさにそれをやっています。この間、Coherenceチームは継続して革新を続けています。例えば、以下の動画はOracle CodeでのBrian Oliverによる分散ストリームに関するセッションです。


この動画では背後にあるすばらしいエンジンについて説明していますが、メイントピックに戻ることにしましょう。

Java Caching

Application Cacheは、最初は言語に依存しないREST APIでリリースされましたが、Javaアプリケーションが容易にキャッシュを利用できるよう、新たにネイティブJavaクライアントライブラリが作成されました。Javaからのキャッシュ使用を簡素化するのに加え、キャッシュとクライアント間の効率的なデータ転送を実現するためのgRPCのオプションもライブラリに追加されています。
gRPC
http://www.grpc.io/
クライアントライブラリはオープンソースフレームワークで、GitHubでホストされており、バイナリは、Maven Centralから直接ダウンロードすることも利用することもできます。
Application Container Cloud Service Application Cache Java API
https://github.com/oracle/accs-caching-java-sdk
Javaクライアントライブラリを紹介するため、簡単な例で使用方法の基礎を説明し、そのサンプルコードをApplication Container Cloudにデプロイする方法を紹介します。

Background

読者の皆さんが、Application Cacheの機能をご存知であることを前提として、今回はJavaクライアントライブラリに焦点を当てています。ACCS Application Cacheをご存知ない場合は、以下のリソースで詳細を説明しています。

Cache API Basics

数ステップの簡単な手順でJavaクライアントライブラリを使ってキャッシュにアクセスすることができます。
  1. 名前(MyCacheなど)と目的のトランスポートプロトコルをサポートするポート(gRPCの場合は1444、RESTの場合は8080)をURLとして指定し、以前に作成したApplication Cache用のSessionProviderを作成します。RESTを使用する場合、キャッシュのホスト名の後に "/ ccs" が続きます。
    SessionProvider sessionProvider = new RemoteSessionProvider("http://MyCache:1444");
  2. 指定したポートで利用可能なトランスポートを指定し、SessionProviderからSessionを取得します。
    Session cacheSession = sessionProvider.createSession(Transport.grpc());
  3. 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

ではこれらを踏まえて、サンプルをデプロイし、試すことにしましょう。
  1. 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
  2. このサンプルのGitリポジトリをローカルに複製します。
  3. サンプルをビルドして、デプロイ可能なアプリケーション・アーカイブを生成します。複製したGitリポジトリのcache-client-examples/appcache-example フォルダ内で、mvn clean packageを実行します。このコマンドを実行すると、”fat”なJarファイルが生成されます。このファイルにはアプリケーションコードと、Javaクライアントライブラリを含む、アプリケーションが依存している全てのライブラリが含まれています。Mavenビルドによって、ACCSアプリケーションアーカイブファイルも生成されます。このファイルにはfat Jarファイルがmanifest.jsonファイルと共にパッケージされています。
  4. ACCSサービスコンソールに移動し、”Create Application”をクリックして、Java SEをランタイムとして選択します。
  5. アプリケーション名を付けて、”Upload”を選択し、Mavenが生成したtargetフォルダから appcache-example-1.0-dist.zip アプリケーションアーカイブを選択します。
  6. 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
  7. 'Create' をクリックして、アプリケーションアーカイブをアップロードし、サンプルのインスタンスをデプロイします。これでおしまいです。
Webコンソールではなく、コマンドラインで操作したい場合には、ACCS REST APIをcURLで使って、アプリケーションのライフサイクルを完全に管理することもできます。
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());
これから、nameemailという2個のクエリパラメータを渡す必要があることがわかります。ターミナルから、ご自身のアプリケーションのURLを使って、以下のように実行してください。
$ curl -i -X POST https://CacheDemo-paas104.apaas.us2.oraclecloud.com/users?name=mark\&email=twain@riverboat.org
実行すると、作成され、キャッシュに配置されたUserオブジェクトがJSONデータを伴い200で返ってきます。
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"
}
作成の成功を確認するため、POSTの結果返ってきたidを使ってユーザーに対するGETを実行することができます。
$ 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に置き換えて)実行してください(これは簡単な例ですので、あまり洗練されていません)。
$ curl -i -X PUT https://CacheDemo-paas104.apaas.us2.oraclecloud.com/users/92e7d5f0-6919-4f72-9f85-e8b01dedc770?name=luke\&email=luke@rebellion.org
200が返ってきて、更新されたユーザーが表示されます。
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オブジェクトが返ります)。
$ 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"
}
削除を確認するため、UserをGETしましょう。
$ curl -i -X GET https://CacheDemo-paas104.apaas.us2.oraclecloud.com/users/92e7d5f0-6919-4f72-9f85-e8b01dedc770
404が返ってくるので、キャッシュにはもう存在しないことがわかります。
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キャッシュクライアントライブラリを入手する方法は複数ありますので、お好きな方法でどうぞ。
  1. 一つ目は、Maven Centralを使う方法です。依存性を解決するため、pom.xmlに以下を追加します。
    <dependency>
        <groupId>com.oracle.cloud.caching</groupId>
        <artifactId>cache-client-api</artifactId>
        <version>1.0.0</version>
    </dependency>
  2. 2番目は、Oracle Technology NetworkのCloud Downloadページから入手する方法です。
    Oracle Cloud Downloads
    http://www.oracle.com/technetwork/topics/cloud/downloads/index.html
    Jarファイル、javadoc、ソースが入ったZipファイルをダウンロードできます。
    Application Container Cloud Service Downloads
    http://www.oracle.com/technetwork/topics/cloud/downloads/app-cloud-service-3707850.html
  3. 最後に、クライアントライブラリのソースが格納されている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
https://github.com/mscharhag/blog-examples/blob/master/LICENSE
特に、元のインメモリUser HashMapをACCS Application Cacheに置き換えました。Michaelのブログエントリにオリジナルのエントリとそれに関連するコードが掲載されています。
Building a simple RESTful API with Spark
http://www.mscharhag.com/java/building-rest-api-with-spark

0 件のコメント:

コメントを投稿