Infinispan REST API made simple

Infinispan servers provide RESTful HTTP access to data via a REST module built on Netty. In this tutorial we will learn how to use it to manage Cache data with regards to all major Infinispan versions starting from the latest version.

Using Infinispan REST API (latest version)

REST endpoints listen on port 11222 by default.

First off, you can configure authentication to the REST endpoint with the cli.sh script in the bin folder of Infinispan server distribution.

./cli.sh user create
Specify a username: qwer1234!
Set a password for the user: qwer1234!
Confirm the password for the user: qwer1234!

Please note that older Infinispan versions used the “user-tool.sh” script to create users. This is now deprecated in Infinispan 12. Here is an example how to use usertool.sh for older Infinispan versions:

./user-tool.sh
Set a password for the user: qwer1234!
Confirm the password for the user: qwer1234!

Enabling BASIC REST authentication

Before starting, it is required that you enable BASIC authentication for your REST Endpoints. Open the conf/server.xml file and include the authentication mechanisms:

<rest-connector>
      <!-- Specifies SASL mechanisms to use for authentication. -->
      <authentication mechanisms="DIGEST BASIC"/>
   </rest-connector>
</endpoints>

Managing Caches with REST API

Let’s begin to show how to create a new Cache, passing as argument the XML Cache configuration and using the following REST URI:

POST /rest/v2/caches/{cacheName}

Which translates into:

curl -u myuser:qwer1234! -X POST -H "Content-type:application/xml" -d "
<infinispan>
    <cache-container>
        <distributed-cache name=\"cacheName\" mode=\"SYNC\"/>
    </cache-container>
</infinispan>" http://localhost:11222/rest/v2/caches/cacheName

Here is how you can verify the Cache configuration:

curl -u myuser:qwer1234! http://localhost:11222/rest/v2/caches/cacheName?action=config
{"distributed-cache":{"mode":"SYNC","transaction":{"mode":"NONE"}}}

On the other hand, you can retrieve both the configuration and th runtime parameters as follows:

curl -u myuser:qwer1234! http://localhost:11222/rest/v2/caches/cacheName

{"stats":{"current_number_of_entries_in_memory":-1,"time_since_start":-1,"time_since_reset":-1,"current_number_of_entries":-1,"total_number_of_entries":-1,"off_heap_memory_used":-1,"data_memory_used":-1,"remove_misses":-1,"evictions":-1,"average_read_time":-1,"average_read_time_nanos":-1,"average_write_time":-1,"average_write_time_nanos":-1,"average_remove_time":-1,"average_remove_time_nanos":-1,"required_minimum_number_of_nodes":-1,"retrievals":-1,"remove_hits":-1,"hits":-1,"stores":-1,"misses":-1},"size":0,"configuration":{"distributed-cache":{"mode":"SYNC","transaction":{"mode":"NONE"}}},"rehash_in_progress":false,"bounded":false,"indexed":false,"persistent":false,"transactional":false,"secured":false,"has_remote_backup":false,"indexing_in_progress":false,"statistics":false}

Finally, in order to delete your Cache, you can issue a DELETE command against the Cache name as follows:

curl -u myuser:qwer1234! -X DELETE http://localhost:11222/rest/v2/caches/cacheName

Managing Cache Data

In order to add a new Entry to our cache, we can use the following URI:

POST /rest/v2/caches/{cacheName}/{cacheKey}

which translates into:

curl -X POST -i  -u "myuser:qwer1234!" -H "Content-type:application/xml" -d "<catalog>
    <book id="book01">
       <author>Gambardella, Matthew</author>
       <title>XML Developer's Guide</title>
      <genre>Computer</genre>
       <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
       <description>An in-depth look at creating applications 
       with XML.</description>
    </book>
 </catalog>" http://localhost:11222/rest/v2/caches/cacheName/book01

In order to retrieve a Cache Entry, we can issue a GET against the cache key:

GET /rest/v2/caches/{cacheName}/{cacheKey}

In our case, this is going to be:

curl -u myuser:qwer1234! http://localhost:11222/rest/v2/caches/cacheName/book01

<catalog>
    <book id=book01>
       <author>Gambardella, Matthew</author>
       <title>XML Developer's Guide</title>
       <genre>Computer</genre>
       <price>44.95</price>
       <publish_date>2000-10-01</publish_date>
       <description>An in-depth look at creating applications 
      with XML.</description>
    </book>
 </catalog>

In order to update a Cache entry, we will use a PUT command:

PUT /rest/v2/caches/{cacheName}/{cacheKey}

In our case, this is going to be:

