Guidance for Transitioning from Data Cache to Reids On Compose Service

Sept 22, 2016

The purpose of this document is to provide a general guidance to Data Cache service users who are in transition toRedis on Compose. The Data Cache service is going to be deprecated, the existing Data Cache service users may need to switchto use Redis on Compose as an alternative caching solution. There is no migration tool provided to move users from the Data Cache to Redis on Compose. User will have to manually modify their existing applications in order to switch to Redis compose service on IBM Bluemix.

In the current Data Cache enabled applications on Bluemix, WXS client libraries are loaded out of the box in the Liberty buildpack, the Liberty buildpack auto-configuration feature will configure the client applications to point to the Data Cache service and enable caching when the application is binding to the Data Cache service. For example, the name of the cache, userid and password and the endpoint URL for accessing the caches, will be auto configured within the Liberty runtime for applications to use. Once the Data Cache service is replaced by Redis on Compose, users need to follow Compose document in order to configure the client libraries and to resolve VCAP information. (See for details)

This documentation contains 2 parts. Part I describes the Java client changes that user will have to do when they switch from Data Cache to Redis on Compose service. Examples of API mappings will be provided in this document. Part II of this document describes REST API mappings between Data Cache service and Redis on Compose. This document will not cover all possible Java client libraries or all possible Redis REST API usage and mappings. User needs to consult with Redis on Compose support to learn more options.

Part I: Java Client API and Mappings

Data Cache service provides Java client API and examples. However, there is no official Redis client library. Redis on Compose service didn’t provide out of the box client library with Java client. Recommended clients for Java by Redis on Compose are “lettuce”. This document will mainly describe the client API mappings between Data Cache service and “lettuce” ( For other possible Java client libraries for Redis, please consult with Redis on Compose service support for details.

Data Cache service client uses the following APIs to connect to the caching server:

ObjectGridManager ogm = ObjectGridManagerFactory.getObjectGridManager();
ClientSecurityConfiguration csc=
csc= ClientSecurityConfigurationFactory.getClientSecurityConfiguration();
csc.setCredentialGenerator(new UserPasswordCredentialGenerator(username,password));
csc.setSecurityEnabled(true);
ClientClusterContext ccc = ogm.connect(host, csc, null);
ObjectGrid clientGrid = ogm.getObjectGrid(ccc, gridName);
ogSession = clientGrid.getSession();

Redis on Compose (using lettuce) shows the similar APIs as shown in the following, however there are no grid and map structures in Redis, so they are not exactly the same.

importcom.lambdaworks.redis.*;
RedisClient redisClient =RedisClient.create("redis://admin:password@host:15200");
StatefulRedisConnection<String, String connection = redisClient.connect();
RedisCommands<String, String syncCommands = connection.sync();

Note: user specifies password as part of connection URL when creating RedisClient connection object. Alternatively, they can call auth() method from connection object to authenticate servers.

Data Cache makes the following calls in order to run CRUD (Create/Read/Update/delete) operations. Note: Redis on Compose will not support cache transaction and commit. If ‘session.begin()… session.commit()’ is used in the Data Cache use case, there is no equivalent approach to set locking strategy and the transaction control in Redis on Compose from your client code.

ObjectMap map= ogSession.getMap("mymap.NONE.P");
map.upsert("key1", "value1");
Object value = map.get("key1");
map.remove("key1");

Redis on Compose (lettuce) makes the following calls to run CRUD operations.

syncCommands.set("key1", "value1");
RedisFuture<String> value = syncCommands.get("key1");
syncCommands.del("key1");

Note: there is no map object in redis. If the asyncCommands are used, async.awaitAll() method may need to be called after key is set in the cache before retrieving the key.

Here is how the Data Cache sets the TTL (Time to live) for the cached entries.

String MapType="mymap.LUT.P"; // time-to-live with last update time
….
map.setTimeToLive(120); // 2 minutes TTL with last update time

Here is how Redis on Compose (lettuce)can setTTL.

……
…..
syncCommands.expire("key1", 120);

There are no equivalent LUT and LAT time to live types in Reids on Compose. However, you may be able to handle TTL programmatically to archive the same goal like what LUT and LAT do in Data Cache service.

The Data Cache closes session and disconnects from the grid by making session close and grid disconnect API calls.

ObjectGridManagerogm = null;
Session sess = null;
try {
ObjectGridManager ogm = ObjectGridManagerFactory.getObjectGridManager();
…..
....
sess = grid.getSession();
….
}
finally {
sess.close();
ogm.disconnect();
}
catch {
…..
}

Redis on Compose sessionscan be closed by calling shutdown API.

RedisClient redisClient = null;
try {
redisClient =RedisClient.create("redis://admin:password@host:15200");
…..
}
finally {
redisClient.shutdown();
}
catch {
…..
}

Here is how the Data Cache sets objects into the grid.

ObjectMap map= ogSession.getMap("mymap.NONE.P");
Map<String, String> myMap = new HashMap<String, String>();
myMap.put("one", "1");
myMap.put("two", "2");
myMap.put("three", "3");
map.put("myMap”, myMap);
myMap = (Map<String, String>)map.get("myMap”);

Redis on Compose can setobjects using either syncCommands or asyncCommands APIs.

….
….
Map<String, String> myMap = new HashMap<String, String>();
myMap.put("one", "1");
myMap.put("two", "2");
myMap.put("three", "3");
syncCommands.mset(myMap);
ListStreamingAdapter<String>adapter=newListStreamingAdapter<String>();
Long count= syncCommands.keys(adapter, "???");
List<String> keys = adapter.getList();

The data cache is an object store, whereas if users want to store java objects in Redis on Compose, users have to serialize and deserialize the objects themselves.

Part II: REST API and Mappings

Redis doesn’t provide out of the box APIs to work with REST services directly, however, Redis and Redis on Compose support 3rd party node.js libraries to integrate with client’s Node.js applications. For example, Redis on Compose recommends “ioredis” node.js library to be integrated with, and here is the link to get the open source and instructions:

For users who useData Cache REST APIs and build their own node.js applications, they usually take the node.js example that is provided by Data Cache service to start with it. Here is an example:

From this example package, wxs.js is a node.js library which does the connection to Data Cache service for CRUD operations. wxs.js uses the Data Cache REST URL /resources/datacaches/<mapname>/ to send REST requests to the Data Cache server side.

From user’s node.js application, the following code will be written to run CRUD operations against the Data Cache service.

Var xhr=createXHR();
xhr.onreadystatechange = function() {
…..
…..
};
if (operation == "get") {
xhr.open("GET", "cache/"+"key1", true);
xhr.send(null);
} elseif (operation =="put") {
xhr.open("PUT", "cache?key="+"key1"+"&value="+ "value1", true);
xhr.send(null);
} else {
xhr.open("DELETE", "cache/"+"key1", true);
xhr.send(null);
}

When writing your node.js applications using ioredis API, you are required to make changes of your node.js applications. Here are the lines of code that you need to replace within your node.js applications in order to connect to Redis server.

var Redis = require('ioredis');
var redis = new Redis(15200, host);
redis.set('key1', 'value1');
redis.get('key1', function (err, result) {
console.log(result);
});
….
….
Redis.del('key1');