Comparison

mod_pubsub_serverinfo/mod_pubsub_serverinfo.lua @ 5827:c3eeeb968403

mod_pubsub_serverinfo: Detect existence of pub/sub node Instead of blindly trying to create the pub/sub node to publish items to, a service discovery query is performed to check if node creation is required. Added various bits of warn and debug logging, to give a user better feedback if and why something is failing.
author Guus der Kinderen <guus.der.kinderen@gmail.com>
date Thu, 04 Jan 2024 11:59:35 +0100
parent 5826:f55e65315ba0
child 5828:55b99f593c3a
comparison
equal deleted inserted replaced
5826:f55e65315ba0 5827:c3eeeb968403
9 local publication_interval = module:get_option(module.name .. "_publication_interval") or 300; 9 local publication_interval = module:get_option(module.name .. "_publication_interval") or 300;
10 10
11 local opt_in_reports 11 local opt_in_reports
12 12
13 function module.load() 13 function module.load()
14 -- Will error out with a 'conflict' if the node already exists. TODO: create the node only when it's missing. 14 discover_node():next(
15 create_node():next() 15 function(exists)
16 if not exists then create_node() end
17 end
18 ):catch(
19 function(error)
20 module:log("warn", "Error prevented discovery or creation of pub/sub node at %s: %s", service, error)
21 end
22 )
16 23
17 module:add_feature("urn:xmpp:serverinfo:0"); 24 module:add_feature("urn:xmpp:serverinfo:0");
18 25
19 module:add_extension(dataform { 26 module:add_extension(dataform {
20 { name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/network/serverinfo" }, 27 { name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/network/serverinfo" },
27 function module.unload() 34 function module.unload()
28 -- This removes all subscribers, which may or may not be desirable, depending on the reason for the unload. 35 -- This removes all subscribers, which may or may not be desirable, depending on the reason for the unload.
29 delete_node(); -- Should this block, to delay unload() until the node is deleted? 36 delete_node(); -- Should this block, to delay unload() until the node is deleted?
30 end 37 end
31 38
32 -- Returns a promise 39 -- Returns a promise of a boolean
40 function discover_node()
41 local request = st.iq({ type = "get", to = service, from = actor, id = new_id() })
42 :tag("query", { xmlns = "http://jabber.org/protocol/disco#items" })
43
44 module:log("debug", "Sending request to discover existence of pub/sub node '%s' at %s", node, service)
45 return module:send_iq(request):next(
46 function(response)
47 if response.stanza == nil or response.stanza.attr.type ~= "result" then
48 module:log("warn", "Unexpected response to service discovery items request at %s: %s", service, response.stanza)
49 return false
50 end
51
52 local query = response.stanza:get_child("query", "http://jabber.org/protocol/disco#items")
53 if query ~= nil then
54 for item in query:childtags("item") do
55 if item.attr.jid == service and item.attr.node == node then
56 module:log("debug", "pub/sub node '%s' at %s does exists.", node, service)
57 return true
58 end
59 end
60 end
61 module:log("debug", "pub/sub node '%s' at %s does not exist.", node, service)
62 return false;
63 end
64 );
65 end
66
67 -- Returns a promise of a boolean
33 function create_node() 68 function create_node()
34 local request = st.iq({ type = "set", to = service, from = actor, id = new_id() }) 69 local request = st.iq({ type = "set", to = service, from = actor, id = new_id() })
35 :tag("pubsub", { xmlns = "http://jabber.org/protocol/pubsub" }) 70 :tag("pubsub", { xmlns = "http://jabber.org/protocol/pubsub" })
36 :tag("create", { node = node }):up() 71 :tag("create", { node = node }):up()
37 :tag("configure") 72 :tag("configure")
42 :tag("field", { var = "pubsub#max_items" }) 77 :tag("field", { var = "pubsub#max_items" })
43 :text_tag("value", "1") 78 :text_tag("value", "1")
44 :up() 79 :up()
45 :tag("field", { var = "pubsub#persist_items" }) 80 :tag("field", { var = "pubsub#persist_items" })
46 :text_tag("value", "0") 81 :text_tag("value", "0")
47 return module:send_iq(request); 82
48 end 83 module:log("debug", "Sending request to create pub/sub node '%s' at %s", node, service)
49 84 return module:send_iq(request):next(
50 -- Returns a promise 85 function(response)
86 if response.stanza == nil or response.stanza.attr.type ~= "result" then
87 module:log("warn", "Unexpected response to pub/sub node '%s' creation request at %s: %s", node, service, response.stanza)
88 return false
89 else
90 module:log("debug", "Successfully created pub/sub node '%s' at %s", node, service)
91 return true
92 end
93 end
94 )
95 end
96
97 -- Returns a promise of a boolean
51 function delete_node() 98 function delete_node()
52 local request = st.iq({ type = "set", to = service, from = actor, id = new_id() }) 99 local request = st.iq({ type = "set", to = service, from = actor, id = new_id() })
53 :tag("pubsub", { xmlns = "http://jabber.org/protocol/pubsub" }) 100 :tag("pubsub", { xmlns = "http://jabber.org/protocol/pubsub" })
54 :tag("delete", { node = node }); 101 :tag("delete", { node = node });
55 102
56 return module:send_iq(request); 103 module:log("debug", "Sending request to delete pub/sub node '%s' at %s", node, service)
104 return module:send_iq(request):next(
105 function(response)
106 if response.stanza == nil or response.stanza.attr.type ~= "result" then
107 module:log("warn", "Unexpected response to pub/sub node '%s' deletion request at %s: %s", node, service, response.stanza)
108 return false
109 else
110 module:log("debug", "Successfully deleted pub/sub node '%s' at %s", node, service)
111 return true
112 end
113 end
114 )
57 end 115 end
58 116
59 function publish_serverinfo() 117 function publish_serverinfo()
60 -- Iterate over s2s sessions, adding them to a multimap, where the key is the local domain name, 118 -- Iterate over s2s sessions, adding them to a multimap, where the key is the local domain name,
61 -- mapped to a collection of remote domain names. De-duplicate all remote domain names by using 119 -- mapped to a collection of remote domain names. De-duplicate all remote domain names by using
110 end 168 end
111 end 169 end
112 170
113 request:up():up() 171 request:up():up()
114 172
115 module:send_iq(request):next() 173 module:send_iq(request):next(
174 function(response)
175 if response.stanza == nil or response.stanza.attr.type ~= "result" then
176 module:log("warn", "Unexpected response to item publication at pub/sub node '%s' on %s: %s", node, service, response.stanza)
177 return false
178 else
179 module:log("debug", "Successfully published item on pub/sub node '%s' at %s", node, service)
180 return true
181 end
182 end,
183 function(error)
184 module:log("warn", "Error prevented publication of item on pub/sub node at %s: %s", service, error)
185 end
186 )
116 187
117 return publication_interval; 188 return publication_interval;
118 end 189 end
119 190
120 local opt_in_cache = {} 191 local opt_in_cache = {}