Welcome to Tigase PubSub component guide
1. PubSub Component
Tigase’s Publish Subscribe component is an XEP-0060 compliant plugin handling all publish and subscribe activity within Tigase server. This is enabled as default with the pubsub name, however you may include the following line if you wish to customize it’s configuration.
pubsub () {}
You may change the name so long as you specify the pubsub class within parenthesis.
1.1. Tigase Pubsub Release Notes
Welcome to Tigase Pubsub 5.0.0! This is a feature release for with a number of fixes and updates.
1.1.1. Tigase PubSub 5.1.0 Release Notes
All Changes
Added support for mam2#extended; #mam-73
Improving processing of presence and sending last published item; #pubsub-133
Fix NPE in UnsubscribeNodeModule; #pubsub-130
Fixed issue with MAM returning incorrect entries for MAM capable PubSub nodes; #pubsub-131
1.1.2. Previous Releases
1.1.3. Tigase PubSub 5.0.0 Release Notes
Major Changes
Add publishing executor with rate limiting
Optimisations and fixes
All Changes
#pubsub-102: Add publishing executor with rate limiting
#pubsub-103: Empty message notification id attribute
#pubsub-105: NPE in RetrieveItemsModule
#pubsub-106: NPE in PubsubPublishModule?Eventbus
#pubsub-107: disco#items feature returned on disco#info request for PubSub node item
#pubsub-108: Fix Missing notification for published events
#pubsub-110: Fix Deadlock in TigPubSubRemoveService SP on MySQL
#pubsub-111: Fix SQLException: At least one parameter to the current statement is uninitialized.
#pubsub-113: Fix StackOverflowError in LRUCacheWithFuture
#pubsub-114: Fix pubsub#persist_items is not advertised
#pubsub-115: Fix Cannot add or update a child row: a foreign key constraint fails (
tigasedb
.tig_pubsub_items
, CONSTRAINTtig_pubsub_items_ibfk_1
FOREIGN KEY (node_id
) REFERENCEStig_pubsub_nodes
(node_id
))#pubsub-119: Fix NPE in DiscoveryModule
#pubsub-120: Fix Empty element in POST payload is incorrectly parsed
#pubsub-121: Use String.intern() for PEP CAPS nodes string
#pubsub-124: Fix PubSub sends notifications about last published item on each presence received from subscriber.
#pubsub-125: Reported features
pubsub#metadata
should bepubsub#meta-data
#pubsub-126: Fix Deadlocks in MySQL schema
#pubsub-127: Fix NPE in UserEntry.remove
#pubsub-128: Fix PatternSyntaxException for users with emoticons in resource
Announcement
Major changes
Tigase pubsub component has undergone a few major changes to our code and structure. To continue to use Tigase pubsub component, a few changes may be needed to be made to your systems. Please see them below:
Database schema changes
Current version comes with changes to database schema to improve JID comparison during lookup of nodes, subscriptions, affiliations, etc.
To continue usage of new versions of pubsub component it is required to manually load new component database schema, see database preparation section for more information.
Warning
Loading of new database schema is required to use new version of pubsub component.
Changes in REST API
We continuously work on improving usability and making our REST API easier to use we added support for handling JSON requests in REST API for pubsub. At the same time we decided to slightly modify responses in XML sent by REST API to make responses in JSON and XML similar.
For more informations about current REST API please look into Rest API section.
New features
Support for using separate database for different domains
Since this version it is possible to use separate pubsub nodes and items based on domains. This allows you to configure component to store informations about nodes and items for particular domain to different database.
For more informations please look into using multiple databases.
Support for MAM
In this version we added support for XEP-0313: Message Archive Management protocol which allows any MAM compatible XMPP client with pubsub support to retrieve items published on pubsub nodes using MAM protocol for querying.
1.2. Configuration
1.2.1. Pubsub naming
Within Tigase, all pubsub component address MUST be domain-based address and not a JID style address. This was made to simplify communications structure. Tigase will automatically set component names to pubsub.domain, however any messages send to pubsub@domain will result in a SERVICE_UNAVAILABLE
error.
Pubsub nodes within Tigase can be found as a combination of JID and node where nodes will be identified akin to service discovery. For example, to address a friendly node, use the following structure:
<iq to='pubsub.domain'>
<query node='friendly node'/>
</iq>
1.2.2. Configure Roster Maximum size
Administrators can configure the maximum allowable roster size per user via the config.tdsl file.
'sess-man' {
'jabber:iqa:roster' {
max_roster_size = '100'
}
}
This sets the roster limit to 100 entries per user. It can be set to any integer, however by default no limit is set and no configuration is set in config.tdsl
file.
1.2.3. Store Full XML of Last Presence
Tigase can store a more detailed <unavailable/>
presence stanza to include timestamps and other information.
Requirements
Ensure that presence-offline
plugin is enabled in config.tdsl. To do this, add be sure presence-offline
is listed under sess-man
'sess-man' {
'presence-offline' () {}
}
The following two lines in sess-man
configure options to broadcast probes to offline users.
'sess-man' {
'skip-offline' = 'false'
'skip-offline-sys' = 'false'
}
Without these lines, Tigase will not send presence probes to users that the server knows to be offline.
The full XML presence is stored under the tig_pairs table with a pkey of last-unavailable-presence
will look like this:
<presence from="[email protected]" xmlns="jabber:client" type="unavailable">
<status>Logged out</status>
<delay stamp="2015-12-29T16:51:50.748Z" xmlns="urn:xmpp:delay"/></presence>
As you can see, the plugin has added a delay stamp which indicates the last time they were seen online. This may be suppressed by using the following line in your config.tdsl file.
'sess-man' {
'delay-stamp' = 'false'
}
You may also limit probe responses only to newly connected resources.
'sess-man' {
'probe-full-jid' = 'true'
}
When a user logs on, they will receive the same full unavailable presence statements from contacts not logged in. Also the repository entry containing their last unavailable presence will be removed.
NOTE: This will increase traffic with users with many people on their rosters.
1.2.4. Using separate store
As mentioned above, by default Tigase pubsub component uses default data source configured for Tigase XMPP Server. It is possible to use separate store by pubsub component. To do so you need to configure new DataSource
in dataSource
section. Here we will use pubsub-store
as name of newly configured data source. Additionally you need to pass name of newly configured data source to dataSourceName
property of default DAO of pubsub component.
dataSource {
pubsub-store () {
uri = 'jdbc:postgresql://server/pubsub-database'
}
}
pubsub () {
dao {
default () {
dataSourceName = 'pubsub-store'
}
}
}
It is also possible to configure separate store for particular domain, ie. pubsub.example.com
. Here we will configure data source with name pubsub.example.com
and use it to store data for pubsub nodes and items at pubsub.example.com
:
dataSource {
'pubsub.example.com' () {
uri = 'jdbc:postgresql://server/example-database'
}
}
pubsub () {
dao {
'pubsub.example.com' () {
# we may not set dataSourceName as it matches name of domain
}
}
}
Note
With this configuration, data for other domains than pubsub.example.com
will be stored in default data source.
1.2.5. Enabling PEP support
To enable XEP-0163: Personal Eventing Protocol support it is required to set persistent-pep
property of pubsub component to true
, set send-last-published-item-on-presence
property of component to true
and enable pep
SessionManager processor.
pubsub () {
persistent-pep = true
send-last-published-item-on-presence = true
}
sess-man () {
pep () {
}
}
Note
If your pubsub component uses different name than pubsub
then you need to set pubsub-jid
property of pep
processor to JID of pubsub component make it aware of a different name of a pubsub component.
Example with pubsub component named ``events`` hosted at server named ``servername.com`` and enabled PEP.
events () {
persistent-pep = true
send-last-published-item-on-presence = true
}
sess-man () {
pep () {
'pubsub-jid' = '[email protected]'
}
}
1.2.6. Enabling REST API
To use REST API for pubsub component it is required that:
Tigase HTTP API component is installed and configured properly. For information about HTTP API component installation please look into HTTP component documentation.
Tigase pubsub REST scripts are copied to HTTP API REST scripts directory In installation package this is already done and scripts are in proper locations. dd* JID of HTTP API component needs to be added to list of trusted jids of Tigase pubsub component
trusted
property (ifhttp
is name of HTTP API component)
pubsub () {
trusted = [ 'http@{clusterNode}' ];
}
1.2.7. Changing nodes cache size
By default Tigase pubsub component caches node configuration of 2000 last loaded nodes. If there are many requests to database to load node configuration and your installation contains many nodes it may be a good idea to increase number of cached nodes.
To do this you need to set pubsub-repository-cache-size
property of pubsub component to new size.
pubsub () {
pubsub-repository-cache-size = 4000
}
Enable sending last published item on presence
By default it is not possible to use delivery of last published item when users broadcasts initial presence. To do so you need to set send-last-published-item-on-presence
of pubsub component to true
. This will allow you to configure nodes to send last published item on presence.
pubsub () {
send-last-published-item-on-presence = true
}
1.2.8. Throttling sending notifications
Notifications sent by PubSub component may be sent in large batches, if you have a nodes with a lot of subscribers. In those cases, it is useful to throttle publications to improve behaviour and performance of other parts of Tigase XMPP Server.
To achieve that, PubSub throttles generate notifications to specified throughput. By default it is set to 5k packets for each CPU core available per second.
To set it to a different value, you can set limit
property of publishExecutor
bean to the expected number of publications per second, ie. 100000;
Note
This value is a number of total throughput, and will not be adjusted by the number of available CPU cores.
pubsub () {
publishExecutor () {
limit = 10000
}
}
Publication rate is also adjusted to current memory usage on a 4 point scale adjusted to the value of two configuration options: highMemoryUsageLimit
and criticalMemoryUsageLimit
(with default values: 90% and 98% respectively): * normal
- if memory usage is below highMemoryUsageLimit
(i.e. below 90%) * high
- memory usage less than halfway between highMemoryUsageLimit
and veryHigh
(i.e. between 90% and 94%) * veryHigh
- memory usage more than halfway between highMemoryUsageLimit
and veryHigh
(i.e. between 94% and 98%) * critical
- if memory usage is above criticalMemoryUsageLimit
(i.e. above 98%)
It’s possible to adjust values of the high and critical limits in publisher bean:
pubsub () {
publishExecutor () {
highMemoryUsageLimit = 90
criticalMemoryUsageLimit = 98
}
}
1.2.9. Disable automatic subscription of node creator
During creation of node pubsub component subscribes creator to pubsub node and delivers notifications to creator. If in your case you do not want this behavior, you may set auto-subscribe-node-creator
property of pubsub component to false
.
pubsub () {
auto-subscribe-node-creator = false
}
1.3. Database
1.3.1. Preparation of database
Before you will be able to use Tigase PubSub Component you need to initialize database. We provide few schemas for this component for MySQL, PostgreSQL, SQLServer and DerbyDB.
They are placed in database/
directory of installation package and named in dbtype-pubsub-version.sql
, where dbname
in name of database type which this schema supports and version
is version of a PubSub component for which this schema is designed.
You need to manually select schema for correct database and component and load this schema to database. For more information about loading database schema look into database preperation section of this guide.
1.3.2. Upgrade of database schema
Database schema for our components may change between versions and if so it needs to be updated before new version may be started. To upgrade schema please follow instructions from the database preperation section.
Note
If you use SNAPSHOT builds then schema may change for same version as this are versions we are still working on.
1.3.3. Schema description
Tigase PubSub component uses few tables and stored procedures. To make it easier to identify tables and stored procedures used by PubSub component they are prefixed with tig_pubsub_
.
Table tig_pubsub_service_jids
This table stores all jids for which PubSub component contains nodes.
Field |
Description |
Comments |
---|---|---|
service_id |
Database ID of a service JID |
|
service_jid |
Value of a service JID |
|
service_jid_sha1 |
SHA1 value of lowercased service JID |
Used for proper bare JID comparison during lookup. (N/A to PostgreSQL schema) |
Table tig_pubsub_jids
This table stores all jids related to PubSub nodes, ie. subscriber, affiliates, creators, publishers, etc.
Field |
Description |
Comments |
---|---|---|
jid_id |
Database ID of a bare JID |
|
jid |
Value of a bare JID |
|
jid_sha1 |
SHA1 value of lowercased bare JID |
Used for proper bare JID comparison during lookup. (N/A to PostgreSQL schema) |
Table tig_pubsub_nodes
Table stores nodes tree structure and node configuration.
Field |
Description |
Comments |
---|---|---|
node_id |
Database ID of a node |
|
service_id |
ID of service JID |
References |
name |
Name of PubSub node |
|
name_sha1 |
SHA1 of PubSub node name |
Used for indexing and faster lookup. (N/A to PostgreSQL schema) |
type |
Type of PubSub node |
0 - collection 1 - leaf |
title |
Title of PubSub node |
|
description |
Description of a node |
|
creator_id |
ID of JID of creator |
References |
creation_date |
Timestamp of creation time |
|
configuration |
Serialized configuration of PubSub node |
|
collection_id |
Points collection (parent node) |
References |
Table tig_pubsub_affiliations
Table stores affiliations between PubSub nodes and jids.
Field |
Description |
Comments |
---|---|---|
node_id |
ID of a node |
References |
jid_id |
ID of a user JID |
References |
affiliation |
Affiliation value |
Table tig_pubsub_subscriptions
Table stores subscriptions of jids to PubSub nodes.
Field |
Description |
Comments |
---|---|---|
node_id |
ID of a node |
References |
jid_id |
ID of a user JID |
References |
subscription |
Subscription value |
|
subscription_id |
Id of a subscription |
Table tig_pubsub_items
Table stores items of PubSub nodes.
Field |
Description |
Comments |
node_id |
ID of a node |
References |
id |
Id of an items |
|
id_sha1 |
SHA1 of item id |
Indexed and used for faster lookup (N/A to PostgreSQL schema) |
creation_date |
Creation date |
|
publisher_id |
ID of publisher JID |
References |
update_date |
Timestamp of last item modification |
|
data |
Item payload |
1.3.4. PubSub Schema Changes
Tigase PubSub Component is currently version 3.3.0 which is introduced in Tigase server v8.0.0.
PubSub 3.2.0 Changes
PubSub v 3.2.0 adds a new procedure TigPubSubGetNodeMeta which supports PubSub metadata retrieval while conducting a disco#info query on nodes.
You will need to upgrade your database if you are not using v3.2.0 schema. Tigase will report being unable to load PubSub component if you do not have this schema version.
The MySQL schema can be found Here.
The Derby schema can be found Here.
The PostGRESQL schema can be found Here.
The MS SQL schema can be found Here.
The same files are also included in all distributions of v8.0.0 in [tigaseroot]/database/
. All changes to database schema are meant to be backward compatible.
For instructions how to manually upgrade the databases, please refer to Tigase v7.1.0 Schema Updates section.
Upgrading older installations (pre-v3.0.0 Schema)
To update older installations of Tigase to the PubSub Schema v3.0.0 follow these instructions. Note this should be done before upgrading to PubSub v3.1.0.
Step by Step guide.
Prepare Old Database for Upgrade
In database
directory of Tigase installation you will find SQL files which will prepare old database schema for upgrade using following this naming pattern: <database_type>-pubsub-schema-3.0.0-pre-upgrade.sql
Where <database_type>
can be one of the following: mysql
, sqlserver
, ie. for MySQL you will find the file mysql-pubsub-schema-3.0.0-pre-upgrade.sql
. You need to execute statements from this file on your source database, which will drop old procedures and functions used to access database and also this statements will rename old tables by adding suffix _1 to each of old tables. Example:
- MySQL
mysql -u tigase -p tigase_pubsub < database/mysql-pubsub-schema-3.0.0-pre-upgrade.sql
- MS SQL
sqlcmd -S %servername% -U %root_user% -P %root_pass% -d %database% -i database\sqlserver-pubsub-schema-3.0.0-pre-upgrade.sql
Update Tigase PubSub Component
For this you need to copy the Tigase PubSub Component jar file to jars directory inside Tigase XMPP Server installation directory. It is also recommended to copy files from database directory of Tigase PubSub Component to database directory in Tigase XMPP Server installation directory.
If you happen to use one of the the distribution packaged (either installer or -dist-max flavored archive) then all required files are already available - both new schema files will be available in database/
directory as well as both versions of PubSub component will be present in jars/
directory - PubSub3 as tigase-pubsub.jar and PubSub2 as tigase-pubsub-2.2.0.jar.old (provided for compatibility reasons).
Load New Schema
In the database
directory you will find files containing new schemas for:
MySQL -
mysql-pubsub-schema-3.0.0.sql
PostgreSQL -
postgresql-pubsub-schema-3.0.0.sql
MSSQL -
sqlserver-pubsub-schema-3.0.0.sql
DerbyDB -
derby-pubsub-schema-3.0.0.sql
andpubsub-db-create-derby.sh
For most databases, with the exception of Derby, you only need to execute statements from the proper file. For example:
- MySQL
mysql -u tigase -p tigase_pubsub < database/mysql-pubsub-schema-3.0.0.sql
- MS SQL
sqlcmd -S %servername% -U %root_user% -P %root_pass% -d %database% -i database\sqlserver-pubsub-schema-3.0.0.sql
- PostgreSQL
psql -h $DB_HOST -q -U ${USR_NAME} -d $DB_NAME -f database/sqlserver-pubsub-schema-3.0.0.sql
For DerbyDB you need to execute the pubsub-db-create-derby.sh
script and pass proper JDBC URI to database to which you want to load schema (if database does not exist, it will be created).
database/pubsub-db-create-derby.sh
NOTE: It is possible to use same database which was used before - then after upgrade you will have new tables and old tables with _1 suffix.
Execute Migration Utility
In the /database
directory you will find the pubsub-db-migrate.sh
file which you need to execute and pass arguments with JDBC URIs needed to connect to source and destination database. If you used dedicated tables for PubSub you will also need to pass a class name used to access database (value of pubsub-repo-class
variable from etc/config.tdsl
file).
Example for dedicated table used for PubSub:
database/pubsub-db-migrate.sh -in-repo-class tigase.pubsub.repository.PubSubDAO
-in 'jdbc:mysql://localhost/tigase_pubsub?user=tigase&password=passwd'
-out 'jdbc:mysql://localhost/tigase_pubsub?user=tigase&password=passwd'
Example for use without dedicated PubSub tables:
database/pubsub-db-migrate.sh
-in 'jdbc:mysql://localhost/tigase?user=tigase&password=passwd'
-out 'jdbc:mysql://localhost/tigase?user=tigase&password=passwd'
Example for use with dedicated tables in a Windows environment:
database/pubsub-db-migrate.cmd -in-repo-class tigase.pubsub.repository.PubSubDAO
-in 'jdbc:sqlserver://<hostname>\\<instance>:<port>;databaseName=<name>;user=tigase;password=tigase;schema=dbo;lastUpdateCount=false'
-out 'jdbc:sqlserver://<hostname>\\<instance>:<port>;databaseName=<name>;user=tigase;password=tigase;schema=dbo;lastUpdateCount=false'
During execution this utility will report information about migration of PubSub data to the new schema, and the same information will be store in pubsub_db_migration.log
.
Finish
After successful migration you will have all data copied to new tables. Old tables will be renamed by adding suffix _1. After verification that everything works OK, you can delete old tables and it’s content as it want be used any more.
1.4. Features
1.5. AdHoc Commands
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
.
1.5.1. Create a Node
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
1.5.2. Delete a Node
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
1.5.3. Subscribe to a Node
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
1.5.4. Unsubscribe to a Node
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
1.5.5. Publish an item to a Node
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("[email protected]")
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();
1.5.6. PubSub Node Presence Protocol
Occupant Use Case
Log in to Pubsub Node
To log in to PubSub Node user must send presence to PubSub component with additional information about node:
<presence
from='[email protected]/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='[email protected]' id='foo'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='princely_musings'>
<item>
<presence xmlns='tigase:pubsub:1' node='princely_musings' jid='[email protected]/pda' type='available'/>
</item>
</items>
</event>
</message>
<message from='pubsub.shakespeare.lit' to='[email protected]' id='bar'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='princely_musings'>
<item>
<presence xmlns='tigase:pubsub:1' node='princely_musings' jid='[email protected]/pda' type='available'/>
</item>
</items>
</event>
</message>
And then will send notification with presences of all occupants to new occupant.
Log out from PubSub Node
To logout from single node, user must send presence stanza with type unavailable:
<presence
from='[email protected]/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='[email protected]' id='foo'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='princely_musings'>
<item>
<presence xmlns='tigase:pubsub:1' node='princely_musings' jid='[email protected]/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.
Retrieving list of all Node Subscribers
To retrieve list of node subscribers, node configuration option tigase#allow_view_subscribers
must be set to true:
<iq type='set'
from='[email protected]/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='[email protected]/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='[email protected]/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
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='[email protected]' 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="[email protected]"
from="[email protected]/1149352695-tigase-20">
<body>Hello</body>
</message>
</item>
</items>
</event>
</message>
Configuration
The pubsub node must be created and configured beforehand:
Create node
<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:
Add sess-man as publisher
<iq type='set'
to='pubsub.coffeebean.local'
id='ent2'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<affiliations node='message_sink'>
<affiliation jid='[email protected]' affiliation='publisher'/>
</affiliations>
</pubsub>
</iq>
Finally, the ‘msgoffline’ offline messages processor must be configured as well
config.tdsl configuration
sess-man {
msgoffline () {
msg-pubsub-jid = 'pubsub.coffeebean.local'
msg-pubsub-node = 'message_sink'
msg-pubsub-publisher = '[email protected]'
}
}
Usage
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.
Managing Subscriptions
Add new Subscriber
<iq type='set'
to='pubsub.coffeebean.local'
id='subman2'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<subscriptions node='message_sink'>
<subscription jid='[email protected]' subscription='subscribed'/>
</subscriptions>
</pubsub>
</iq>
Remove Subscriber
<iq type='set'
to='pubsub.coffeebean.local'
id='subman2'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<subscriptions node='message_sink'>
<subscription jid='[email protected]' subscription='none'/>
</subscriptions>
</pubsub>
</iq>
1.6. REST API
All example calls to pubsub REST API are prepared for pubsub component running at pubsub.example.com
. It is required to replace this value with JID of pubsub component from your installation.
It is possible to provide parameters to requests as:
- XML
All parameters passed in content of HTTP request needs to be wrapped with
<data/>
tag as root tag of XML document, while returned parameters will be wrapped<result/>
tag as root tag of XML document.- JSON
Parameters must be passed as serialized JSON object. Additionally
Content-Type
header of HTTP request needs to be set toapplication/json
.
1.6.1. Create a node
HTTP URI: /rest/pubsub/pubsub.example.com/create-node
Available HTTP methods:
GET
Method returns example content which contains all required and optional parameters that may be passed to newly created node.
POST
Command requires fields node
and pubsub#node_type
to be filled with proper values for execution.
node
- field should contain id of node to createowner
- field may contains jid which should be used as jid of owner of newly created node (will use jid of Tigase HTTP API Component if not passed)pubsub#node_type
- should contain type of node to create (two values are possible:leaf
- node to which items will be published,collection
- node which will contain other nodes)
Example content to create node of id example
and of type leaf
and with owner set to admin@example.com
.
Using XML
Request in XML.
<data>
<node>example</node>
<owner>[email protected]</owner>
<pubsub prefix="true">
<node_type>leaf</node_type>
</pubsub>
</data>
Response in XML.
<result>
<Note type="fixed">
<value>Operation successful</value>
</Note>
</result>
Using JSON
Request in JSON.
{
"node" : "example",
"owner" : "[email protected]",
"pubsub#node_type" : "leaf"
}
Response in JSON.
{
"Note": "Operation successful"
}
1.6.2. Delete a node
HTTP URI: /rest/pubsub/pubsub.example.com/delete-node
Available HTTP methods:
GET
Method returns example content which contains all required and optional parameters that may be passed.
POST
Command requires field node
to be filled.
node
- field should contain id of node to delete
Example content to delete node with id example
Using XML
Request in XML.
<data>
<node>example</node>
</data>
Response in XML.
<result>
<Note type="fixed">
<value>Operation successful</value>
</Note>
</result>
Using JSON
Request in JSON.
{
"node" : "example"
}
Response in JSON.
{
"Note" : "Operation successful"
}
1.6.3. Subscribe to a node
HTTP URI: /rest/pubsub/pubsub.example.com/subscribe-node
Available HTTP methods:
GET
Method returns example content which contains all required and optional parameters that may be passed.
POST
Command requires fields node
and jids
to be filled.
node
- field should contain id of node to subscribe tojids
- field should contain list of jids to be subscribed to node
Example content to subscribe to node with id example
users with jid test1@example.com
and test2@example.com
Using XML
Request in XML.
<data>
<node>example</node>
<jids>
<value>[email protected]</value>
<value>[email protected]</value>
</jids>
</data>
Response in XML.
<result>
<Note type="fixed">
<value>Operation successful</value>
</Note>
</result>
Using JSON
Request in JSON.
{
"node" : "example",
"jids" : [
"[email protected]",
"[email protected]"
]
}
Response in JSON.
{
"Note" : "Operation successful"
}
1.6.4. Unsubscribe from a node
HTTP URI: /rest/pubsub/pubsub.example.com/unsubscribe-node
Available HTTP methods:
GET
Method returns example content which contains all required and optional parameters that may be passed.
POST
Command requires fields node
and jids
to be filled.
node
- field should contain id of node to unsubscribe fromjids
- field should contain list of jids to be unsubscribed from node
Example content to unsubscribe from node with id example
users test1@example.com
and test2@example.com
Using XML
Request in XML.
<data>
<node>example</node>
<jids>
<value>[email protected]</value>
<value>[email protected]</value>
</jids>
</data>
Response in XML.
<result>
<Note type="fixed">
<value>Operation successful</value>
</Note>
</result>
Using JSON
Request in JSON.
{
"node" : "example.com",
"jids" : [
"[email protected]",
"[email protected]"
]
}
Response in JSON.
{
"Note" : "Operation successful"
}
1.6.5. Publish an item to a node
HTTP URI: /rest/pubsub/pubsub.example.com/publish-item
Available HTTP methods:
GET
Method returns example content which contains all required and optional parameters that may be passed.
POST
Command requires fields node
and entry
to be filled
node
- field should contain id of node to publish toitem-id
- field may contain id of entry to publishexpire-at
- field may contain timestamp (in XEP-0082 format) after which item should not be delivered to userentry
- field should contain multi-line entry content which should be valid XML value for an item
Example content to publish item with id item-1
to node with id example
and with content in example field. P
Using XML
with XML payload
In this example we will use following XML payload:
Payload.
<item-entry>
<title>Example 1</title>
<content>Example content</content>
</item-entry>
Request in XML.
<data>
<node>example</node>
<item-id>item-1</item-id>
<expire-at>2015-05-13T16:05:00+02:00</expire-at>
<entry>
<item-entry>
<title>Example 1</title>
<content>Example content</content>
</item-entry>
</entry>
</data>
Response in XML.
<result>
<Note type="fixed">
<value>Operation successful</value>
</Note>
</result>
with JSON payload
It is possible to publish JSON payload as value of published XML element. In example below we are publishing following JSON object:
Payload.
{ "key-1" : 2, "key-2" : "value-2" }
Request in XML.
<data>
<node>example</node>
<item-id>item-1</item-id>
<expire-at>2015-05-13T16:05:00+02:00</expire-at>
<entry>
<payload>{ "key-1" : 2, "key-2" : "value-2" }</payload>
</entry>
</data>
Response in XML.
<result>
<Note type="fixed">
<value>Operation successful</value>
</Note>
</result>
Using JSON
with XML payload
To publish XML using JSON you need to set serialized XML payload as value for entry
key. In this example we will use following XML payload:
Payload.
<item-entry>
<title>Example 1</title>
<content>Example content</content>
</item-entry>
Request in JSON.
{
"node" : "example",
"item-id" : "item-1",
"expire-at" : "2015-05-13T16:05:00+02:00",
"entry" : "<item-entry>
<title>Example 1</title>
<content>Example content</content>
</item-entry>"
}
Response in JSON.
{
"Note" : "Operation successful"
}
with JSON payload
As JSON needs to be set as a value of an XML element it will be wrapped on server side as a value for <payload/>
element.
Payload.
{ "key-1" : 2, "key-2" : "value-2" }
Request in JSON.
{
"node" : "example",
"item-id" : "item-1",
"expire-at" : "2015-05-13T16:05:00+02:00",
"entry" : {
"key-1" : 2,
"key-2" : "value-2"
}
}
Response in JSON.
{
"Note" : "Operation successful"
}
Published item.
<payload>{ "key-1" : 2, "key-2" : "value-2" }</payload>
1.6.6. Delete an item from a node
HTTP URI: /rest/pubsub/pubsub.example.com/delete-item
Available HTTP methods:
GET
Method returns example content which contains all required and optional parameters that may be passed.
POST
Command requires fields node
and item-id
to be filled
node
- field contains id of node to publish toitem-id
- field contains id of entry to publish
Example content to delete an item with id item-1
from node with id example
.
Using XML
Request in XML.
<data>
<node>example</node>
<item-id>item-1</item-id>
</data>
Response in XML.
<result>
<Note type="fixed">
<value>Operation successful</value>
</Note>
</result>
Using JSON
Request in JSON.
{
"node" : "example",
"item-id" : "item-1"
}
Response in JSON.
{
"Note" : "Operation successful"
}
1.6.7. List available nodes
HTTP URI: /rest/pubsub/pubsub.example.com/list-nodes
Available HTTP methods:
GET
Method returns list of available pubsub nodes for domain passed as part of URI (pubsub.example.com
).
Example response in XML.
<result>
<title>List of available nodes</title>
<nodes label="Nodes" type="text-multi">
<value>test</value>
<value>node_54idf40037</value>
<value>node_3ws5lz0037</value>
</nodes>
</result>
in which we see nodes: test
, node_54idf40037
and node_3ws5lz0037
.
Example response in JSON.
{
"title" : "List of available nodes",
"nodes" : [
"test",
"node_54idf40037",
"node_3ws5lz0037"
]
}
in which we see nodes: test
, node_54idf40037
and node_3ws5lz0037
.
1.6.8. List published items on node
HTTP URI: /rest/pubsub/pubsub.example.com/list-items
Available HTTP methods:
GET
Method returns example content which contains all required and optional parameters that may be passed.
POST
Command requires field node
to be filled
node
- field contains id of node which items we want to list
Example content to list of items published on node with id example
.
Using XML
Request in XML.
<data>
<node>example</node>
</data>
Response in XML.
<result>
<title>List of PubSub node items</title>
<node label="Node" type="text-single">
<value>example</value>
</node>
<items label="Items" type="text-multi">
<value>item-1</value>
<value>item-2</value>
</items>
</result>
where item-1
and item-2
are identifiers of published items for node example
.
Using JSON
Request in JSON.
{
"node" : "example"
}
Response in JSON.
{
"title" : "List of PubSub node items",
"node" : "example",
"items" : [
"item-1",
"item-2"
]
}
where item-1
and item-2
are identifiers of published items for node example
.
1.6.9. Retrieve item published on node
HTTP URI: /rest/pubsub/pubsub.example.com/retrieve-item
Available HTTP methods:
GET
Method returns example content which contains all required and optional parameters that may be passed.
POST
Command requires fields node
and item-id
to be filled
node
- field contains id of node which items we want to listitem-id
- field contains id of item to retrieve
Example content to list of items published on node with id example
.
Using XML
Request in XML.
<data>
<node>example</node>
<item-id>item-1</item>
</data>
Response in XML.
<result>
<title>Retrieve PubSub node item</title>
<node label="Node" type="text-single">
<value>example</value>
</node>
<item-id label="Item ID" type="text-single">
<value>item-1</value>
</item-id>
<item label="Item" type="text-multi">
<value>
<item expire-at="2015-05-13T14:05:00Z" id="item-1">
<item-entry>
<title>Example 1</title>
<content>Example content</content>
</item-entry>
</item>
</value>
</item>
</result>
inside item element there is XML encoded element which is published on node example
with id item-1
.
Using JSON
Request in JSON.
{
"node" : "example",
"item-id" : "item-1"
}
Response in JSON.
{
"title" : "Retrieve PubSub node item",
"node" : "example",
"item-id" : "item-1",
"item" : [
"<item expire-at\"2015-05-13T14:05:00Z\" id=\"item-1\">
<item-entry>
<title>Example 1</title>
<content>Example content</content>
</item-entry>
</item>"
]
}
1.6.10. Retrieve user subscriptions
HTTP URI: /rest/pubsub/pubsub.example.com/retrieve-user-subscriptions
Available HTTP methods:
GET
Method returns example content which contains all required and optional parameters that may be passed.
POST
Command requires field jid
to be filled.
jid
- field contains JID of a user for which we want to retrieve subscriptionsnode-pattern
- field contains regex pattern to match. When field is not empty, request will return only subscribed nodes which match this pattern. If field should be empty it may be omitted in a request.
Example content to retrieve list of nodes to which user test@example.com
is subscribed at pubsub.example.com
which starts with test-
(pattern test-.*
)
Using XML
Request in XML.
<data>
<jid>[email protected]</jid>
<node-pattern>test-.*</node-pattern>
</data>
Response in XML.
<result>
<nodes label="Nodes" type="text-multi">
<value>test-123</value>
<value>test-342</value>
</nodes>
</result>
Using JSON
Request in JSON.
{
"jid" : "[email protected]",
"node-pattern" : "test-.*"
}
Response in JSON.
{
"nodes" : [
"test-123",
"test-342"
]
}