curl -X PUT -i  -u "myuser:qwer1234!" -H "Content-type:application/xml" -d "<catalog>
    <book id="book01">
       <author>John Smith</author>
       <title>XML Developer's Guide</title>
       <genre>Computer</genre>
       <price>44.95</price>
       <publish_date>2000-10-01</publish_date>
       <description>An in-depth look at creating applications 
       with XML.</description>
    </book>
 </catalog>" http://localhost:11222/rest/v2/caches/cacheName/book01

Finally, to delete a Cache Entry, we will be using a DELETE command

DELETE /rest/v2/caches/{cacheName}/{cacheKey}

In our case, this is going to be:

curl -X DELETE -u myuser:qwer1234! http://localhost:11222/rest/v2/caches/cacheName/book01

For more details, check the latest release of Infinispan REST documentation: https://infinispan.org/docs/stable/titles/rest/rest.html

Infinispan REST Interface for releases 8 and 9

The second part of the tutorial covers using REST API with older Infinispan releases (8 and 9)

If you are using an older infinispan release (8 or 9) the REST service is also available as part of the server distribution, so you don’t need any more to download an external Web application for it:

15:51:49,815 INFO  [org.infinispan.server.endpoint] (MSC service thread 1-2) DGENDPT10000: REST starting
15:51:50,332 INFO  [org.infinispan.rest.embedded.netty4.NettyRestServer] (MSC service thread 1-2) ISPN012003: REST server starting, listening on 127.0.0.1:8080
15:51:50,333 INFO  [org.infinispan.server.endpoint] (MSC service thread 1-2) DGENDPT10002: REST mapped to rest/rest
15:51:50,452 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management
15:51:50,453 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:9990
15:51:50,453 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: Infinispan Server 9.0.0.Final (WildFly Core 2.2.0.Final) started in 3918ms - Started 150 of 161 services (47 services are lazy, passive or on-demand)

The supported HTTP methods in the REST API for entities are as follows:

  • HEAD : This retrieves a cache entry, but you’ll receive exactly the same content that you have stored, which means that if you have stored a binary object, you will need to deserialize the content yourself
  • GET: This retrieves a cache entry or a list of keys
  • POST: This creates a new cache entry
  • DELETE: This deletes an entry
  • PUT: This updates a cache entry

HTTP GET and HEAD are similar methods and can be used to read data from the cache. The HTTP GET method is used to retrieve a cache entry. If the cache entry exists, the GET will return a representation of the data that was stored in the cache and a response code of 200 ( OK ). Otherwise, if the requested cache key does not exist, it will return a 404 ( NOT FOUND ) or 400 ( BAD REQUEST ) response code.

Accessing Infinispan REST Service

If your goal is just to test the REST services, the simplest option is to use existing tools, such as the cURL library, which is a well known command line tool developed for transferring files using a URL syntax, and it supports protocols such as HTTP, HTTPS, FTP, and FTPS, among others.

So let’s say you want to store in Infinispan the following XML under the key 156211:

<catalog>
   <book id="book01">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications 
      with XML.</description>
   </book>
</catalog>

First of all, we’ll need to create an application user so that we are allowed to access the rest application:

$ ./add-user.sh -a -u myuser -p "qwer1234!" -ro supervisor,reader,writer

Next, let’s use cURL to insert an entry with a POST:

$ curl -X POST -i  -u "myuser:qwer1234!" -H "Content-type:application/xml" -d "<catalog>
>    <book id="book01">
>       <author>Gambardella, Matthew</author>
>       <title>XML Developer's Guide</title>
>       <genre>Computer</genre>
>       <price>44.95</price>
>       <publish_date>2000-10-01</publish_date>
>       <description>An in-depth look at creating applications 
>       with XML.</description>
>    </book>
> </catalog>" http://localhost:8080/rest/default/156211

Now you can use an HTTP GET to retrieve the XML document for the key 156211:

$ curl -i -u "myuser:qwer1234!" -H "Accept:application/xml" http://localhost:8080/rest/default/156211

Since the release of Infinispan 5.3, you can obtain additional information for a given cache key by appending the extended parameter on the query string, as follows:

GET /cacheName/cacheKey?extended

For example:

$ curl -i -u "myuser:qwer1234!" -H "Accept:application/xml" http://localhost:8080/rest/default/156211?extended

Here’s the information which will be returned along with the XML file:

HTTP/1.1 200 OK
Connection: keep-alive
Cluster-Node-Name: localhost
ETag: "application/xml-1890166279"
Cluster-Server-Address: [127.0.0.1:55200]
Cluster-Primary-Owner: localhost
Last-Modified: Thu, 1 Jan 1970 01:00:00 +0100
Content-Type: application/xml
transfer-encoding: chunked

