Oracle Application Container Cloud (ACCS) の Application Cache
Oracle Application Container Cloud(ACCS)の Application Cacheは、インメモリ・データグリッドのテクノロジーとして利用されてきた Oracle Coherenceをベースに作られています。簡単にサービスが作成でき、クラスタ構成すればスケーラビリティと可用性が実現できます。Oracle Coherenceを使えるのに安いのがメリットです。
Application Cacheは外部から直接アクセスはできず、ACCS上のアプリからアクセスするロジックを実装する必要があります。
で、アクセスするコードを書くことになるのですが...
マニュアルのサンプル・コードのややこしいところ
おそらくは大抵の開発者が最初に参照するはずのマニュアルのサンプルコードが、挙動を説明するためとはいえ、ややこしい印象を受けます。(以下がマニュアルのNode.jsからApplication Cacheのチュートリアル)
http://www.oracle.com/webfolder/technetwork/tutorials/obe/cloud/apaas/node/node-accs-caching-basic/node-accs-caching-basic.html#section2
1. Application Cacheへの POST
が特殊
サンプルコードでは、クライアントからデータ更新のために PUTメソッドを受け取ると、Application Cacheに対しては POST
を送信(逆に、クライアントから POST
を受け取ったときは Application Cache には PUT
を送信)しています。
Application Cacheの場合、POSTメソッドでは X-Methodというヘッダーに Application Cache 固有の処理情報をセット(たとえば replace や putIfAbsent)します。さらに、POSTのときだけ Content-Type
を application/octet-stream
にする必要があります。この使い方の説明のために、「PUT
メソッドを受け取ると、Application Cache には POST
」といった、わかりにくいサンプルコードになっているように見えます。
- ちなみに
X-Method
でセットできる値については、以下のPOST
部分を参照のこと
ただ、データ更新で必ずPOST
しなければいけないわけではなく、PUT
すればデータの新規作成も更新も両方できてしまいます(が、そのはっきりした説明がマニュアルにはない)。
2. ローカルでアプリの実行確認できない
サンプルコードでは、外部からはアクセスできない内部的な Application Cacheの URI にアクセスしています。ローカルでは実行できず、必ず ACCSへのデプロイをしてテストをしなければいけなくなります。簡単な挙動はローカルでテストしたほうが効率的なので、この点がちょっと使いにくい部分です。
ちなみに、Javaの場合、ローカルキャッシュがあります。参考記事:「Application Container Cloud Service のキャッシュ機能をローカル環境で開発してみた」https://qiita.com/shinyay/items/c87fe8877de8661bfeb0 )
accs-cache-handlerの良さ
そんなときに見つけたのが、accs-cache-handler
という NPM
パッケージでした。
https://www.npmjs.com/package/accs-cache-handler
https://redthunder.blog/2017/02/20/developing-with-accs-caching-services/
- 簡単に書ける
- 稼働するURIを意識する必要がなく、キャッシュ名を指定すればよいだけです
- ローカルで動かせる
- Application Cacheを使うかどうかは環境変数を見るだけ
- ローカルで実行する場合、
Internal Caching URL is not set. Falling back on using a local hashmap instead.
といったメッセ―が出て起動します - このアプリを ACCS上にデプロイするときにApplication Cacheをバインドすると、自動的にApplication Cache用の環境変数がセットされ、自動的にApplication Cacheを参照するようになります。
- ローカルで実行する場合、
- Application Cacheを使うかどうかは環境変数を見るだけ
データをキャッシュしてレスポンスを高速にしたい、負荷が高いのでスケールアウト構成にしたいといった、もともとの Oracle Coherence の用途だけでなく、お手軽に Application Cacheにアクセスするコードが書け(かつ安価に利用できる)るので、セッション情報を保持したりステートフルなアプリを書きたいという目的にも使えると思います。
node-rest-client との実装比較
どれだけコードが違うかを比較するため、マニュアルのサンプルで使われているnode-rest-client
とaccs-cache-handler
それぞれで、最初の宣言部分とデータ更新する部分の実装例を書いてみます。どちらも Application Cache に対してPUT
します。
let CCSHOST = process.env.CACHING_INTERNAL_CACHE_URL;
let baseCCSURL = `http://${CCSHOST}:8080`;
let cacheName = 'testcache';
var Client = require('node-rest-client').Client;
var client = new Client();
exports.insert = function(req, res, next){
var keyString = req.params.keyString.toString();
var body = req.body;
var args = {
data: JSON.parse(JSON.stringify(body)),
headers: {
"Content-Type" : "application/json",
}
};
client.put(`${baseCCSURL}/ccs/${cacheName}/${keyString}`, args, function(data, response){
var responseBody = { };
res.contenttype='application/json';
res.charSet('utf-8');
if(response.statusCode == 200 || response.statusCode == 204) {
console.log('insert %s successfull',keyString);
responseBody['status'] = 'Successful.';
} else {
responseBody['statusCode'] = response.statusCode;
responseBody['headers'] = response.headers;
}
res.send(JSON.parse(JSON.stringify(responseBody)));
});
next();
}
let Cache = require('accs-cache-handler');
let cacheName = 'testcache';
let objCache = new Cache(cacheName);
exports.insert = function(req, res, next){
var keyString = req.params.keyString.toString();
var body = req.body;
objCache.put(keyString, body, function(err){
if(err) {
console.log(err);
res.send(500, JSON.parse(JSON.stringify(err)));
} else {
res.send(200);
}
});
next();
}