diff --git a/plugins/mod_shard.lua b/plugins/mod_shard.lua index 67d5616..37775b5 100644 --- a/plugins/mod_shard.lua +++ b/plugins/mod_shard.lua @@ -21,7 +21,7 @@ local shard_name = module:get_option("shard_name", nil); if not shard_name then error("shard_name not configured", 0); end - +local persistent_rooms = module:open_store("persistent", "map"); module:log("info", "%s added to shard %s", module.host, shard_name); local function build_query_result(rooms, stanza) @@ -35,42 +35,53 @@ end local function get_local_rooms(host) local rooms = set.new(); - for room in pairs(hosts[host].muc.rooms) do - rooms:add(room); + for room in hosts[host].modules.muc.live_rooms() do + rooms:add(room.jid); end return rooms; end -local function is_persistent_room(jid) - local node, host, _ = jid_split(jid); - local bare = node..'@'..host; +local function is_local_room(room_jid) + local node, host, _ = jid_split(room_jid); + if not node then return false; end - if hosts[host] and hosts[host].muc.rooms[bare] then - return hosts[host].muc.rooms[bare]._data.persistent; + if not hosts[host] or not hosts[host].modules.muc then + return false; + end + for room in hosts[host].modules.muc.live_rooms() do + if room.jid == room_jid then return true; end end return false; end -local function check_redis_info(room) - local rhost = redis_mucs.get_room_host(room); +local function is_persistent_room(jid) + local room_jid = jid_bare(jid); + local res = persistent_rooms:get(nil, room_jid); + module:log("debug", "[%s] is_persistent:%s", room_jid, tostring(res)); + if res then return true else return false end; +end + +local function check_redis_info(room_jid) + local rhost = redis_mucs.get_room_host(room_jid); + if not rhost then return; end if rhost ~= shard_name then - module:log("info", "clean wrong shard info for room[%s]", room); - redis_mucs.clean_room_host(room, rhost); - redis_mucs.set_room_host(room, shard_name); + module:log("info", "clean wrong shard info for room[%s]", room_jid); + redis_mucs.clean_room_host(room_jid, rhost); + redis_mucs.set_room_host(room_jid, shard_name); end end local function handle_room_event(event) local to = event.stanza.attr.to; local node, host, _ = jid_split(to); - local rhost, bare; + local rhost, room_jid; if node then - bare = node..'@'..host; - if not is_persistent_room(bare) and hosts[host].muc.rooms[bare] then - module:log("debug", "room[%s] is hosted here. Nothing to do", bare); - check_redis_info(bare); + room_jid = jid_bare(to); + if is_local_room(room_jid) then + module:log("debug", "room[%s] is hosted here. Nothing to do", room_jid); + check_redis_info(room_jid); return nil; end module:log("debug", "looking up target room shard for %s", to); @@ -87,19 +98,19 @@ local function handle_room_event(event) end if not rhost then - assert(bare); - if is_persistent_room(bare) then + assert(room_jid); + if is_persistent_room(room_jid) then module:log("info", - "restore missing info for persistent room[%s]", bare); - redis_mucs.set_room_host(bare, shard_name); + "restore missing info for persistent room[%s]", room_jid); + redis_mucs.set_room_host(room_jid, shard_name); else - module:log("debug", "room not found. Nothing to do"); + module:log("debug", "room[%s] not found, nothing to do", room_jid); end return nil; end if rhost == shard_name then - module:log("debug", "room is hosted here. Nothing to do"); + module:log("debug", "room[%s] is hosted here, nothing to do", room_jid); return nil end @@ -113,11 +124,11 @@ local function handle_event (event) local stop_process_local; if not host then - module:log("debug", "no host. Nothing to do here"); + module:log("debug", "no host, nothing to do here"); return nil end - if hosts[host].muc then + if hosts[host].modules.muc then module:log("debug", "to MUC %s detected", host); return handle_room_event(event); end @@ -128,7 +139,7 @@ local function handle_event (event) end if not node then - module:log("debug", "no node. Nothing to do here"); + module:log("debug", "no node, nothing to do here"); return nil end @@ -163,7 +174,7 @@ local function handle_shard_error(event) local jid = stanza.attr.to; local _, host, _ = jid_split(jid); - if hosts[host].muc then + if hosts[host].modules.muc then module:log("debug", "to MUC %s detected, clean conference %s", host, jid); redis_mucs.clean_room_host(jid, server_id) diff --git a/plugins/mod_sipwise_pushd.lua b/plugins/mod_sipwise_pushd.lua index b617031..57cbf84 100644 --- a/plugins/mod_sipwise_pushd.lua +++ b/plugins/mod_sipwise_pushd.lua @@ -13,6 +13,8 @@ local sql = require "util.sql"; local format = string.format; local jid_split = require "util.jid".split; local jid_bare = require "util.jid".bare; +local jid_host = require "util.jid".host; +local jid_resource = require "util.jid".resource; local hosts = prosody.hosts; local http = require "net.http"; local uuid = require "util.uuid"; @@ -144,8 +146,8 @@ end local function get_members(muc_room) local res = set.new(); - if muc_room and muc_room._affiliations then - for o_jid, _ in pairs(muc_room._affiliations) do + if muc_room then + for o_jid, _, _ in muc_room:each_affiliation() do res:add(o_jid); end end @@ -154,58 +156,35 @@ end local function get_occupants(muc_room) local res = set.new(); - for _, occupant in pairs(muc_room._occupants) do + for _, occupant in muc_room:each_occupant() do res:add(jid_bare(occupant.jid)); end return res; end -local function get_nick(muc_room, occ_jid) - if not occ_jid then return nil end - local bare_occ_jid = jid_bare(occ_jid) - for nick, occupant in pairs(muc_room._occupants) do - if jid_bare(occupant.jid) == bare_occ_jid then - return nick; - end - end -end - -local function get_jid_from_nick(muc_room, occ_nick) - if not occ_nick then return nil end - - for nick, occupant in pairs(muc_room._occupants) do - if occ_nick == nick then - return occupant.jid; - end - end -end - local function get_muc_room(room_jid) - local _, host, _ = jid_split(room_jid); + local host = jid_host(room_jid); - if not hosts[host]then + if not hosts[host] then module:log("warn", "host [%s] not defined", tostring(host)); return nil end - if not hosts[host].muc then + if not hosts[host].modules.muc then module:log("warn", "muc not enabled here [%s]", tostring(host)); return nil end - if not hosts[host].muc.rooms then - module:log("warn", "muc with no rooms defined at [%s]??", - tostring(host)); - return nil - end - return hosts[host].muc.rooms[jid_bare(room_jid)]; + return hosts[host].modules.muc.get_room_from_jid(jid_bare(room_jid)); end local function get_muc_caller(room_jid) - local room = get_muc_room(room_jid) + local nick = jid_resource(room_jid); + + local room = get_muc_room(room_jid); if not room then - module:log("warn", "room %s not here", room_jid); + module:log("warn", "room %s not here", jid_bare(room_jid)); return nil; end - return get_jid_from_nick(room, room_jid); + return room:get_occupant_by_nick(nick); end local function get_callee_badge(jid) @@ -251,26 +230,26 @@ local function get_muc_info(stanza, caller_info) local room; if muc_stanza then - muc['jid'] = muc_stanza.attr.jid; + muc.jid = muc_stanza.attr.jid; else - muc['jid'] = jid_bare(from); + muc.jid = jid_bare(from); end - muc['name'], muc['domain'] = jid_split(muc['jid']); - if not is_local_domain(muc['domain']) then + muc.name, muc.domain = jid_split(muc.jid); + if not is_local_domain(muc.domain) then module:log("debug", "not from local host[%s]", tostring(muc.domain)); return nil; end - local room_host = hosts[muc['domain']].muc; + local room_host = hosts[muc.domain].modules.muc; if not room_host then module:log("debug", "not from MUC host[%s]", muc.domain); return nil; end - room = room_host.rooms[muc['jid']]; + room = room_host.get_room_from_jid(muc.jid); if room then - muc['room'] = room:get_description() or muc['name']; + muc.room = room:get_description() or muc.name; if muc_stanza then - muc['invite'] = format("Group chat invitation to '%s' from %s", - muc['room'], caller_info.display_name); + muc.invite = format("Group chat invitation to '%s' from %s", + muc.room, caller_info.display_name); end return muc; end @@ -424,7 +403,7 @@ local function fire_offline_message(event, muc_room, off_jid) local stanza_c = st.clone(event.stanza); local orig_from = event.stanza.attr.from; stanza_c.attr.to = off_jid; - stanza_c.attr.from = get_nick(muc_room, orig_from); + stanza_c.attr.from = muc_room:get_occupant_jid(orig_from); module:log("debug", "stanza[%s] stanza_c[%s]", tostring(event.stanza), tostring(stanza_c)); @@ -449,10 +428,10 @@ end local function handle_muc_offline(event, room_jid) local _, host = jid_split(room_jid); - local muc = hosts[host].muc; + local muc = hosts[host].modules.muc; if muc then - local muc_room = hosts[host].muc.rooms[room_jid]; + local muc_room = muc.get_room_from_jid(room_jid); if not muc_room then module:log("debug", "muc room[%s] not here. Nothing to do", room_jid); @@ -518,9 +497,9 @@ local function handle_muc_presence(event) local room = get_muc_room(stanza.attr.to); if not room then return; end local from_jid = jid_bare(stanza.attr.from); - local affiliation = room._affiliations[from_jid]; + local affiliation = room:get_affiliation(from_jid); if affiliation ~= "owner" then - room._affiliations[from_jid] = "owner"; + room:set_affiliation(true, from_jid, "owner"); module:log("debug", "[%s] set affiliation to 'owner' for [%s]", room:get_name(), from_jid); end diff --git a/plugins/mod_sipwise_redis_mucs.lua b/plugins/mod_sipwise_redis_mucs.lua index 512b825..ebe7997 100644 --- a/plugins/mod_sipwise_redis_mucs.lua +++ b/plugins/mod_sipwise_redis_mucs.lua @@ -17,7 +17,7 @@ local redis_client; local redis_mucs = module:shared("redis_mucs"); local function test_connection() - if not redis_client then return nil end; + if not redis_client then return nil; end local ok, _ = pcall(redis_client.ping, redis_client); if not ok then redis_client = nil; @@ -33,11 +33,35 @@ end local function muc_created(event) local room = event.room; + local rhost = redis_client:get(room.jid); + if rhost then + module:log("warn", "[%s] already at %s", room.jid, rhost); + return nil; + end redis_mucs.set_room_host(room.jid, redis_config.server_id); module:log("debug", "muc-room-created %s", room.jid); end +local function muc_pre_restore(event) + local room_jid = event.jid; + local rhost = redis_client:get(room_jid); + + if rhost ~= redis_config.server_id then + module:log("warn", "[%s] already at %s", room_jid, rhost); + return false; + end + module:log("debug", "[%s] already here", room_jid); + return true; +end + +local function muc_restored(event) + local room = event.room; + + redis_mucs.set_room_host(room.jid, redis_config.server_id); + module:log("debug", "muc-room-restored %s", room.jid); +end + local function muc_destroyed(event) local room = event.room; @@ -107,6 +131,15 @@ function module.load() redis_config = module:get_option("redis_sessions_auth", redis_config); end +function shutdown_component() + local rooms = redis_mucs.get_rooms(module:get_host()); + + for room_jid in rooms do + redis_mucs.clean_room_host(room_jid, redis_config.server_id); + end +end +module:hook_global("server-stopping", shutdown_component, -300); + function module.add_host(module) local host = module:get_host(); local _type = module:get_host_type(); @@ -114,6 +147,8 @@ function module.add_host(module) if _type == "component" then module:hook("muc-room-created", muc_created, 200); module:hook("muc-room-destroyed", muc_destroyed, 200); + module:hook("muc-room-restored", muc_restored, 200); + module:hook("muc-room-pre-restore", muc_pre_restore, 200); end module:log("debug", "hooked at %s as %s", host, _type); end