#ignite-964: add CACHE_GET_AND_PUT_IF_ABSENT method for nodejs cache.
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/16ff838d Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/16ff838d Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/16ff838d Branch: refs/heads/ignite-964 Commit: 16ff838df8f019d81c41ea2eb884bc849a2aa4d4 Parents: 943d2db Author: ivasilinets <ivasilin...@gridgain.com> Authored: Wed Jul 1 15:39:49 2015 +0300 Committer: ivasilinets <ivasilin...@gridgain.com> Committed: Wed Jul 1 15:39:49 2015 +0300 ---------------------------------------------------------------------- .../processors/rest/GridRestCommand.java | 3 ++ .../processors/rest/GridRestProcessor.java | 1 + .../handlers/cache/GridCacheCommandHandler.java | 37 ++++++++++++++++++-- modules/nodejs/src/main/js/cache.js | 15 +++++++- .../ignite/internal/NodeJsCacheApiSelfTest.java | 7 ++++ modules/nodejs/src/test/js/test-cache-api.js | 25 +++++++++---- .../http/jetty/GridJettyRestHandler.java | 4 ++- 7 files changed, 82 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/16ff838d/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java index 2d9a159..5a11faf 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java @@ -45,6 +45,9 @@ public enum GridRestCommand { /** Store value in cache and return previous value. */ CACHE_GET_AND_PUT("getandput"), + /** Store value in cache and return previous value. */ + CACHE_GET_AND_PUT_IF_ABSENT("getandputifabsent"), + /** Store value in cache. */ CACHE_PUT("put"), http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/16ff838d/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java index ee9bfce..14811f3 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java @@ -549,6 +549,7 @@ public class GridRestProcessor extends GridProcessorAdapter { case CACHE_APPEND: case CACHE_PREPEND: case CACHE_GET_AND_PUT: + case CACHE_GET_AND_PUT_IF_ABSENT: perm = SecurityPermission.CACHE_PUT; name = ((GridRestCacheRequest)req).cacheName(); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/16ff838d/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java index 5d7f24a..798d151 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java @@ -57,6 +57,7 @@ public class GridCacheCommandHandler extends GridRestCommandHandlerAdapter { CACHE_CONTAINS_KEY, CACHE_GET, CACHE_GET_AND_PUT, + CACHE_GET_AND_PUT_IF_ABSENT, CACHE_GET_ALL, CACHE_PUT, CACHE_ADD, @@ -75,6 +76,7 @@ public class GridCacheCommandHandler extends GridRestCommandHandlerAdapter { CACHE_CONTAINS_KEY, CACHE_GET, CACHE_GET_AND_PUT, + CACHE_GET_AND_PUT_IF_ABSENT, CACHE_PUT, CACHE_ADD, CACHE_REMOVE, @@ -175,6 +177,18 @@ public class GridCacheCommandHandler extends GridRestCommandHandlerAdapter { break; } + case CACHE_GET_AND_PUT_IF_ABSENT: { + final Object val = req0.value(); + + if (val == null) + throw new IgniteCheckedException(GridRestCommandHandlerAdapter.missingParameter("val")); + + fut = executeCommand(req.destinationId(), req.clientId(), cacheName, skipStore, key, + new GetAndPutIfAbsentCommand(key, val)); + + break; + } + case CACHE_GET_ALL: { fut = executeCommand(req.destinationId(), req.clientId(), cacheName, skipStore, key, new GetAllCommand(getKeys(req0))); @@ -810,10 +824,10 @@ public class GridCacheCommandHandler extends GridRestCommandHandlerAdapter { private static final long serialVersionUID = 0L; /** Key. */ - private final Object key; + protected final Object key; /** Value.*/ - private final Object val; + protected final Object val; /** * @param key Key. @@ -831,6 +845,25 @@ public class GridCacheCommandHandler extends GridRestCommandHandlerAdapter { } /** */ + private static class GetAndPutIfAbsentCommand extends GetAndPutCommand { + /** */ + private static final long serialVersionUID = 0L; + + /** + * @param key Key. + * @param val Value. + */ + GetAndPutIfAbsentCommand(Object key, Object val) { + super(key, val); + } + + /** {@inheritDoc} */ + @Override public IgniteInternalFuture<?> applyx(IgniteInternalCache<Object, Object> c, GridKernalContext ctx) { + return c.getAndPutIfAbsentAsync(key, val); + } + } + + /** */ private static class GetAllCommand extends CacheProjectionCommand { /** */ private static final long serialVersionUID = 0L; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/16ff838d/modules/nodejs/src/main/js/cache.js ---------------------------------------------------------------------- diff --git a/modules/nodejs/src/main/js/cache.js b/modules/nodejs/src/main/js/cache.js index 4ac07f8..17abd2a 100644 --- a/modules/nodejs/src/main/js/cache.js +++ b/modules/nodejs/src/main/js/cache.js @@ -152,7 +152,7 @@ Cache.prototype.containsKeys = function(keys, callback) { } /** - * Put cache value + * Get and put cache value * * @this {Cache} * @param {string} key Key @@ -165,6 +165,19 @@ Cache.prototype.getAndPut = function(key, val, callback) { } /** + * Stores given key-value pair in cache only if cache had no previous mapping for it. + * + * @this {Cache} + * @param {string} key Key + * @param {string} value Value + * @param {onGet} callback Called on finish + */ +Cache.prototype.getAndPutIfAbsent = function(key, val, callback) { + this._server.runCommand(this._createCommand("getandputifabsent"). + setPostData(JSON.stringify({"key" : key, "val" : val})), callback); +} + +/** * Execute sql query * * @param {SqlQuery|SqlFieldsQuery} qry Query http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/16ff838d/modules/nodejs/src/test/java/org/apache/ignite/internal/NodeJsCacheApiSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/nodejs/src/test/java/org/apache/ignite/internal/NodeJsCacheApiSelfTest.java b/modules/nodejs/src/test/java/org/apache/ignite/internal/NodeJsCacheApiSelfTest.java index d79debc..8ae8c7b 100644 --- a/modules/nodejs/src/test/java/org/apache/ignite/internal/NodeJsCacheApiSelfTest.java +++ b/modules/nodejs/src/test/java/org/apache/ignite/internal/NodeJsCacheApiSelfTest.java @@ -133,4 +133,11 @@ public class NodeJsCacheApiSelfTest extends NodeJsAbstractTest { public void testGetAndPut() throws Exception { runJsScript("testGetAndPut"); } + + /** + * @throws Exception If failed. + */ + public void testGetAndPutIfAbsent() throws Exception { + runJsScript("testGetAndPutIfAbsent"); + } } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/16ff838d/modules/nodejs/src/test/js/test-cache-api.js ---------------------------------------------------------------------- diff --git a/modules/nodejs/src/test/js/test-cache-api.js b/modules/nodejs/src/test/js/test-cache-api.js index 904a65f..9b28b4e 100644 --- a/modules/nodejs/src/test/js/test-cache-api.js +++ b/modules/nodejs/src/test/js/test-cache-api.js @@ -78,13 +78,28 @@ testGetAndPut = function() { TestUtils.testDone(); } - function getAndPut(cache, entry) { + function getAndPut(cache, entry, next) { cache.getAndPut("key", "7", onGetAndPut); } startTest("mycache", {trace: [put, getAndPut], entry: ["key", "6"]}); } +testGetAndPutIfAbsent = function() { + function getAndPutIfAbsent(cache, entry, next) { + cache.getAndPutIfAbsent("key", "7", onGetAndPutIfAbsent); + + function onGetAndPutIfAbsent(err, res) { + assert(err === null, "Get error on get and put [err=" + err + "]"); + assert(res === "6", "Incorrect result for getAndPut [expected=6, val" + res + "]"); + + next(); + } + } + + startTest("mycache", {trace: [put, getAndPutIfAbsent, getExist], entry: ["key", "6"]}); +} + function objectEntries() { entries = []; @@ -187,15 +202,13 @@ function notContainsKeys(cache, entries, next) { } function getExist(cache, entry, next) { - var key = Object.keys(entry)[0]; - - cache.get(entry[0], onGet); - function onGet(error, value) { assert(!error); - assert(value === entry[1]); + assert(value === entry[1], "Get incorrect value on get [exp=" + entry[1] + ", val=" + value + "]"); next(); } + + cache.get(entry[0], onGet); } function remove(cache, entry, next) { http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/16ff838d/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java ---------------------------------------------------------------------- diff --git a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java index 029129b..d190163 100644 --- a/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java +++ b/modules/rest-http/src/main/java/org/apache/ignite/internal/processors/rest/protocols/http/jetty/GridJettyRestHandler.java @@ -367,6 +367,7 @@ public class GridJettyRestHandler extends AbstractHandler { case CACHE_GET: case CACHE_GET_ALL: case CACHE_GET_AND_PUT: + case CACHE_GET_AND_PUT_IF_ABSENT: case CACHE_PUT: case CACHE_PUT_ALL: case CACHE_REMOVE: @@ -415,7 +416,8 @@ public class GridJettyRestHandler extends AbstractHandler { restReq0.values(map); } else if (cmd == CACHE_GET || cmd == CACHE_PUT || cmd == CACHE_REMOVE || - cmd == CACHE_CONTAINS_KEY || cmd == CACHE_GET_AND_PUT) { + cmd == CACHE_CONTAINS_KEY || cmd == CACHE_GET_AND_PUT || + cmd == CACHE_GET_AND_PUT_IF_ABSENT) { JSONCacheObject cacheObj = new JSONCacheObject(o); restReq0.cacheName(F.isEmpty(cacheName) ? null : cacheName);