diff --git a/debian/control b/debian/control index 7a19af7..f7bc9bf 100644 --- a/debian/control +++ b/debian/control @@ -14,6 +14,7 @@ Depends: lua-argparse, lua-cjson, lua-curl, + lua-redis (>= 2.0.5~git20141117.880dda9-7~), lua-sql-mysql (>= 2.4.0), lua5.1, ngcp-system-tools-ce | ngcp-system-tools, diff --git a/ngcp/push.lua b/ngcp/push.lua index 3ba87d0..bbf1658 100644 --- a/ngcp/push.lua +++ b/ngcp/push.lua @@ -72,7 +72,8 @@ function NGCPPush:len(key, node) end local function value_base(v) - return v.idx .. separator .. v.label .. separator .. v.node .. separator .. v.node_uri .. separator .. v.mode + return v.idx .. separator .. v.label .. separator .. v.node .. separator + .. v.node_uri .. separator .. v.mode .. separator .. v.joined end function NGCPPush:add(v) @@ -99,16 +100,48 @@ end local function split_val(value) local t = utils.explode(separator, value); - return t[1], t[2], t[3], t[4], t[5], t[6]; + return t[1], t[2], t[3], t[4], t[5], t[6], tonumber(t[7]); end local function insert_val(res, v, key_name) - local key, idx, label, node, node_uri, mode = split_val(v) - local val = {idx=idx, label=label, node=node, node_uri=node_uri, mode=mode} + local key, idx, label, node, node_uri, mode, joined = split_val(v) + local val = {idx=idx, label=label, node=node, node_uri=node_uri, mode=mode, joined=joined} val[key_name] = key table.insert(res, val) end +function NGCPPush:set(v, key_name, value) + if key_name == 'key' or key_name == 'callid' then + error(string.format("key[%s] not allowed to change", key_name)) + end + if not self.redis:test_connection() then + self.redis:connect() + end + local val_base = value_base(v) + local val = v.callid.. separator ..val_base + local pos = self.redis.client:lpos(v.key, val) + if not pos then + error(string.format("old value[%s] not found in key[%s]", val, v.key)) + end + v[key_name] = value + local new_val_base = value_base(v) + local new_val = v.callid.. separator ..new_val_base + self.redis.client:lset(v.key, pos, new_val) + KSR.dbg(string.format("lset[%s][%s]=>[%s]\n", + v.key, tostring(pos), new_val)); + + val = v.key .. separator .. val_base + pos = self.redis.client:lpos(v.callid, val) + if not pos then + error(string.format("old value[%s] not found in callid[%s]", val, v.callid)) + end + new_val = v.key.. separator ..new_val_base + self.redis.client:lset(v.callid, pos, new_val) + KSR.dbg(string.format("lset[%s]=>[%s] %s\n", + v.callid, tostring(pos), new_val)); + return v +end + function NGCPPush:get(key) if not self.redis:test_connection() then self.redis:connect() diff --git a/tests/ngcp_push.lua b/tests/ngcp_push.lua index 72a66e4..ab33916 100644 --- a/tests/ngcp_push.lua +++ b/tests/ngcp_push.lua @@ -55,13 +55,14 @@ TestNGCPPush = {} --class node="node", node_uri="node_uri", mode="stored", + joined=0, } end function TestNGCPPush:test_add() self.redis:ping() ;mc :returns(true) - self.redis:lpush("whatever", "callid_A#0#label#node#node_uri#stored") ;mc :returns(1) - self.redis:lpush("callid_A", "whatever#0#label#node#node_uri#stored") ;mc :returns(1) + self.redis:lpush("whatever", "callid_A#0#label#node#node_uri#stored#0") ;mc :returns(1) + self.redis:lpush("callid_A", "whatever#0#label#node#node_uri#stored#0") ;mc :returns(1) mc:replay() self.push:add(self.v) @@ -70,13 +71,13 @@ TestNGCPPush = {} --class function TestNGCPPush:test_del_ok() self.redis:ping() ;mc :returns(true) - self.redis:lrem("whatever", 0, "callid_A#0#label#node#node_uri#stored") ;mc :returns(1) + self.redis:lrem("whatever", 0, "callid_A#0#label#node#node_uri#stored#0") ;mc :returns(1) self.redis:llen("whatever") ;mc :returns(0) self.redis:ping() ;mc :returns(true) self.redis:del("whatever") - self.redis:lrem("callid_A", 0, "whatever#0#label#node#node_uri#stored") ;mc :returns(1) + self.redis:lrem("callid_A", 0, "whatever#0#label#node#node_uri#stored#0") ;mc :returns(1) self.redis:llen("callid_A") ;mc :returns(1) mc:replay() @@ -89,13 +90,13 @@ TestNGCPPush = {} --class -- Note that non-existing keys are treated like empty lists, -- so when key does not exist, the command will always return 0. self.redis:ping() ;mc :returns(true) - self.redis:lrem("whatever", 0, "callid_A#0#label#node#node_uri#stored") ;mc :returns(0) + self.redis:lrem("whatever", 0, "callid_A#0#label#node#node_uri#stored#0") ;mc :returns(0) self.redis:llen("whatever") ;mc :returns(0) self.redis:ping() ;mc :returns(true) self.redis:del("whatever") ;mc :returns(0) - self.redis:lrem("callid_A", 0, "whatever#0#label#node#node_uri#stored") ;mc :returns(0) + self.redis:lrem("callid_A", 0, "whatever#0#label#node#node_uri#stored#0") ;mc :returns(0) self.redis:llen("callid_A") ;mc :returns(0) self.redis:del("callid_A") ;mc :returns(0) @@ -107,7 +108,7 @@ TestNGCPPush = {} --class function TestNGCPPush:test_callid_get() self.redis:ping() ;mc :returns(true) - self.redis:lrange("callid_A", 0, -1) ;mc :returns({"whatever#0#label#node#node_uri#stored"}) + self.redis:lrange("callid_A", 0, -1) ;mc :returns({"whatever#0#label#node#node_uri#stored#0"}) mc:replay() local res = self.push:callid_get("callid_A") @@ -129,7 +130,7 @@ TestNGCPPush = {} --class function TestNGCPPush:test_get() self.redis:ping() ;mc :returns(true) - self.redis:lrange("whatever", 0, -1) ;mc :returns({"callid_A#0#label#node#node_uri#stored"}) + self.redis:lrange("whatever", 0, -1) ;mc :returns({"callid_A#0#label#node#node_uri#stored#0"}) mc:replay() local res = self.push:callid_get("whatever") @@ -149,5 +150,38 @@ TestNGCPPush = {} --class mc:verify() lu.assertEquals(res, {}) end + + function TestNGCPPush:test_set_joined() + self.redis:ping() ;mc :returns(true) + self.redis:lpos("whatever", "callid_A#0#label#node#node_uri#stored#0") ;mc :returns(1) + self.redis:lset("whatever", 1, "callid_A#0#label#node#node_uri#stored#1") ;mc :returns(1) + + self.redis:lpos("callid_A", "whatever#0#label#node#node_uri#stored#0") ;mc :returns(2) + self.redis:lset("callid_A", 2, "whatever#0#label#node#node_uri#stored#1") ;mc :returns(1) + + mc:replay() + local res = self.push:set(self.v, 'joined', 1) + mc:verify() + lu.assertNotNil(res) + lu.assertEquals(res.joined, 1) + end + + function TestNGCPPush:test_set_ko() + self.redis:ping() ;mc :returns(true) + self.redis:lpos("whatever", "callid_A#0#label#node#node_uri#stored#0") ;mc :returns(nil) + + mc:replay() + lu.assertErrorMsgContains( + 'not found in key[whatever]', self.push.set, self.push, self.v, 'joined', 1) + mc:verify() + end + + function TestNGCPPush:test_set_ko_key() + + mc:replay() + lu.assertErrorMsgContains( + 'key[key] not allowed to change', self.push.set, self.push, self.v, 'key', "nono") + mc:verify() + end -- class TestNGCPPush --EOF