Similar to the HTTP API, AdHoc commands based on groovy scripts can be sent to this component to do a number of tasks. All scripts for these Ad-hoc commands are found at sec/main/groovy/tigase/admin
in source distributions, or at this link. To use them, the scripts need to be copied into the scripts/admin/pubsub
folder in the Tigase installation directory.
For all examples, the component address will be pubsub.example.com
.
Ad-hoc command node: create-node
Required role: Service Administrator
Command requires fields node
and pubsub#node_type
to be filled with proper values for execution.
- node
Field containing id of node to create.
- pubsub#node_type
Contains one of two possible values.
* leaf-node
Node that will be published.
* collection
Node that will contain other nodes.
Other fields are optional fields that can be set to change configuration of newly create node to different configuration than default.
Example call using TCLMT:
bin/tclmt.sh -u admin@example.com -p admin123 remote pubsub.example.com create-node example admin@example.com leaf
Ad-hoc command node: delete-node
Required role: Service Administrator
Command requires node
field to be filled.
- node
Field containing id of node to delete.
Example call using TCLMT:
bin/tclmt.sh -u admin@example.com -p admin123 remote pubsub.example.com delete-node example
Ad-hoc command node: subscribe-node
Required role: Service Administrator
Command requires node
and jids
nodes to be filled.
- node
Field containing node to subscribe to.
- jids
Field containing list of JIDs to subscribe to the node.
Example call using TCLMT:
bin/tclmt.sh -u admin@example.com -p admin123 remote pubsub.example.com subscribe-node example admin@example.com,test1@example.com
Ad-hoc command node: unsubscribe-node
Required role: Service Administrator
Command requires node
and jids
nodes to be filled.
- node
Field containing node to unsubscribe to.
- jids
Field containing list of JIDs to unsubscribe to the node.
Example call using TCLMT:
bin/tclmt.sh -u admin@example.com -p admin123 remote pubsub.example.com unsubscribe-node example admin@example.com,test2@example.com
Ad-hoc command node: publish-item
Required role: Service Administrator
Command requires fields node
and entry
to be filled.
- node
Field containing id of node to publish to.
- item-id
Field may contain id of entry to publish, can be empty.
- entry
Field should contain multi-line entry content that should be valid XML values for items.
This command due to it’s complexity cannot be easily executed by TCLMT using default remote script which provides support for basic adhoc commands. Example call using TCLMT:
bin/tclmt.sh -u admin@example.com -p admin123 remote pubsub.example.com publish-item example item-1 '<entry><title>Example 1</title></entry>'
Example Groovy script to execute create-node command using JAXMPP2
import tigase.jaxmpp.j2se.Jaxmpp import tigase.jaxmpp.core.client.AsyncCallback import tigase.jaxmpp.core.client.exceptions.JaxmppException import tigase.jaxmpp.core.client.xmpp.stanzas.Stanza import tigase.jaxmpp.core.client.SessionObject import tigase.jaxmpp.j2se.ConnectionConfiguration import tigase.jaxmpp.core.client.xml.Element import tigase.jaxmpp.core.client.xml.DefaultElement import tigase.jaxmpp.core.client.xmpp.forms.JabberDataElement Jaxmpp jaxmpp = new Jaxmpp(); jaxmpp.with { getConnectionConfiguration().setConnectionType(ConnectionConfiguration.ConnectionType.socket) getConnectionConfiguration().setUserJID("admin@example.com") getConnectionConfiguration().setUserPassword("admin123") } jaxmpp.login(true); def packet = IQ.create(); packet.setAttribute("to", "pubsub.example.com"); Element command = new DefaultElement("command"); command.setXMLNS("http://jabber.org/protocol/commands"); command.setAttribute("node", "create-node"); packet.addChild(command); Element x = new DefaultElement("x"); x.setXMLNS("jabber:x:data"); command.addChild(x); def data = new JabberDataElement(x); data.addTextSingleField("node", "example"); data.addListSingleField("pubsub#node_type", "leaf"); jaxmpp.send(packet, new AsyncCallback() { void onError(Stanza responseStanza, tigase.jaxmpp.core.client.XMPPException.ErrorCondition error) throws JaxmppException { println "received error during processing request"; } void onSuccess(Stanza responseStanza) throws JaxmppException { x = responseStanza.getFirstChild("command").getFirstChid("x"); data = new JabberDataElement(x); def error = data.getField("Error"); println "command executed with result = " + (error ? "failure, error = " + error.getFieldValue() : "success"); } void onTimeout() { println "command timed out" } }); Thread.sleep(30000); jaxmpp.disconnect();
Occupant Use Case
To log in to PubSub Node user must send presence to PubSub component with additional information about node:
<presence from='hag66@shakespeare.lit/pda' id='n13mt3l' to='pubsub.shakespeare.lit'> <pubsub xmlns='tigase:pubsub:1' node='princely_musings'/> </presence>
Component will publish this information in node:
<message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo'> <event xmlns='http://jabber.org/protocol/pubsub#event'> <items node='princely_musings'> <item> <presence xmlns='tigase:pubsub:1' node='princely_musings' jid='hag66@shakespeare.lit/pda' type='available'/> </item> </items> </event> </message> <message from='pubsub.shakespeare.lit' to='bernardo@denmark.lit' id='bar'> <event xmlns='http://jabber.org/protocol/pubsub#event'> <items node='princely_musings'> <item> <presence xmlns='tigase:pubsub:1' node='princely_musings' jid='hag66@shakespeare.lit/pda' type='available'/> </item> </items> </event> </message>
And then will send notification with presences of all occupants to new occupant.
To logout from single node, user must send presence stanza with type unavailable:
<presence from='hag66@shakespeare.lit/pda' type='unavailable' to='pubsub.shakespeare.lit'> <pubsub xmlns='tigase:pubsub:1' node='princely_musings'/> </presence>
Component will send events to all occupants as described:
<message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo'> <event xmlns='http://jabber.org/protocol/pubsub#event'> <items node='princely_musings'> <item> <presence xmlns='tigase:pubsub:1' node='princely_musings' jid='hag66@shakespeare.lit/pda' type='unavailable'/> </item> </items> </event> </message>
If component receives presence stanza with type unavailable without specified node, then component will log out user from all nodes he logged before and publish events.
To retrieve list of node subscribers, node configuration option tigase#allow_view_subscribers
must be set to true:
<iq type='set' from='hamlet@denmark.lit/elsinore' to='pubsub.shakespeare.lit' id='config2'> <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> <configure node='princely_musings'> <x xmlns='jabber:x:data' type='submit'> <field var='FORM_TYPE' type='hidden'> <value>http://jabber.org/protocol/pubsub#node_config</value> </field> <field var='tigase#allow_view_subscribers'><value>1</value></field> </x> </configure> </pubsub> </iq>
When option is enabled, each subscriber may get list of subscribers the same way as owner.
<iq type='get' from='hamlet@denmark.lit/elsinore' to='pubsub.shakespeare.lit' id='subman1'> <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> <subscriptions node='princely_musings'/> </pubsub> </iq>
There is extension to filter returned list:
<iq type='get' from='hamlet@denmark.lit/elsinore' to='pubsub.shakespeare.lit' id='subman1'> <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> <subscriptions node='princely_musings'> <filter xmlns='tigase:pubsub:1'> <jid contains='@denmark.lit' /> </filter> </subscriptions> </pubsub> </iq>
In this example will be returned all subscriptions of users from domain "denmark.lit". == Offline Message Sink :author: Bartosz Malkowski :version: v2.0 November 2016. Reformatted for v8.0.0.
Messages sent to offline users is published in pubsub node, from where that message is sent to all the node subscribers as a pubsub notification.
<message from='pubsub.coffeebean.local' to='bard@shakespeare.lit' id='foo'> <event xmlns='http://jabber.org/protocol/pubsub#event'> <items node='message_sink'> <item id='ae890ac52d0df67ed7cfdf51b644e901'> <message type="chat" xmlns="jabber:client" id="x2ps6u0004" to="userB_h6x1bt0002@coffeebean.local" from="userA_uyhx8p0001@coffeebean.local/1149352695-tigase-20"> <body>Hello</body> </message> </item> </items> </event> </message>
The pubsub node must be created and configured beforehand:
<iq type='set' to='pubsub.coffeebean.local' id='create1'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <create node='message_sink'/> </pubsub> </iq>
After that is done, you need to add SessionManager as a publisher:
<iq type='set' to='pubsub.coffeebean.local' id='ent2'> <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> <affiliations node='message_sink'> <affiliation jid='sess-man@coffeebean.local' affiliation='publisher'/> </affiliations> </pubsub> </iq>
Finally, the 'msgoffline' offline messages processor must be configured as well
Because these sinks use a standard pubsub component, administration of the sink node is identical to any other pubsub node. XEP-0060 defines standard pubsub usage and management.
<iq type='set' to='pubsub.coffeebean.local' id='subman2'> <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> <subscriptions node='message_sink'> <subscription jid='bard@shakespeare.lit' subscription='subscribed'/> </subscriptions> </pubsub> </iq>