As you can see, the GET operation returns the following custom headers:

  • Cluster-Primary-Owner: This is the name of the node that is the primary owner of the key
  • Cluster-Node-Name: This is the name of the node that handled the request in JGroups
  • Cluster-Physical-Address: This is the physical address of the JGroups cluster that handled the request

If you want to delete an item from the Cache, you can use the HTTP DELETE method as follows:

$ curl -i -u "myuser:qwer1234!" -X DELETE http://localhost:8080/rest/default/156211

Finally, if you want to update an existing key, you can use the PUT HTTP method as follows:

$ curl -i  -u "myuser:qwer1234!" -X PUT -H "Content-type:application/xml" "<catalog>
>    <book id="book01">
>       <author>Gambardella, Matthew</author>
>       <title>XML Developer's Guide</title>
>       <genre>Computer</genre>
>       <price>48.95</price>
>       <publish_date>2000-10-01</publish_date>
>       <description>An in-depth look at creating applications 
>       with XML.</description>
>    </book>
> </catalog>" http://localhost:8080/rest/default/156211

Other useful options you can append to your query string

  • performAsync: If defined, performAsync will perform asynchronous requests and the operation will return without waiting for data replication.
  • timeToLiveSeconds is the number of seconds before this entry is automatically deleted. If omitted, Infinispan assumes -1 as the default value and the cache entry will not expire.
  • maxIdleTimeSeconds is the number of seconds between the last usage of this entry and the time it will automatically be deleted. If omitted, Infinispan assumes -1 as the default value and the cache entry will not expire as a result of idle time.

Infinispan REST Interface for releases 4 and 5

If you need to access the Infinispan 4,5 data grid from any kind of client (which is able to consume a RESTful service), then Infinispan REST server is what you need !

Download Infinispan server-rest application from here

This tutorial has been tested with the release 4.2.1 of Infinispan and JBoss AS 6

Now unzip the file infinispan-4.2.1.FINAL-server-rest.zip and extract the file infinispan.war which will be deployed on JBoss AS 6.

Please note, due to issues with the VFS of JBoss AS 6, some libraries (namely scala-library-2.8.1.jar) cause the application deployment to fail. In order to solve this issue you can add to your WEB-INF folder of infinispan.war a JBoss AS metadata file (jboss-scanning.xml) which excludes scala library from the deployment.

Here’s jboss-scanning.xml

<scanning xmlns="urn:jboss:scanning:1.0">

   <path name="WEB-INF/lib/scala-library-2.8.1.jar">
     <exclude name="scala" recurse="true"/>
   </path>

</scanning>

This is how your infinispan.war archive will look like:

infinispan.war

–WEB-INF

   lib

   classes

   — web.xml

   — jboss-scanning.xml

Ok. Now launch JBoss AS 6 and point your browser to the infinispan REST server:

http://localhost:8080/inifinispan

infinispan rest

You will hit a welcome page which describes how basically the REST server works:

In order to insert elements in the cache, you can issue an HTTP PUT and POST request.

PUT /{cacheName}/{cacheKey}

POST /{cacheName}/{cacheKey}

In order to retrieve elements from the cache you can use HTTP GET request:

GET /{cacheName}/{cacheKey}

In order to delete elements from the cache you can issue an HTTP DELETE request:

DELETE /{cacheName}/{cacheKey}

By default infinispan has just the “___defaultcache” registered, so if you want to try out of the box the REST server, just create a REST client.

Following here is a jQuery client which puts an entry in the cache:

<html>
<head>

<title>jQuery RESTful client performing PUT</title>
 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
 
 <script type="text/javascript">

$.ajax({
type: "PUT",
url: '/infinispan/rest/___defaultcache/bucket1',
data: "Data in cache",
success: function(response){
$("#mydiv").html(response);
}
});

 
 </script>
 
</head>
<body>
<div id="mydiv"><p> </p></div>
 </body>
</html>

And here’s the corresponding page which performs a get on the bucket1 key:

<html>
<head>
 <title>jQuery RESTful client performing GET</title>
 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
 
 <script type="text/javascript">

$.ajax({
type: "GET",
url: '/infinispan/rest/___defaultcache/bucket1',
data: "",
success: function(response){
 $("#mydiv").html(response);

}
});

 
 </script>
 
</head>
<body>
<div id="mydiv"><p> </p></div>
 </body>
</html>

Do I need to download jQuery to run this sample ? no at all. jQuery is accessed on the cloud via <script src=”http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js”></script>. If you cannot reach the web from there, of course download jquery.js and place it on the server’s path.

Found the article helpful? if so please follow us on Socials