1. Tigase v8.0.0 announcement

Tigase v8.0.0 Change notes and announcement

1.1. Major Changes

1.1.1. Kernel and beans configuration

Tigase now operates using a Kernel and Beans style of programming. What does this mean for Tigase and You? Good news, really. Tigase XMPP Server is now working as a Kernel program, which will operate on it’s own and handle all the core functionality of the server. Component, and non-essential functionality will now be loaded as Beans. As a user, your experience will not change all that much. However, beans can be loaded and unloaded without having to restart Tigase, meaning that the program will behave more dynamically. This means a smaller footprint on memory on resources when components are not needed, and longer uptimes without having to rest art the program! This also allows for greater flexibility for Tigase XMPP Server to be better customized for unique solutions.

1.1.2. New Configuration File Format

With the change of Tigase to a Kernel and Beans style of programming, we have also changed how the configuration file is managed. Although you will still edit the config.tdsl file like a plaintext file, a new style of formatting will be used known as DSL. Domain Specific Language may add more lines, but is a cleaner format, and provides a more secure configuration design since validation of the configuration is done at the domain level. For more information on this format and how to configure Tigase, visit DSL Configuration Guide.

1.1.3. Cluster Node Shutdown Changes

Starting with Tigase v8.0.0, users connected on clustered nodes will be able use a see-other-host strategy when a node is being shutdown. Note: This may not be compatible with all clients. The Ad-hoc command is designed for a graceful shutdown of cluster nodes as a groovy script Shutdown.groovy. This script also allows for the -timeout setting which will delay shutdown of the node, and alert all users (via a headline message) that the server will be shutdown after a time. User clients that are compatible with the command will then detect other connected clusters and maintain their connections.

If the command is being sent to shut down the whole cluster, no see-other-host implementation will be sent, however -timeout settings may still be used.

The script may be activated by an ad-hoc command, or sent using REST from remote or Tigase Admin UI.

1.1.4. Significant cleanup of code and repositories

Multiple changes have been made to the structure and coding for v8, many related to trimming size of repositories and old calls. Some of these improvements are listed here: - Empty javadocs that do not convey values have been removed. - All code is reformatted to be compliant with out codestyle guidelines. - Calls to System.out.print*() and printStackTrace() have been removed from code. - Depreciated and unused classes have been removed.

1.1.5. BouncyCastle being used for StartTLS

BouncyCastle Crypto API has now been employed to handle StartTLS negotiation. By doing this, Tigase now supports tls-unique within the SCRAM PLUS authentication implementation. This API is may be employed by calling the class in your configuration file:

c2s () {
    sslContextContainer(class: tigase.extras.bcstarttls.BCSSLContextContainer) {}
}

The BouncyCastle classes are included in the dist-max archives.

1.1.6. virtual-hosts property changes

Virtual hosts property is now able to be configured in blocks instead of an ordered list making configurations more readable. Reference Virtual-Hosts Configuration for more details.

1.1.7. All artifacts are signed

Since work began on v8.0.0 Tigase has required that all changes to Tigase XMPP Server and dependencies be signed with known certificates. This version marks the first to be totally signed.

1.1.8. Scaled Down Installation Methods

We have cleaned up installation methods for Tigase and now recommend the use of web-installer method. Binary and .jar installation methods have been removed and will no longer be produced for v8.0.0 and later. Manual installation is still available for those unable to use HTTP or browser access. Visit our Quick Start guide for instructions on these other methods.

1.1.9. Emojis now supported on Tigase XMPP Servers

Emojis are now supported on MySQL databases, however some settings may be need to be changed, although they won’t affect existing databases. Visit this section for details.

1.1.10. XEP-0215 External Service Discovery now supported

Tigase now supports XEP-0215 - External Service Discovery allowing Tigase to discover services that are not available VIA the XMPP Protocol. For setup and configuration information visit External Service Discovery Component documentation.

1.1.11. XEP-0313 Message Archive Management now supported

XEP-0313 - Message Archive Management is now supported by Tigase featuring custom enhancements like full-text search & searching by tags. MAM requires Tigase’s message archive to be enabled in the config.tdsl file, and the schema (XEP-0136 or XEP-0313) must be configured in session manager settings. To turn on MAM, see configuration guide located here.

1.1.12. XEP-0363 HTTP File Upload now supported

XEP-0363 - HTTP File Upload is now supported using Tigase HTTP API component now allowing for a more robust one-to-many file uploading option. Configuration details are available at the HTTP File Upload Component section of documentation.

1.1.13. Startup now uses bootstrapping

Tigase now uses bootstrapping to startup, which will load configuration from config.tdsl file like before. Then Tigase will begin it’s normal operations with the configuration options. All startup functions for Tigase will now run under the bootstrap bean.

1.1.14. CAPTCHA system now available for in-band registration

XEP-0077 In band registration can use Data Forms as an option to process new registrations. Now you can secure these registrations by employing a CAPTCHA solution. By enabling this option you can reduce the number of potential spammers and bots on your server.

1.1.15. Schema changes

Now each component has it’s own schema for databases, they are no longer tied into Tigase XMPP server versions making changes and updates to individual components easier, and may not disrupt all users not using certain components. See the schema update section for more details.

1.1.16. Shrinkable Statistics History

Statistics history can now be automatically made smaller if a systems memory resources are above a certain amount. By default this is enabled and will trigger when over 95% of memory is in use. Half of all existing entries will be removed at this time. The same pattern will continue to halve the available records every time the threshold is met. A hard-set minimum of 5 entries is set, so you will always have the last 5 entries. This setting may be adjusted by adding the following setting to your config.tdsl file and adjusting the integer value:

stats() {
  'stats-high-memory-level' = 95
  }

1.1.17. Statistics now available for all modules

For any bean, you may enable statistics by using the following

bean (class) {
  statistics = true
}

1.1.18. Spam Protection

Tigase XMPP Server v8.0.0 now includes some efforts to prevent spam bot accounts from running on servers.

Account Registration Limits Expanded

Account registration limits have been expanded and now you can set separate counters, or configure components individually for their own limits. Visit this section for configuration details.

Accounts created using in-band registration now will use confirmation E-mail

In an effort to create a more secure method for implementing JabberIqRegister Tigase XMPP Server will now require the use of a confirmation E-mail by default in the process. The E-mail must be valid, and accounts will be made into pending status until a user clicks the generated URI in the E-mail and activates the account. This is a plugin and must be enabled in the config.tdsl file by using the following code:

'account-registration-email-validator'() {}
Further Spam prevention

Tigase-spam component is now in dist-max, and has a numer of features described here in this section.

1.1.19. Changes in password storage

Before version 8.0.0, user passwords were stored in plaintext in the user_pw database field within tig_users table, but in plaintext. It was possible to enable storage of the MD5 hash of the password instead, however this limited authentication mechanism SASL PLAIN only. However an MD5 hash of a password is not really a secure method as it is possible to revert this mechanism using rainbow tables.

Therefore, we decided to change this and store only encrypted versions of a password in PBKDF2 form which can be easily used for SCRAM-SHA-1 authentication mechanism or SCRAM-SHA-256. SASL PLAIN mechanism can also use these encrypted passwords.

The storage of encrypted passwords is now enabled by default in v8.0.0 of Tigase.

1.1.20. Dynamic TLS Buffer

Memory Buffer for TLS no longer remains at highest buffer size needed for the server session. Buffer will now free memory during idle connections. Thus drastically improving program footprint.

1.1.21. XEP-0305 XMPP Quickstart support for C2S component has been enabled

XEP-0305 XMPP Quickstart has been enabled to improve connection on our C2S connection manager. Most improvements will be seen with our mobile clients. To enable this, use the following in your config.tdsl file:

c2s () {
  pipelining = true
}

1.1.22. Database Timestamps

Timestamps in database will be stored using UTC time.

1.1.23. Config-type properties have changed

Config-type is now configured using DSL format. Visit this section for more information. The names of different config-type properties have changed: default replaces --gen-config-def, --gen=config-all, and --gen-config-default configuration types. session-manager replaces --gen-config-sm. connection-managers replaces --gen-config-cs. component replaces --gen-config-comp. setup - is a new type of config created for initial configuration of Tigase XMPP Server.

Note
Old versions are no longer supported, you HAVE to replace old versions with the new ones manually when upgrading to v8.0.0.

1.1.24. Database Watchdog implemented

It is now possible to set connection testing to databases when connections are idle and customize the frequency with which this is done. Visit this section for more details.

1.1.25. Packet statistics expanded

Packet statistics both retrieved VIA XMPP and during graceful shutdown have now been separated to a per-XMLNS basis. This may be disabled by adding the following line to config.tdsl file: ’detailed-other-statistics' = false `

1.1.26. XEP-0016 Behavior changes

XEP states that Privacy lists should be used when no user session exists in addition to when there is. Previously, Tigase would only filter results when retrieving messages, allowing blocked users to store offline messages. This has now been changed to reflect the XEP properly, and messages will be filtered while there is no user session. If however, you wish to use the previous version, where offline messages are cached first and then filtered, you may use the following configuration:

'sess-man' {
    'jabber:iq:privacy' () {
        privacyListOfflineCache (active: true) {
          size = 20000
        }
    }
}

By default, the cache has a limit of 10000 entries, that may be set by using size bean as seen above.

1.1.27. Access Control List has new ACL modifiers

New permissions have been added to ACL including DOMAIN_OWNER and DOMAIN_ADMIN to reduce permissions checking, and add another level of fine-grained permissions. For more details, please see Tigase ACL configuration for more details.

1.1.28. Option to ignore schema-version check added

You can now skip the schema check phase for individual databases. To do this, add the following do the datasource configuration block:

DataSource () {
  default () {
    'schema-management' = false
  }
}

This will do the following: - Print a warning during repository startup. - Skip schema upgrades for the source. - Skip schema destruction for the source.

1.2. New Minor Features & Behavior Changes

  • #611 Support for Message of the Day is now enabled in Tigase XMPP Server and can be administered using XEP-0133 Service Administration.

  • #1569 Re-implemented XEP-0133 Service Administration Scripts 4.3 Disable User and 4.4 Re-enable User.

  • #1449 Monitoring modules now works in OSGi mode.

  • #1706 auto-authorize of presence subscriptions can now be set for individual vhosts.

  • #1968 Added a Proxy Wrapper to handle reconnections to database connection pool to help prevent deadlocking threads.

  • #3511 Mechanism responsible for closing XMPP in SessionManager has been changed to process all packets from TCP connection before closing connection.

  • #3802 Implementation and API of LocalEventBus and ClusteredEventBus has been unified and is now available as EventBus.

  • #3918 Session Establishment Advertisement is now optional, bringing session establishment in line with RFC 6121.

  • #4111 Changed input buffer sizing to use a ratio of 2 to 1 based on input capacity. No longer using a constant value.

  • #4212 Database schema files have been flattened and made for better organization.

  • #4501 CounterDataFileLogger now has an upper limit and will be default be shrunk to 75% if available disk space is 5% or less than 100MB.

  • #4654 PubSub component has been updated and new schema uses UTF-8 encoding when hashing database lookup.

  • #4776 Tigase DbSchemaLoader now prompts for password if one is missing from command line.

  • #4788 Push component added to dist-max archive.

  • #4814 SASL-SCRAM will now be automatically disabled if auth database uses encoded passwords.

  • #4844 External components can now have SSL socket connections assigned to them.

  • #4859 Tigase DbSchemaLoader now can support using SSL when connecting to databases.

  • #4874 Tigase Test Suite has been updated to correspond to all changes for v8.0.0.

  • #4877 In-memory repository implemented for testing ONLY.

  • #4880 Tigase config-type settings have been reduced and changed. See this section for more details.

  • #4908 Limited Ad-hoc execution to admin only within monitor component.

  • #5005 Detailed logging configuration is now available in DSL format. See xref:[customLogging] for more details.

  • #5069 Packet processed statistics now separates results based on XML Namespaces.

  • #5079 Tigase DbSchemaLoader can now process multiple .sql files in one command by using a comma separated list when calling.

  • #5086 Tigase server monitor is loaded after delay to prevent NPE during startup.

  • #5149 StanzaReceiver and StanzaSender Components have been deprecated and are no longer part of Tigase XMPP Server. Related SQL tables xmpp_stanza and short_news have also been removed from schemas.

  • #5150 All TigaseDB tables now use the tig_ prefix.

  • #5214 Check has been added if recipient exists before storing offline messages for local jid.

  • #5293 DbSchemaLoader now will fail execution instead of skipping when encountering missing files.

  • #5379 Server ready detection has been improved in testrunner.sh.

  • #5397 Webhelp Documentation will no longer be built.

  • #5422 Errors with Beans will now result in compact and more readable StackTrace print in console log.

  • #5423 System configuration will now be printed to log file as ConfigHolder.loadConfiguration output.

  • #5425 GetAnyFile and GetConfigFile scripts moved to message-router instead of basic-conf.

  • #5429 Adjusted settings for Dynamic Rostering now can use separate beans for multiple implementations.

  • #5430 BindResource is now set to FINER log level to reduce console output verbosity.

  • #5475 Setting default environment variables is now possible in config.tdsl file using env('env-1', 'def-value') lines. Details available in DSL Configuration section.

  • #5496 Destroy Schema task now added to schema manager.

  • #5583 Error messages now properly sent when offline message storage is full.

  • #5674 All components now use UTC timestamp when interacting with databases.

  • #5800 Better annotation of deprecated code, cleanup and removal code previously marked as deprecated.

  • #5964 Server version is now added to JMX statistics.

  • #5982 Remote JVM debugging configuration added to tigase.conf file, commented by default.

  • #6038 Data Source pool connections are now initialized concurrently instead of one at a time, dropping initializing time.

  • #6103 RosterElement`no longer keeps `XMPPResourceConnection instance as it is cached elsewhere. Removal results in net improvement in memory footprint.

  • #6133 Tigase now checks components against server version to ensure compatibility.

  • #6163 Groovy plugin updated to v2.4.12.

  • #6206 Separated TigaseXMLTools and TigaseUtil packages for better compatibility with JDK v9.

  • #6216 MongoDB Driver now updated to v3.5.0.

  • #6560 tigase anti-spam component now included in tigase dist-max archive.

  • #6821 Improved error reporting when errors from ConfigReader.

  • #6842 DefaultTypesConverter no longer requires case sensitive enums.

  • #7082 ClassUtilBean now handles packet filtering for packets part of Tigase Server but not containing beans, other improvements to mDNS.

  • #7433 SeeOtherHost no longer uses PropertiesBeanConfigurator to parse configuration.

  • #7446 User credentials can now be managed with Ad-hoc commands.

  • #7743 Improved error message when repository is not found.

  • #7773 Ad-hoc commands can now by executed asynchronously.

1.3. Fixes

  • #2750 Multiple artifact and depreciated file cleanup. Massive code cleanup and javadoc cleaning.

  • #3582 Schema files streamlined, and no longer embedded in code.

  • #3611 Fixed TheadExceptionHandler caused by ACS unable to read PubSub schema changes.

  • #3686 Issues with processing XHTML-IM have been fixed, and now render correctly messages with multiple CData items.

  • #3689 Packets returned from CM no longer bear the original senders' jid.

  • #3803 New call RouteEvent has been added to check to list and check events and determine which should be forwarded to other nodes.

  • #3822 Error is now thrown if listener is registered for an event that is not found in EventBus.

  • #3910 Fixed NPE in SessionManager when session is closed during execution of everyMinute method.

  • #3911 Fixed issue of dropping connections during thread load distribution.

  • #4185 Fixed an error where messages would be duplicated on stream resumption due to a counter being reset upon reconnection.

  • #4447 Fixed condition where expired messages in offline store would cause locks.

  • #4547 config.dump file now is fully compatible with init.tdsl file and DSL file formatting.

  • #4672 Fixed UnsupportedOperationException occurring during configuration of WebSocketConnectionClustered.

  • #4776 DBSchemaLoader now asks for user credentials if parameter is missing. Exceptions are no longer thrown if file specified is not found.

  • #4885 client-port-delay-listening no longer causes exception when called.

  • #4973 Changed Message History query to now include a limit when selecting items, preventing an SQLTimeoutException.

  • #5005 Fixed an issue where disabling components would result in server shutdown.

  • #5042 Fixed issue when implementing custom SASL providers, mechanisms and callback handler factories.

  • #5066 Fixed issue initializing databases using MongoDB.

  • #5076 last_login and last_logout values are now properly updated while using SASL SCRAM authentication.

  • #5084 SCRAM now checks to see if account is disabled before retrieving password.

  • #5085 Fixed too many beans implemented error in Monitor Component.

  • #5088 Removed unnecessary SASL request processing after session is closed.

  • #5118 Fixed NPE during query of privacy lists then type is missing.

  • #5303 Fixed beans not being overridden by configuration if they were registered in RegistrarBean or AbstractKernelBasedComponent.

  • #5311 Offline messages are no longer dumped from MongoDB when restarting server.

  • #5394 Loading main Derby schema no longer throws exceptions.

  • #5428 Fixed parsing of v-host per domain limit property.

  • #5450 Server no longer automatically shuts down when default or other db can not be found or accessed.

  • #5458 Fixed potential timeout arising from XMPPIOService::xmppStreamOpened() method.

  • #5480 Fixed issue in Derby DB where obtaining offline messages results in SQLException.

  • #5525 Fixed S2S invalid-namespace error being returned during connection establishment.

  • #5587 Fixed unclosed ResultSet when storing a message to AMP-offline database in Derby causing deadlock.

  • #5645 Added fix for possible NPE when failing to retrieve beans.

  • #5670 config-dump now prints configuration for inactive components and beans to log.

  • #5692 Messages sent with negative priority were being occasionally dropped and not processed to OfflineMessageHandler.

  • #5727 Fixed potential issue with MySQL procedures not being killed properly.

  • #5750 Statistics now filter out zero-value results unless FINEST level is requested.

  • #5831 Fixed occurrence of OutOfMemory error.

  • #5864 Fixed NPE when executing BOSH pre-bind script.

  • #5867 Fixed NPE occurring during configuration dump.

  • #6000 Fixed a few issues with dynamic rosters properly handling presence subscription requests.

  • #6006 Improved configuration file and DB Schema handling.

  • #6041 Fixed potential issue where vhosts DB could be overwritten by vhosts configuration in init.config.

  • #6078 Fixed ClusterConnectionManager to use custom_elements_limit instead of a fixed value.

  • #6080 Fixed Packet Filtering to not filter cluster node information requests.

  • #6083 Fixed clustered mode shutting down server when certain components are disabled.

  • #6135 Tigase now properly enabled selective TLS if not enabled globally.

  • #6140 Fixed issue while sending server welcome message.

  • #6141 Fixed NPE at startup.

  • #6234 Fixed an error where an error message would repeat unnecessarily.

  • #6284 Ad-hoc commands now refresh SSL Certificate, and restart is no longer required.

  • #6293 Server no longer sends no response upon setting empty photo in vCard.

  • #6263 Fixed missing namespaces in responses from adhoc commands.

  • #6400 Added a proper error when max-queue-size is too small and server cannot start.

  • #6408 Fixed an issue where single WebSocket frames contained multiple XML stanzas instead of one per frame.

  • #6411 Main kernel is now called to smooth shutdown. Further, timeout periods are opened up for large instances.

  • #6574 SSL certificate upload handling is now fixed within cluster mode.

  • #6598 Fixed EventBus Registration connection issues between cluster nodes.

  • #6658 Cluster connections no longer potentially keep open connection after cluster is no longer connected or available.

  • #6749 Fixed schema parsing for DerbyDB.

  • #6776 Fixed failing Websocket connections if header contains more than one value.

  • #6875 Fixed an issue where C2S connections could be accepted before SessionManager was initialized.

  • #7037 Fixed error while parsing negative values from config.tdsl file.

  • #7055 Improvements to metaspace use and other memory use tweaks.

  • #7304 Virtual host logs now properly follow log size limits.

  • #7431 AdHoc requests between the same user with different resources are no longer dropped with `NoConnectionIdExecption`error.

  • #7434 Adjusted SeeOtherHotDualIP to use new table name in cluster nodes database.

  • #7491 Stacktraces from CertificateContainer are no longer printed to tigase-console.log, but will be printed to tigase.log.

  • #7687 Fixed an error where connections failed after authentication timeout were marked as active after cleanup.

  • #7747 Fixed ClusterRepoItemEvent serialization issues causing unsupported conversion error in cluster mode.

1.4. Component Changes

1.4.1. AMP

  • #7301 Tigase AMP component now uses multiple processing threads.

1.4.2. PubSub

  • #5033 PubSub now compatible with using emojis in pubsub items.

  • #5693 Fixed parsing configuration of SessionManager processors.

  • #5766 PubSub now writes to all databases with UTC timestamp.

  • #5953 Fixed presences not being removed from presenceByService collection if client disconnects without <unavailable/> presence being sent.

  • #6176 version changed to PubSub v4.0.0.

  • #7707 Fixed potential NPE in PubSub.

1.4.3. http-api

  • #4873 Support added to display timestamp fields as data, time, and timezone fields.

  • #4876 Implemented using XML repository for new setups, and updated default config to use this.

  • #4888 http-api now is enabled by default.

  • #5209 Updated visual styling of pages hosted by component.

  • #5290 Fixed invalid property name.

  • #5316 Account Registration now can now require and send confirmation E-mails.

  • #5415 Web Setup now checks configuration for message archive conflicts.

  • #5460 MongoDB now supported through web-setup.

  • #5717 Fixed default values of check-boxes in admin UI not being shown.

  • #5950 Supported added for XEP-0363: HTTP File Upload.

  • #6159 Fixed NPE thrown if scripts directory is not present.

  • #6176 version changed to tigase-http-api v2.0.0.

  • #6212 Added mechanism for password changing through HTTP API.

  • #7307 Fixed scripts returning 404 while handling rest/user/ requests even though user exists.

  • #7178 Ad-hoc commands are now categorized in groups for better organization.

  • #7568 Added timeout reading for HTTP request headers, added configurable accept-timeout.

1.4.4. message-archive

  • #4867 fixed issue when changing MA jid.

  • #4888 message-archive is enabled by default.

  • #5033 Update message archive to be compatible with emojis.

  • #5391 Added missing query statement block starts and ends to be compatible with SQL Server.

  • #5604 Modified access to static fields and functions.

  • #5681 Fixed duplication of groupchat messages with different ids by modifying hash algorithm.

  • #6176 version changed to message-archive v2.0.0.

  • #7615 feature-not-implemented response no longer occurs when removing stored messages.

1.4.5. MUC

  • #4888 muc now is enabled by default.

  • #5033 MUC component is now compatible with emojis.

  • #5066 Fixed issues working with MongoDB repository.

  • #5085 Removed invalid annotation parameter values.

  • #5559 Fixed NPE while changing default room configuration.

  • #5666 User may add more than one <item/> elements to query when querying room members.

  • #5715 Welcome messages may now be disabled globally, or in individual room configurations.

  • #5736 Rooms with no subject now return empty <subject/> element, as per XEP-0048 7.2.16.

  • #5813 Fixed NPE during room creation.

  • #6176 version changed to tigase-muc v3.0.0.

  • #6395 Fixed tigase.db.UserNotFoundException during retrieval of MUC user.

  • #6734 Introduced muc#roomconfig_maxresources to allow configuration of max number of resources for a single occupant.

  • #7443 Disabled XEP-0091 by default, added history attribute validation.

1.4.6. socks5 Proxy

  • #2750 Cleanup of code and removal of empty javadocs.

  • #5867 Fixed NPE during configuration dump when component is disabled.

  • #6176 version changed to tigase-socks5 v2.0.0.

1.4.7. stats

  • #5206 Fixed exception causing duplicate error entry.

  • #5728 Fixed MySQLIntegrityConstraintViolationException in upload handler.

  • #6161 Removed usage of classes from javax.xml.ws package for JDKv9 compatibility.

1.4.8. STUN Server

  • #6176 version changed to tigase-stun v2.0.0.

1.4.9. WebSocket

  • #6481 Websocket component has been improved to be more compliant with rfc6455

2. Jabber/XMPP introduction

2.1. Jabber/XMPP is Instant Messaging Technology

All federated XMPP servers are connected in one global communications network allowing you to send messages to friends who have accounts on other Jabber servers.

This is very much like sending e-mail but the difference between Jabber and e-mail is the same as the difference between sending a traditional mail and talking on the phone.

All messages sent through Jabber are sent instantly and you also receive responses instantly. More over you can see whether your mate is online and available for talking or not.

There exists similar technologies to Jabber like Yahoo, MSN, and ICQ. There are, however, quite a few differences.

XMPP is an open standard which means everybody can know how it works, everybody can implement their own software connecting to the network both client and server side.

The server side is actually the biggest difference and advantage. Many companies have offices in different locations, and such instant messaging technology could be very useful to employees for communication. Companies are not inclined to allow confidential discussions to go outside the company’s network. Especially if it is not very secure to leave such information on third party public servers.

XMPP servers on the other hand, allows you to deploy server software on your own company network. Employees can then talk securely and all information remains on the company’s secure network. Of course if offices are located in different locations or countries then all messages are transmitted over the public network - the Internet. This is not a problem since XMPP supports SSL/TLS - secure encrypted connections which helps you protect your discussion.

Then if your employees need to contact customers outside your company, the whole discussion can go through your server and a server located on the customer side.

There are many other scenarios and use cases but I hope this brief introduction gives you an idea of the differences and advantages of XMPP technology.

2.2. Installing Minichat on Your Website

We have made Minichat available to demonstrate new projects we are working on, to run some tests, and collect your opinions. The feedback we’ve recieved has exceeded our expectations. The most common question was: Can I/how can I install this on my website?

Installing Minichat on your website is very simple so I am providing instructions here for all of you that want to include the Minichat client on your website and allow visitors to chat with you.

Just to remind you - this code is under development and will be updated and changed frequently. It may even stop working temporarily or permanently. We can and will intentionally block certain users or IP addresses if we discover any abuse. If you are ready for this and still want to use it continue reading…​

First thing to know: Minichat will only work with the tigase.org XMPP server right now. This is not because of some limitations in the code or special non-standard implementation. This is to simplify deployment of the service. If you wanted Minichat to connect to a different domain or XMPP server the installation would be much more difficult, involving Apaches proxy mod installation, configuration and possibly Bosh component/server deployment.

Second thing to know: Minichat connects to the server as anonymous user. To avoid sending spam the anonymous user can only send messages to users within the XMPP server. It means that although you can configure Minichat to send messages to user@jabber.org, Tigase server won’t deliver those messages.

2.2.1. Instructions:

  1. Register an account on the tigase.org website. For purposes of this guide let’s say the account name is: your-account. The Jabber ID will be: your-account@tigase.org.

    Note! There seems to be some confusion so let me clarify this. You create an account on the www.tigase.org website but your Jabber account domain is: tigase.org.

  2. Setup the Jabber/XMPP client of your choice to connect to the Tigase server in domain: tigase.org. Note you must allow plain text login. TLS is supported so the connection is secure and your password is still safe.

  3. There are a few ways for adding the client to the website but you always use startup parameters as URL query to the client link. Following parameters are possible:

    • jid=your-account@tigase.org tells the client who you want website visitors talk to. Normally you put your own account here.

    • name=YourName screen name (displayed name) of your account.

    • domain=tigase.org domain name you want Minichat to connect to. At the moment only tigase.org is allowed.

    • autologin=true determines whether the Minichat client automatically connects to the server when the page is loaded or waits for the visitor to click on the title bar.

    • The first way described is to put the client in exactly the same way as it is on the www.tigase.org website. The chat window is always visible but the client is not connected to the server until someone clicks on the Minichat title bar. Include in your page following code:

    <iframe
      src="http://minichat.tigase.org/MesComp.html?jid=your-account@tigase.org&name=YourName&domain=tigase.org"
      width="220px" height="250px" frameborder="0"></iframe>
    • By adding a single bit of code: autologin=true the client automatically connects to the server and is ready for chatting without need to click on the title bar.

      <iframe
        src="http://minichat.tigase.org/MesComp.html?jid=your-account@tigase.org&name=YourName&domain=tigase.org&autologin=true"
        width="220px" height="250px" frameborder="0"></iframe>
    • A third option is the least intrusive but the most complex to install. It puts a small, clickable image with text on your page: Click to chat with…​. When the website visitor clicks a new window pops up with the Minichat which automatically connects to the server. You need to put some code in the web page header:

      <link rel="stylesheet" type="text/css"
        href="http://minichat.tigase.org/minichat.css"/>
      <link rel="stylesheet" type="text/css"
        href="http://minichat.tigase.org/mygwt-all.css" />

      And similar to other configurations code in the web page body:

      <iframe
        src="http://minichat.tigase.org/Runner.html?jid=your-account@tigase.org&name=YourName&domain=tigase.org"
        width="220px" height="250px" frameborder="0"></iframe>

Enjoy and send us your comments…​

2.3. How to Use Tigase Service

2.3.1. This Article Describes How to use tigase.org Service for Instant Communications

You have to install and run a Jabber client application to use the service.

Short instructions:

Usually you just need to enter the user name of the form: user@tigase.org. Your XMPP client should take care of all other things as our service doesn’t need any special settings. If you don’t have an account on tigase.org server yet just tick the option to register new account. That’s it!

Long Instructions:

The good news is that there are many programs to choose from which allow you to communicate through our server. So you can pick up your favorite application or use an existing one that is compatible and start using our service.

All clients presented below support multiple accounts on Jabber or XMPP servers. What this means is that you can have a few Jabber accounts on different servers and you can still use just one program to connect to all of them at the same time.

The full list of all known XMPP clients is very long. You can obviously try them all but below is a selection which is recommended by the Tigase team. The selected programs might not be the best choice for you, but these programs have been tested and we can offer help with using them. Here is a list of recommended instant messaging clients:

  • Psi Pure XMPP client. Although it supports only Jabber networks it is a very user friendly and comfortable program. It works on most popular operating systems like Linux, MS Windows, and Apple MacOS X.

  • Gajim This is another Jabber only client. Very user friendly and works on most of Linux distributions, FreeBSD, and MS Windows.

  • Pidgin (previously Gaim) This is not just a Jabber client. This type of application is called multicommunicator as apart from Jabber it supports many other instant messaging networks/protocols such as: AIM/ICQ, MSN, Yahoo, Gadu-Gadu, IRC, and a few others. So it is especially convenient if you have friends using other messaging networks. Pidgin works on most Linux distributions, and on MS Windows.

  • Kopete This is a KDE component and although it only works on Linux based system it also supports many of the most popular instant messaging protocols apart from Jabber like: AIM, Gadu-Gadu, ICQ, IRC, MSN, Yahoo.

Install the XMPP client of your choice and set up for a Tigase account.

2.4. Configuration Instructions for Psi

2.4.1. Psi - Initial Configuration

The first time you run Psi you see a screen like this:

Psi First Run

To connect to tigase.org server we need to configure the program. Below are step-by-step instructions for novice users on how to setup Psi.

  1. Psi can connect to many servers at the same time so we have to identify each connection. The first thing to do is assign a name to the connection we just created. As we are going to define connection to tigase.org server let’s just name it: Tigase.

    Psi Add Account

    Note! At the moment you can register an account through the Web site only. This is a single account for both services: The Drupal website and XMPP service on the tigase.org domain. If you want to have a Jabber account on the tigase.org server go to the registration page, un-tick "Register new account", and go to the point no 5. You can use guide points 2-4 to register a Jabber account on any other Jabber server.

  2. When you press the Add button you will see next window where you can enter your Jabber account details:

    Psi Empty Account

  3. Invent your user name for the account on Tigase server. Let’s assume your user name is: frank. Jabber ID’s however consist of 2 parts - your user name and server address. Exactly the same as an e-mail address. As you are registering an account on tigase.org server, you will have to enter in this field: frank@tigase.org. Next enter your password and click the Register button.

    Psi Register Account

  4. On successful registration you will receive a confirmation message and you should see a window like this:

    Register Account Success

    It is possible that somebody may have already registered your chosen username. If so, you will receive error message and will then have to select another user name and try to register again.

  5. After clicking the OK button you will see a window with your connection and account setup. You can stick with default values for now.

    psi-account-properties-basic

    Just click the Save button and this window closes.

  6. Now you have your account configured and ready to use but you are still off-line. You can find out whether you are on-line or off-line by looking at the bottom of main Psi window. There you can see Offline text.

    PSI After Registration

    Click on this Offline text and you will see a list of possible options. Just select Online.

    PSI Connected

    Now you are connected!

The box also allows you to choose other online statuses which can tell other users if you are away or busy.

Well, you are now connected but how to talk to other people? How to add friends to the contact list?

You can send a message to your friends straight away using the Psi menu option New blank message. It is much more convenient however, if you could see which of your friends is online and available for chatting and if you could start talking to your friend just by clicking on his name.

2.4.2. Short Instructions How to Add Your First Contact

  1. Click on Psi menu - the button next to the Online text. You will see something like this:

    PSI Menu

    From all menu options select the top one - Add a contact:

    PSI Menu add Contact

  2. The next window will display where you can enter your contact details:

    PSI Add User Empty

    You have to know the Jabber ID of the person you want to add to your contact list. Let’s assume, for example, you want to add Tigase server administrator’s Jabber ID to your contact list. So, after you enter these details the window will look like this:

    PSI Add User Filled

    Click the Add button.

  3. Now you will see a confirmation window that a new person has been added to your contact list:

    PSI Kobit Added

    But there is more behind the scenes. Adding a contact to your Roster (contact list) usually means you can see whether the person is online and available to talk or not. The person however, may not wish you to see his presence. So, to make sure the other person accepts you as a friend Psi sent a request to the address you just entered with the question of whether he agrees to show his presence to you.

    You won’t be able to see the users availability until he sends confirmation.

  4. Once the other user sends confirmation back, you will usually receive 2 system events:

    PSI Kobit Auth Received

  5. Click on the contact to see a window with these messages:

    PSI Authorized Window

  6. One message just says you have been authorized by the other user:

    PSI Authorized Window 2

    So you simply click Next to see the second message.

  7. The second message is a bit more interesting. It contains the question of whether you also authorize the other user to see your presence. If you want to accept this request just click Add/Auth.

    PSI Authorized Window 3

  8. Finally main Psi window with your new contact:

    PSI Kobit Added Authorized

Well done!

You are ready to start Jabbering. Good luck.

Where to go next? For detailed Psi documentation refer to the program Wiki page: http://psi-im.org/wiki/Main_Page

Welcome to the Tigase Administration Guide.

3. About Tigase XMPP Server

Tigase XMPP Server is an Open Source and Free (AGPLv3) Java based server. The goals behind its design and implementation of the server are:

  1. Make the server robust and reliable.

  2. Make the server a secure communication platform.

  3. Make a flexible server which can be applied to different use cases.

  4. Make an extensible server which takes full advantage of XMPP protocol extensibility.

  5. Make the server easy to setup and maintain.

3.1. Robust and reliable

This means that the server can handle many concurrent requests/connections and can run for a long time reliably. The server is designed and implemented to handle millions of simultaneous connections.

It is not enough however to design and implement a high load server and hope it will run well. The main focus of the project is put in into testing. Tests are taken so seriously that a dedicated testing framework has been implemented. All server functions are considered as implemented only when they pass a rigorous testing cycle. The testing cycle consists of 3 fundamental tests:

  1. Functional tests - Checking whether the function works at all.

  2. Performance tests - Checking whether the function performs well enough.

  3. Stability tests - Checking whether the function behaves well in long term run. It must handle hundreds of requests a second in a several hour server run.

3.2. Security

There are a few elements of the security related to XMPP servers: secure data transmissions which is met by the implementation of SSL or TLS protocol, secure user authorization which is met by the implementation of DIGEST or SASL user authorization and secure deployment which is met by component architecture.

Secure deployment Tigase software installation does not impact network security. Companies usually have their networks divided into 2 parts: DMZ which is partially open to the outside world and the Private network which is closed to the outside world.

If the XMPP server is to provide an effective way of communication between company employees regardless if they are in a secure company office or outside (perhaps at a customer site), it needs to accept both internal and external connections. So the natural location for the server deployment is the DMZ. However, this solution has some considerations: each company has normally established network users base and integrated authorization mechanisms. However, that information should be stored outside the DMZ to protect internal security, so how to maintain ease of installation and system security?

Tigase server offers a solution for such a case. With it’s component structure, Tigase can be easily deployed on any number machines and from the user’s point of view it is seen as a one logical XMPP server. In this case we can install a Session Manager module in the private network, and a Client Connection Manager with Server Connection Manager in the DMZ.

Session Manager connects to DMZ and receives all packets from external users. Thus is can securely realize users authorization based on company authorization mechanisms.

3.3. Flexibility

There are many different XMPP server implementations. The most prevalent are:

  • Used as a business communication platform in small and medium companies where the server is not under a heavy load. For such deployments security is a key feature.

  • For huge community websites or internet portal servers is, on the other hand, usually under very heavy load and has to support thousands or millions of simultaneous connections. For such a deployment we need a different level of security as most of the service is open to the public.

  • For very small community deployments or for small home networks the key factor is ease to deploy and maintain.

Architecture based on components provides the ability to run selected modules on separate machines so the server can be easily applied in any scenario.

For simple installation the server generates a config file which can be used straight away with very few modifications or none at all. For complex deployments though, you can tweak configurations to your needs and setup XMPP server on as many physical machines as you need.

3.4. Extensibility

The world changes all the time as does user’s needs. The XMPP protocol has been designed to be extensible to make it easy to add new features and apply it to those different user’s needs. As a result, XMPP is a very effective platform not only for sending messages to other users, it can also be extended for sending instant notifications about events, a useful platform for on-line customer service, voice communication, and other cases where sending information instantly to other people is needed.

Tigase server has been designed to be extensible using a modular architecture. You can easily replace components which do not fulfill your requirements with others better fitting your needs. But that is not all, another factor of extensibility is how easy is to replace or add new extensions. A great deal of focus has been put into the server design API to make it easy for other software developers to create extensions and implement new features.

3.5. Ease of Use

Complex computer networks consisting of many servers with different services are hard to maintain. This requires employing professional staff to operate and maintain the network.

Not all networks are so complex however, most small companies have just a few servers for their needs with services like e-mail and a HTTP server. They might want to add an XMPP server to the collection of their services and don’t want to dedicate resources on setup and maintenance. For such users our default configuration is exactly what they need. If the operating system on the server is well configured, then Tigase should automatically pickup the correct hostname and be ready to operate immediately.

Tigase server is designed and implemented to allow dynamic reconfiguration during runtime so there is no need to restart the server each time you want to change configuration settings.

There are also interfaces and handlers available to make it easy to implement a web user interface for server monitoring and configuring.

4. Licensing and Open Source

As mentioned previously, Tigase is open source under AGPLv3. If you are not familiar with open source software, or the environment, here are some frequently asked questions that might provide some answers.

What does open source mean?
This means that Tigase’s source code is available to the public to see how Tigase works. There are no 'black boxes' for packets where things just happen, everything is out in the open, whereas other companies may consider this propitiatory information. In addition, we have the benefit of many talented people working with Tigase to constantly improve Tigase server and related projects. These people not only include the Tigase development team, but other members of the community who submit code improvements, patches, enhancements, or other changes to Tigase.

Does this mean that the binaries are open to malicious code?
Although we accept patches from contributors, our repository does not accept them directly. Code may be submitted through our tigase.tech page and our developers will review the code before it is added. All builds are tested for functionality and security when they are built.

Does this mean it is less secure?
Not at all. Although anybody can see the source code, and know how Tigase works; your installation, connections, and settings are uniquely yours. Tigase is regularly tested and written to be as secure as possible using the latest encryption and secure connection protocols.

Is Tigase free?
Tigase is free for download and use in it’s unmodified state. Our commercial grade products such as Advanced Clustering Strategy is available for free use for testing & development.

Does this mean I cannot use it in my product or commercial environment?
Not necessarily, consult the Affero General Public License Agreement v3 to see if your use qualifies. Tigase is offered under commercial license if your use is not covered by AGPLv3.

Are there options for closed code or extensions?
Yes! Commercial licenses can be custom made for each client, and software written for your company may be made private or part of our open source distributions at your discretion.

Can I contribute code?
Sure! Register an account in here and submit patches through our redmine!

5. Tigase Server Binary Updates

Most open source projects try to make sure that the nightly builds compile correctly so that these builds can be used. However, we at Tigase believe that these builds should be separated until they are thoroughly tested and released. Although lots of installations out there we know of just run from our nightly builds, this puts an extra responsibility to make sure all code is functional and will constantly work. Therefore, our general approach is to run all basic functionality tests before each code commit to make sure it works correctly. This does not guarantee that there will never be a problem, but it is a precaution from preventing bad builds from arriving in the hands of our customers.

Some users on the other hand, like to be on the bleeding edge and regularly use our nightly builds exploring new code changes and playing with new features before they are put to a full release. Others prefer to stick to stable and fully tested public releases. Others however, want something from the middle, the most recent features, but bug fixes, something like a beta or a release-candidate state.

Should you choose to use the nightly builds, a few things you should consider: - Changes may be made to the code that can negatively affect performance. - Changes may be made to the code that can negatively affect security. We highly recommend testing these builds in your environments before upgrading.

With these considerations in mind, we provide nightly builds at this link which provides directories by date.

Standard naming format is tigase-server-x.x.x-SNAPSHOT-byyyy.* x.x.x is the major version the builds are working towards, with yyyy being the specific build. Note individual days may have the same builds as noted by the byyyy section of the file.

Just like the standard distributions, the builds are available with the following extensions:

  1. javadoc.jar - Java installer for javadoc only

  2. dist.zip - Compressed binaries with no dependencies.

  3. dist.tar.gz - tarball compressed binaries with no dependencies.

  4. dist-max.zip - Compressed binaries with all dependencies.

  5. dist-max.tar.gz - tarball compressed binaries with all dependencies.

We also provide automated testing of each of our nightly builds for each supported databases. Tests are done with both functional and low memory parameters in mind, and are available at this link. These tests can provide a quick examination of function before upgrading your current build.

The latest Cluster tests are available at this link which shows performance and traffic use under strain using the latest available build of Tigase.

6. Quick Start Guide

6.1. Minimum Requirements

Before you begin installing Tigase server onto your system, please make sure the minimum requirements are installed first:
- Java Development Kit v8 or later - We recommend Oracle JDK. OpenJDK may work, but some features might cause errors.

  • Administrator access - We recommend that you install Tigase Server from a user login with administrator access.

6.2. Contents

This is a set of documents allowing you to quickly start with our software. Every document provides an introduction to a single topic allowing you to start using/developing or just working on the subject. Please have a look at the documents list below to find a topic you are looking for. If you don’t find a document for the topic you need please let us know.

6.3. Installation Using Web Installer

When Tigase XMPP Server starts up, it looks for the default configuration file: etc/config.tdsl. If this file has not been modified you can run the web installer. Which will step you through the process of configuring Tigase. If you are installing Tigase in a Windows environment, please see the Windows Installation section.

6.3.1. Download and Extract

First download Tigase XMPP Server and extract it. You can download the official binaries, or the latest and greatest nightly builds.

You may also use wget:

$ wget http://build.tigase.org/nightlies/dists/latest/tigase-server-dist-max.tar.gz
$ tar -xf tigase-server-dist-max.tar.gz
$ cd tigase-server-<version>
Tip
Do not run as root user!

6.3.2. Start the Server

scripts/tigase.sh start etc/tigase.conf

6.3.3. Verify Tigase is Running

You should see a list of listening ports.

$ lsof -i -P
COMMAND   PID   USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
java    18387 tigase  141u  IPv6 22185825      0t0  TCP *:8080 (LISTEN)
java    18387 tigase  148u  IPv6 22185834      0t0  TCP *:5222 (LISTEN)
java    18387 tigase  149u  IPv6 22185835      0t0  TCP *:5223 (LISTEN)
java    18387 tigase  150u  IPv6 22185836      0t0  TCP *:5290 (LISTEN)
java    18387 tigase  151u  IPv6 22185837      0t0  TCP *:5280 (LISTEN)
java    18387 tigase  152u  IPv6 22185838      0t0  TCP *:5269 (LISTEN)

6.3.4. Connect to the Web Installer

Some points before you can connect:

This setup page is restricted access, however for first setup there is a default account set to setup Tigase: Username: admin Password: tigase

This combination will only be valid once as it will be removed from config.tdsl file on completion of setup process. After this point the setup page will only be accessible using the following:

  1. JID accounts listed as administrators in admins line in config.tdsl file.

  2. Username and password combinations added to config.tdsl file manually, or at the last page in this process.

Point your browser to http://localhost:8080/setup/ unless you are working remotely. Then you can use the domain name, or IP address. I used http://tpub.xmpp-test.net:8080/setup/ for this guide.

Enter the username and password above to gain access.

6.3.5. Step Through the Installation Process

You will be greeted by the following "About software" page.

web-install-01

Read it and then click "Next"

web-install-02

Here is some information about our commercial products and licensing. Please read though the agreement, type in your name or company and click "Next".

web-install-03

This page will look over your basic configuration settings, these include the server type, domains you wish to use, and gives you a chance to specify an administrator for the domain. Also, you will be selecting what type of database Tigase server will be using (configuration comes later). If you do not specify an administrator and password, one is made for you, which will be admin@yourdomain and password is tigase. If you wish to configure your server beyond the basics, check Advanced configuration options.

web-install-04

The Advanced configuration page. Select what components and configurations you need. Some may be highlighted red to indicate conflicts or unmet requirements.

web-install-05

Plugins which will be loaded by the server, most plugins are enabled by default. Some may be highlighted red to indicate conflicts or unmet requirements.

web-install-06

This is where the database is setup. The type of database selected in step 3 will influence available options. BE SURE TO SPECIFY DATABASE ROOT USER ACCOUNT AND PASSWORD

web-install-07

You should see a page like this after a successful database setup. This page will reveal any issues with your database setup such as invalid URIs, passwords, and schemas. You may hit Back on your browser to check credentials and settings and try again.

web-install-08

Next a page asking if you’d like to provide an API Access Key to access HTTP REST commands. It is highly recommended that you either specify an API key or block access. Open API keys allow any REST command to be interpreted by the server.

web-install-09

The Setup Access Page will be locked from the admin/tigase user as specified above. This is your chance to have the setup pages add a specific user in addition to admin accounts to re-access this setup process later. If left blank, only JIDs listed in admin will be allowed to access.

web-install-10

The installation is complete and this is what the config.tdsl file will look like. If you have a custom setup, or would like to put your own settings in, you may copy and past the contents here to edit the current config.tdsl file. Click "Save" to write the file to disk.

web-install-11

You have now finished the installation, proceed to the next step to restart the server.

6.3.6. Restart the Server

It is recommended at this point to stop the server manually and restart it using the proper script for your OS. From the Tigase base directory enter

./scripts/tigase.sh stop

./scripts/{OS}/init.d/tigase start etc/tigase.conf

where {OS} is your type of Linux, gentoo, debian, mandriva, or redhat

To further fine tune the server you should edit etc/tigase.conf. Ensure JAVA_HOME path is correct, and increase memory if needed using JAVA_OPTIONS -Xmx (max), and -Xms (initial). You will need to direct Tigase to read settings from this file on startup as follows.

Everything should be running smooth at this point. Check the logfiles in logs/ if you experience any problems.

6.3.7. Windows Instructions for using Web Installer

There are a few steps involved with setting up Tigase with the web installer in a Windows environment. Please follow this guide.

First step is to extract the dist-max archive in it’s entirety to the intended running directory. Once there, run the Setup.bat file inside the win-stuff folder. This will move the necessary files to the correct folders before Tigase begins operation.

From here, you have a few options how to run Tigase; run.bat will operate Tigase using a java command, or run.bat which will start Tigase using the wrapper. You may also install Tigase and run it as a service.

One this setup is finished, web installer will continue the same from here.

6.4. Manual Installation in Console Mode

Our preferred way to install the Tigase server is using Web installer and configuration program which comes with one of the binary packages. Please pick up the latest version of the JAR file in our download section.

In many cases however it is not always possible to use the web installer. In many cases you have just an ssh access or even a direct access in console mode only. We are going to provide a text-only installer in one of the next releases but for the time being you can use our binary packages to install the server manually. Please continue reading to learn how to install and setup the server in a few easy steps…​

If you have an old version of the Tigase server running and working and you intend to upgrade it please always backup the old version first.

Note
Please note that these instructions are for *nix operating systems, and some modifications may be required for other Operating Systems!

6.4.1. Get the Binary Package

Have a look at our download area. Always pick the latest version of the package available. For manual installation either zip or tar.gz file is available. Pick one of files with filename looking like: tigase-server-x.y.z-bv.tar.gz or tigase-server-x.y.z-bv.zip where 'x', 'y', 'z' and 'v' are version numbers and they change from a release to release.

Alternatively, you may use wget

wget http://build.tigase.org/nightlies/dists/latest/tigase-server-dist-max.tar.gz

6.4.2. Unpack the Package

Unpack the file using command for the tar.gz file:

 $ tar -xzvf tigase-server-x.y.z-bv.tar.gz

or for the zip file:

 $ unzip tigase-server-x.y.z-bv.zip

A new directory will be created: tigase-server-x.y.z-bv/.

Sometimes after unpacking package on unix system startup script doesn’t have execution permissions. To fix the problem you have to run following command:

 $ chmod u+x ./scripts/tigase.sh

6.4.3. Prepare Configuration

If you look inside the new directory, it should like this output:

 $ ls -l
total 88
drwxr-xr-x 2 tigase tigase  4096 Aug 15 18:17 certs
-rw-r--r-- 1 tigase tigase     0 Aug 15 18:26 ChangeLog
drwxr-xr-x 2 tigase tigase 12288 Aug 15 18:17 database
drwxrwxr-x 4 tigase tigase  4096 Oct 12 09:48 docs
drwxrwxr-x 2 tigase tigase  4096 Oct 12 09:48 etc
drwxrwxr-x 2 tigase tigase  4096 Oct 12 09:48 jars
-rw-r--r-- 1 tigase tigase 34203 Aug 15 18:26 License.html
drwxr-xr-- 2 tigase tigase  4096 Aug 15 18:26 logs
-rw-r--r-- 1 tigase tigase  3614 Aug 15 18:26 package.html
-rw-r--r-- 1 tigase tigase  2675 Aug 15 18:26 README
drwxr-xr-x 9 tigase tigase  4096 Aug 15 18:17 scripts
drwxr-xr-x 5 tigase tigase  4096 Aug 15 18:17 tigase
drwxrwxr-x 4 tigase tigase  4096 Oct 12 09:48 win-stuff

At the moment the most important is the etc/ directory with these files:

 $ ls -l etc/
total 36
-rw-r--r-- 1 tigase tigase  153 Aug 15 18:11 bosh-extra-headers.txt
-rw-r--r-- 1 tigase tigase  325 Aug 15 18:11 client-access-policy.xml
-rw-r--r-- 1 tigase tigase  124 Aug 15 18:11 config.tdsl
-rw-r--r-- 1 tigase tigase  263 Aug 15 18:11 cross-domain-policy.xml
-rw-r--r-- 1 tigase tigase 2337 Aug 15 18:11 jmx.access
-rw-r--r-- 1 tigase tigase 2893 Aug 15 18:11 jmx.password
-rw-r--r-- 1 tigase tigase  735 Aug 15 18:11 logback.xml
-rw-r--r-- 1 tigase tigase 3386 Aug 15 18:11 snmp.acl
-rw-r--r-- 1 tigase tigase 1346 Aug 15 18:11 tigase.conf
Configure tigase.conf

Tigase.conf is a file that contains general program operating parameters, and java settings for Tigase to run. For now, the only setting we need to set is the JAVA_HOME directory.

JAVA_HOME="${JDKPath}"

Replace ${JDKPath} with a path to Java JDK installation on your system.

Configure config.tdsl

You need also to edit the config.tdsl file. It contains initial parameters normally set by the configuration program. As this is a manual installation, you will have to edit this document yourself. It contains already a few lines:

'config-type' = 'setup'

http () {
    setup () {
        'admin-user' = 'admin'
        'admin-password' = 'tigase'
    }
}

You will need to set a few things in order to get Tigase up and running.

Step 1: Change config-type

Refer to config-type property description for details, but for most operations, change setup to default.

Step 2: Set virtual hosts

Without a virtual host, your XMPP server has no domain with which to operate. To set a virtual host use the following configuration:

'virtual-hosts' = [ 'hostname' ]

You have to replace hostname with a domain name used for your XMPP installation. Let’s say this is jabber.your-great.net. Your setting should look like this:

`'virtual-hosts' = [ 'jabber.your-great.net' ]`

There are many other settings that can be configured visit this section for details.

Step 3: Set Administrators

At least one administrator is required, and once the database is setup will have the default password of tigase. Be sure to change this once you have finished setting up your server. To add admins, use the following line in the config.tdsl file:

`admins = [ 'admin@jabber.your-great.net', 'user2jabber.your-great.net' ]`
Step 4: Set databases

You will also need to configure connection to the database. First you have to decide what database you want to use: Derby, MySQL, PostgreSQL, MSSQL, or MondoDB. Each database will have slightly different configurations. If we are using derby, in a directory called tigasedb, your configuration would look like this:

dataSource () {
    default () {
        uri = 'jdbc:derby:tigasedb;create=true'
    }
}

Consult dataSource property for more configuration info.

This is enough basic configuration to have your Tigase server installation running.

6.4.4. Install Database

Creating the database is the next step. Previously, we had scripts to handle this process, but we now have the advantage of functions in the tigase.sh script that can be used. Setting up the database can now be done using a single command.

./scripts/tigase.sh install-schema etc/tigase.conf -T derby -D tigasedb -H localhost -U tigase_user -P tigase_pass -R root -A rootpass -J admin@jabber.your-great.net -N pass

This command will install tigase using a Derby database on one named tigasedb hosted on localhost. The username and password editing the database is tigase_pass and root. Note that -J explicitly adds the administrator, this is highly recommended with the -N passing the password. You may customize this command as needed, refer to the install-schema section of the documentation for more information.

On a windows system, you need to call the program directly:

C:\tigase>java -cp "jars/*" tigase.db.util.SchemaManager "install-schema" -T derby -D tigasedb -H localhost -U tigase_user -P tigase_pass -R root -A rootpass -J admin@jabber.your-great.net -N pass

If this successfully passes, you should see some information printed out

LogLevel: CONFIG
2017-10-12 20:05:47.987 [main]             DBSchemaLoader.init()                   CONFIG:   Parameters: [ingoreMissingFiles: false, logLevel: CONFIG, adminPassword: pass, admins: [admin@jabber.your-great.net], dbRootPass: rootpass, dbRootUser: root, dbType: derby, dbName: tigasedbx, dbHostname: localhost, dbUser: tigase_user, dbPass: tigase_pass, useSSL: false, useLegacyDatetimeCode: false, serverTimezone: null, file: null, query: null]
Oct 12, 2017 8:05:48 PM tigase.util.DNSResolverDefault <init>
WARNING: Resolving default host name: ubuntu took: 7
Oct 12, 2017 8:05:49 PM tigase.db.util.SchemaManager loadSchemas
INFO: found 1 data sources to upgrade...
Oct 12, 2017 8:05:49 PM tigase.db.util.SchemaManager loadSchemas
INFO: begining upgrade...
LogLevel: CONFIG
2017-10-12 20:05:49.877 [main]             DBSchemaLoader.init()                   CONFIG:   Parameters: [ingoreMissingFiles: false, logLevel: CONFIG, adminPassword: pass, admins: [admin@jabber.your-great.net], dbRootPass: rootpass, dbRootUser: root, dbType: derby, dbName: tigasedbx, dbHostname: null, dbUser: null, dbPass: null, useSSL: null, useLegacyDatetimeCode: false, serverTimezone: null, file: null, query: null]
2017-10-12 20:05:49.877 [main]             DBSchemaLoader.validateDBConnection()   INFO:     Validating DBConnection, URI: jdbc:derby:tigasedbx;create=true
2017-10-12 20:05:50.932 [main]             DBSchemaLoader.validateDBConnection()   CONFIG:   DriverManager (available drivers): [org.apache.derby.jdbc.AutoloadedDriver@65262308, jTDS 1.3.1, com.mysql.jdbc.Driver@54997f67, com.mysql.fabric.jdbc.FabricMySQLDriver@189633f2, org.postgresql.Driver@76fc5687]
2017-10-12 20:05:50.932 [main]             DBSchemaLoader.validateDBConnection()   INFO:     Connection OK
2017-10-12 20:05:50.933 [main]             DBSchemaLoader.validateDBExists()       INFO:     Validating whether DB Exists, URI: jdbc:derby:tigasedbx;create=true
2017-10-12 20:05:50.936 [main]             DBSchemaLoader.withConnection()         CONFIG:   DriverManager (available drivers): [org.apache.derby.jdbc.AutoloadedDriver@65262308, jTDS 1.3.1, com.mysql.jdbc.Driver@54997f67, com.mysql.fabric.jdbc.FabricMySQLDriver@189633f2, org.postgresql.Driver@76fc5687]
2017-10-12 20:05:50.937 [main]             DBSchemaLoader.lambda$validateDBExists$283()  INFO: Exists OK
2017-10-12 20:05:50.939 [main]             DBSchemaLoader.loadSchemaFile()         INFO:     Loading schema from file(s): database/derby-schema-7-2.sql, URI: jdbc:derby:tigasedbx;create=true
2017-10-12 20:05:50.941 [main]             DBSchemaLoader.withConnection()         CONFIG:   DriverManager (available drivers): [org.apache.derby.jdbc.AutoloadedDriver@65262308, jTDS 1.3.1, com.mysql.jdbc.Driver@54997f67, com.mysql.fabric.jdbc.FabricMySQLDriver@189633f2, org.postgresql.Driver@76fc5687]
2017-10-12 20:05:51.923 [main]             DBSchemaLoader.lambda$loadSchemaFile$287()  INFO:  completed OK
2017-10-12 20:05:51.925 [main]             DBSchemaLoader.loadSchemaFile()         INFO:     Loading schema from file(s): database/derby-message-archiving-schema-1.3.0.sql, URI: jdbc:derby:tigasedbx;create=true
2017-10-12 20:05:51.926 [main]             DBSchemaLoader.withConnection()         CONFIG:   DriverManager (available drivers): [org.apache.derby.jdbc.AutoloadedDriver@65262308, jTDS 1.3.1, com.mysql.jdbc.Driver@54997f67, com.mysql.fabric.jdbc.FabricMySQLDriver@189633f2, org.postgresql.Driver@76fc5687]
2017-10-12 20:05:52.209 [main]             DBSchemaLoader.lambda$loadSchemaFile$287()  INFO:  completed OK
2017-10-12 20:05:52.210 [main]             DBSchemaLoader.loadSchemaFile()         INFO:     Loading schema from file(s): database/derby-muc-schema-2.5.0.sql, URI: jdbc:derby:tigasedbx;create=true
2017-10-12 20:05:52.211 [main]             DBSchemaLoader.withConnection()         CONFIG:   DriverManager (available drivers): [org.apache.derby.jdbc.AutoloadedDriver@65262308, jTDS 1.3.1, com.mysql.jdbc.Driver@54997f67, com.mysql.fabric.jdbc.FabricMySQLDriver@189633f2, org.postgresql.Driver@76fc5687]
2017-10-12 20:05:52.305 [main]             DBSchemaLoader.lambda$loadSchemaFile$287()  INFO:  completed OK
2017-10-12 20:05:52.306 [main]             DBSchemaLoader.loadSchemaFile()         INFO:     Loading schema from file(s): database/derby-pubsub-schema-3.3.0.sql, URI: jdbc:derby:tigasedbx;create=true
2017-10-12 20:05:52.307 [main]             DBSchemaLoader.withConnection()         CONFIG:   DriverManager (available drivers): [org.apache.derby.jdbc.AutoloadedDriver@65262308, jTDS 1.3.1, com.mysql.jdbc.Driver@54997f67, com.mysql.fabric.jdbc.FabricMySQLDriver@189633f2, org.postgresql.Driver@76fc5687]
2017-10-12 20:05:52.731 [main]             DBSchemaLoader.lambda$loadSchemaFile$287()  INFO:  completed OK
2017-10-12 20:05:52.732 [main]             DBSchemaLoader.addXmppAdminAccount()    INFO:     Adding XMPP Admin Account, URI: jdbc:derby:tigasedbx;create=true
2017-10-12 20:05:52.732 [main]             DBSchemaLoader.addXmppAdminAccount()    CONFIG:   RepositoryFactory.getAuthRepository(null, jdbc:derby:tigasedbx;create=true,{data-repo-pool-size=1})
Oct 12, 2017 8:05:52 PM tigase.db.jdbc.DataRepositoryImpl initialize
INFO: Table schema found: jdbc:derby:tigasedbx;create=true, database type: derby, database driver: org.apache.derby.jdbc.EmbeddedDriver
Oct 12, 2017 8:05:52 PM tigase.db.jdbc.DataRepositoryImpl initialize
INFO: Initialized database connection: jdbc:derby:tigasedbx;create=true
2017-10-12 20:05:52.884 [main]             DBSchemaLoader.addXmppAdminAccount()    INFO:     All users added
2017-10-12 20:05:52.884 [main]             DBSchemaLoader.postInstallation()       INFO:     Post Installation, URI: jdbc:derby:tigasedbx;create=true
2017-10-12 20:05:52.891 [main]             DBSchemaLoader.withConnection()         CONFIG:   DriverManager (available drivers): [org.apache.derby.jdbc.AutoloadedDriver@65262308, jTDS 1.3.1, com.mysql.jdbc.Driver@54997f67, com.mysql.fabric.jdbc.FabricMySQLDriver@189633f2, org.postgresql.Driver@76fc5687]
2017-10-12 20:05:52.892 [main]             DBSchemaLoader.lambda$postInstallation$286()  INFO: Finalizing...
2017-10-12 20:05:52.893 [main]             DBSchemaLoader.lambda$postInstallation$286()  INFO:  completed OK
2017-10-12 20:05:52.895 [main]             DBSchemaLoader.shutdownDerby()          INFO:     Validating DBConnection, URI: jdbc:derby:tigasedbx;create=true
2017-10-12 20:05:53.129 [main]             DBSchemaLoader.withConnection()         SEVERE:


=====
Failure: Database 'tigasedbx' shutdown.
=====


Oct 12, 2017 8:05:53 PM tigase.db.util.SchemaManager loadSchemas
INFO: schema upgrade finished!




  =============================================================================
          Schema installation finished

  Data source: default with uri jdbc:derby:tigasedbx;create=true
          Checking connection to database        ok
          Checking if database exists        ok
          Loading schema: Tigase XMPP Server (Core), version: 8.0.0        ok
          Loading schema: Tigase Message Archiving Component, version: 1.3.0        ok
          Loading schema: Tigase MUC Component, version: 2.5.0        ok
          Loading schema: Tigase PubSub Component, version: 3.3.0        ok
          Adding XMPP admin accounts        ok
          Post installation action        ok

  Example etc/config.tdsl configuration file:

  'config-type' = 'default'
  debug = [ 'server' ]
  'virtual-hosts' = [ 'ubuntu' ]
  dataSource () {
      default () {
          uri = 'jdbc:derby:tigasedbx;create=true'
      }
  }
  amp () {}
  bosh () {}
  c2s () {}
  eventbus () {}
  http () {}
  'message-archive' () {}
  monitor () {}
  muc () {}
  pubsub () {}
  s2s () {}
  ws2s () {}
  =============================================================================

Note at the end, the script will output a recommended example file. You may use this in conjunction with your written config file, but some settings may not be set using this configuration. Again, it is only an EXAMPLE.

6.4.5. Start the Server

You can start the server using the tigase file found in the scripts sub-directory of Tigase server base directory. There, select the type of linux you have, debian, gentoo, mendriva or redhat. In the root server directory type the following command:

./scripts/{OS}/init.d/tigase start etc/tigase.conf

Where {OS} is your *nix operating system.

and you should get the output like this:

Starting Tigase:
nohup: redirecting stderr to stdout
Tigase running pid=18103

6.4.6. Check if it is Working

The server is started already but how do you know if it is really working and there were no problems. Have a look in the logs/ directory. There should be a few files in there:

 $ ls -l logs/
total 40K
-rw-r--r-- 1 20K 2009-02-03 21:48 tigase-console.log
-rw-r--r-- 1 16K 2009-02-03 21:48 tigase.log.0
-rw-r--r-- 1   0 2009-02-03 21:48 tigase.log.0.lck
-rw-r--r-- 1   6 2009-02-03 21:48 tigase.pid

The first 2 files are the most interesting for us: tigase-console.log and tigase.log.0. The first one contains very limited information and only the most important entries. Have a look inside and check if there are any WARNING or SEVERE entries. If not everything should be fine.

Now you can connect with an XMPP client of your choice with the administrator account you setup earlier.

6.5. Windows Installation

Tigase XMPP Server can also work on Microsoft Windows systems and servers, although some slight modifications may be necessary to get things ready to run.

Although you may wish to use command line, take note that commands entered in shell may require quotations in some cases.

Make sure that you have Java JDK v8 installed on your system prior to installing Tigase. It will also help to fully setup whatever database software you will be using as well.

6.5.1. Step 1: Initial Setup

Download the Tigase XMPP Server archive from our repository and extract it to a directory of your choice.

Once that is completed, enter the directory win-stuff and run the setup.bat program. This program when run, will extract the necessary files to appropriate places on your computer. The bat file should look like the following:

copy "tigase.ico" "..\"
copy "wrapper\wrapper.jar" "..\jars"
copy "wrapper\wrapper.dll" "..\jars"
copy "wrapper\wrapper.exe" "..\"
copy "wrapper\wrapper.conf" "..\"
copy "wrapper\wrapper-community-license-1.2.txt" "..\"
copy "scripts\*.*" "..\"

6.5.2. Step 2: Starting Server

To start the server you may use a command prompt from the installation directory

java -cp "jars/*" tigase.server.XMPPServer
Note
this may freeze the command window, and will only display output from Tigase.

Or you may run wrapper.exe or tigase.bat from the GUI.

2A: Installing as a service

The cleanest way to operate Tigase in a Windows environment is to install Tigase as a Service by running the InstallTigaseService.bat program. This will install Tigase as a system service, and now the server can be controlled from the services.msc panel. This allows for stopping, starting, and pausing of Tigase XMPP Server and allowing for graceful shutdowns.

For a basic installation, MySQL is recommended over Derby DB. For that purpose, we have included a basic installation guide for MySQL on Windows systems here:

6.5.3. MySQL Database Installation

The section describes installation and configuration of the MySQL database to work with Tigase server.

Download the binary package from MySQL download area at mysql.com. Make sure you select executable proper for your operating system.

Run the installation program and follow default installation steps. When the installation is complete find the MySQL elements in the Windows Start menu and run the MySQL Configuration Wizard. Follow the wizard and make sure to check settings against the screenshots in the guide below.

In Welcome window just press 'Next'.(pic.1)

sql1

In the next window select option: 'Detailed Configuration' and press 'Next' (pic. 2)

sql2

On the next screen select option: 'Server Machine' and press 'Next' (pic. 3)

sql3

On the forth windows leave the default" 'Multi-functional Database' and press 'Next' (pic. 4)

sql4

On the step number five just press 'Next' using defaults. (pic. 5)

sql5

Again, on window 6 select the default - 'Decision Support (DSS)/OLAP' and press 'Next' (pic.6)

sql6

Make sure you switch OFF the 'Strict mode' and and press 'Next' (pic. 7)

sql7

On the character encoding page select: 'Manual Selected Default Character set/ Collation' and 'utf8', press 'Next' (pic.8)

sql8

On next window select 'Include Bin Directory in Windows PATH' and press 'Next' (pic.9)

sql9

On this window just enter the database super user password and make sure you remember it. When ready press 'Next' (pic. 10)

sql10

This is the last screen. Press 'Execute' to save the configuration parameters. (pic. 11)

sql11

When the configuration is saved you can repeat all the steps and change settings at any time by running: START ⇒ Programs ⇒ MYSQL⇒ MYSQL serwer machine⇒ MySQL Server Instance Config Wizard

Now we have to setup Tigase database. From the Start menu run the MySQL console and enter all commands below finishing them with <ENTER>:

  1. Create the database:

    mysql>create database tigasedb;
  2. Add database user:

    mysql> GRANT ALL ON tigasedb.* TO tigase_user@'%' IDENTIFIED BY 'tigase_passwd';
    mysql> GRANT ALL ON tigasedb.* TO tigase_user@'localhost' IDENTIFIED BY 'tigase_passwd';
    mysql> GRANT ALL ON tigasedb.* TO tigase_user IDENTIFIED BY 'tigase_passwd';
    mysql> FLUSH PRIVILEGES;
  3. Load Tigase database schema:

    mysql> use tigasedb;
    mysql> source c:/Program Files/Tigase/database/mysql-schema.sql;

When the system is up and running you can connect with any XMPP client (Psi for example) to your server to see if it is working.

6.6. Tigase Server Network Instructions

One you have installed Tigase XMPP Server on a machine, you’re going to want to use it. If you are just using for local communications on a network behind a router, you’re all set. Enjoy and use!

However, if you want to have people from other computers outside your network connect to your server, you’re going to have to go through a few more steps to show your server out to the public.

Note
This guide is merely a recommendation of how to get a local server to be open to incoming communications. Any time you open ports, or take other security measures you risk compromising your network security. These are only recommendations, and may not be appropriate for all installations. Please consult your IT Security expert for securing your own installation.

XMPP, being a decentralized communication method, relies on proper DNS records to figure out where and how an XMPP server is setup. Operating an XMPP Server will require you to properly setup DNS routing so not only can clients connect to you, but if you decide to run a federated server and enable server to server communication, you will need to do the same. If you already have a DNS server already, you should have little issue adding these records. If you do not have a DNS setup pointing to your server, you may use a free dynamic name service such as dynu.com.

6.6.1. A Records

You will not be able to use an IP Address or a CNAME record to setup an XMPP Server. While it’s not required, an A record can provide some other benefits such serving as a backup in case the SRV record is not configured right.

6.6.2. SRV Records

You will need to set SRV records both for client-to-server (c2s) communication and, if you plan to use it, server to server (s2s) communication. We recommend both records are entered for every server as some resources or clients will check for both records. For this example we will use tigase.org is our domain, and xmpp as the xmpp server subdomain.

SRV records have the following form:

_service._protocol.name. TTL class SRV Priority weight port target.

The key is as follows:

  • service: is the symbolic name of the desired service, in this case it would be xmpp-client or xmpp-server.

  • protocol: is the transport protocol, either TCP or UDP, XMPP traffic will take place over TCP.

  • name: the domain name where the server resides, in this case tigase.org.

  • TTL: a numeric value for DNS time to live in milliseconds, by default use 86400.

  • class: DNS class field, this is always IN.

  • priority: the priority of the target host with lower numbers being higher priority. Since we are not setting up multiple SRV records, we can use 0.

  • weight: the relative weight for records with the same priority. We can use 5.

  • port: the specific TCP or UDP port where the service can be found. In this case it will be 5222 or 5269.

  • target: the hostname of the machine providing the service, here we will use xmpp.tigase.org.

For our example server, the SRV records will then look like this:

_xmpp-client._TCP.tigase.org 86400 IN SRV 0 5 5222 xmpp.tigase.org

_xmpp-server._TCP.tigase.org 86400 IN SRV 0 5 5269 xmpp.tigase.org

Tigase and Vhosts

If you are running multiple vhosts or subdomains that you wish to separate, you will need another record. In this case an A record will be all you need if you are using default ports. If you are using custom ports, you will need to have a new SRV record for each subdomain.

6.6.3. Hosting VIA Tigase.me

If you don’t want to do all the hosting yourself, you can still have an XMPP service running in your own domain. The only condition right now is that this must be a DNS registered domain and DNS must point to the following DNS address: tigase.me. Please note, do not confuse it with tigase.im domain name.

Although SRV records are required by the XMPP specifications we do not require SRV records either. If you want to register: your-domain.tld on our XMPP service make sure that either the command:

$ host your-domain.tld
your-domain.tld has address 94.23.164.209

This displays 94.23.164.209 address or commands:

$ host -t SRV _xmpp-server._tcp.your-domain.tld
_xmpp-server._tcp.your-domain.tld has SRV record 10 0 5269 tigase.me.
$ host -t SRV _xmpp-client._tcp.your-domain.tld
_xmpp-client._tcp.your-domain.tld has SRV record 10 0 5222 tigase.me.

This displays tigase.me DNS name. We strongly recommend not to use the IP address directly however, as if the service grows too much, it will be much easier for us to migrate and expand it using the DNS name rather then IP address.

If you want to have MUC and PubSub available under your domain as subdomains, you have to setup DNS for your muc.your-domain.tld and pubsub.your-domain.tld domains too.

For MUC:

$ host -t SRV _xmpp-server._tcp.muc.your-domain.tld
_xmpp-server._tcp.muc.your-domain.tld has SRV record 10 0 5269 tigase.me.
$ host -t SRV _xmpp-client._tcp.muc.your-domain.tld
_xmpp-client._tcp.muc.your-domain.tld has SRV record 10 0 5222 tigase.me.

For PubSub :

$ host -t SRV _xmpp-server._tcp.pubsub.your-domain.tld
_xmpp-server._tcp.pubsub.your-domain.tld has SRV record 10 0 5269 tigase.me.
$ host -t SRV _xmpp-client._tcp.pubsub.your-domain.tld
_xmpp-client._tcp.pubsub.your-domain.tld has SRV record 10 0 5222 tigase.me.

Now, how do you register your domain with our service?

There are a few ways. We recommend checking with the Add and Manage Domains section of the documentation on setting that up. If you cannot or don’t want to do it on your own, the way described in the guide please send us a message, either via XMPP to admin@tigase.im or the contact form requesting new domain. User registration is available via in-band registration protocol. You can also specify whether you want to allow anonymous authentication to be available for your domain and you can specify maximum number of users for your domain.

6.6.4. Checking setup

If you have a cell phone on a separate network with an XMPP client, you can now try to login to test the server. If that is not handy, you can use an online tool to check proper DNS records such as kingant’s: https://kingant.net/check_xmpp_dns/ and it will tell you if anything is missing.

6.6.5. Ports description

Once your server is setup, you may need to open at least two ports. By default XMPP communication happens on ports 5222/5269, to which point SRV records. Other ports used by the server are:

  • 3478 (TURN or STUN, plain socket, TCP and UDP)

  • 5349 (TURN or STUN, over TLS, TCP and UDP)

  • 5222 (default XMPP socket port)

  • 5223 (legacy XMPP socket port)

  • 5269 (default s2s port, i.e.: federation support)

  • 5277 (component protocol port, e.g.: for external components)

  • 5280 (default BOSH port)

  • 5290 (default WebSocket port)

  • 8080 (HTTP API component port)

  • 9050 (JMX Monitoring)

If for any reason you can’t use default ports and have to change them it’s possible to point SRV records those ports. Please keep in mind, that you have to open those ports for incoming connections in your firewall. In case you are using iptables you can use following command to include those ports in your rules:

iptables -A INPUT -p tcp -m tcp --dport 5222 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 5223 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 5269 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 5277 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 5280 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 5290 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 9050 -j ACCEPT

Both ports should be setup to use TCP only. If for any reason you want to make service available for different ports you can:

  1. change ports in Tigase configuration and update DNS SRV records;

  2. forward those ports to default Tigase ports (this is especially useful under *nix operating system if you want to utilize ports lower than 1024 while running, as recommended, Tigase service from user account - there is a limitation and user accounts can bind to ports lower than 1024), for example using iptables rules (in following example we are making available Tigase SSL websocket port available under port 443, which is usually opened in corporate firewalls):

    iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 5291

6.7. Tigase Script Selection

As mentioned in each of the quick start sections, each distribution of Tigase XMPP server comes with a number of scripts that are customized for different versions of Linux.

Table 1. init.d chart
Operating system init.d file path Types of Operating Systems

Debian

tigase-server/scripts/debian/tigase.init.d

Knoppix, Ubuntu (before v15.04), Raspbian or Duvian

Gentoo

tigase-server/scripts/gentoo/init.d/tigase

CoreOS (before v94.0.0), Tin Hat Linux or other *too based systems

Mandriva

tigase-server/scripts/mandriva/init.d/tigase

Specific init.d file for Mandriva Linux

Redhat

tigase-server/scripts/redhat/init.d/tigase

RedHat (before v7.0) and other RPM based linux derivatives like CentOS (before v.7.14), openSUSE (before v12.2)

We currently don’t support systemd - please see systemd: Availability for the complete reference of supported distributions and appropriate versions.

6.7.1. Configuration: For All Linux Distributions

Once you’ve located the appropriate distribution scripts (please take a look at the table above), copy it to your system’s init.d folder (usually it’s /etc/init.d/):

sudo cp $SCRIPT_FILE_PATH /etc/init.d/tigase

You may also need to make it executable:

sudo chmod +x /etc/init.d/tigase

It is recommended that you open the script files or configuration files as some have some parameters that you will need to specify.

Gentoo

The conf.d script must contain the following parameters:

TIGASE_HOME="/home/tigase/tigase-server"
TIGASE_USER=tigase
TIGASE_CONF="etc/tigase.conf"

The following should be configured:

  • TIGASE_HOME - Specifies the Tigase Server installation directory.

  • TIGASE_USER - Specifies the user that will run the program. This should be a user with SU permissions.

  • TIGASE_CONF - The location of tigase.conf file, relative to the TIGASE_HOME directory.

Mandriva

Mandriva has a single init.d file, however it should be configured:


export JAVA_HOME=/usr/java/jdk1.8.0
export TIGASE_DIR=/opt/tigase/server/
tigase=$TIGASE_DIR/scripts/tigase.sh
prog=tigase
config=$TIGASE_DIR/etc/tigase.conf

The following should be configured:

  • JAVA_HOME - The location of your JDK Installation.

  • TIGASE_DIR - Tigase Server installation directory.

  • tigase - The location of your tigase.sh script. This should not need adjusting if you maintain the default file structure.

  • config - The location of your tigase.conf file. This should not need adjusting if you maintain the default file structure.

pid file will be stored in /var/run/ser.pid

Redhat

Similar to Mandriva, you will need to configure the init.d file:


JAVA_HOME=/usr/lib/jvm/java/

USERNAME=tigase
USERGROUP=tigase
NAME=tigase
DESC="Tigase XMPP server"

TIGASE_HOME=/home/tigase/tigase-server
TIGASE_LIB=${TIGASE_HOME}/jars
TIGASE_CONFIG=/etc/tigase.conf
TIGASE_OPTIONS=
TIGASE_PARAMS=

PIDFILE=
TIGASE_CONSOLE_LOG=
  • USERNAME - Username running Tigase, should have su permissions.

  • USERGROUP - The usergroup of the username.

  • NAME - OS name for Tigase program.

  • DESC - Optional description.

  • TIGASE_HOME - The location of your Tigase Server installation directory.

  • TIGASE_LIB - The location of your Tigase Jars folder, you should not need to adjust this if you set TIGASE_HOME properly, and maintain the default file structure.

  • TIGASE_CONFIG - The location of your tigase.conf file relative to TIGASE_HOME

  • TIGASE_OPTIONS - Legacy options for Tigase, most are now handled in config.tdsl or tigase.conf.

  • TIGASE_PARAMS - Parameters passed to command line when launching Tigase.

  • PIDFILE - Location of Tigase PID file if you wish to use custom directory. Default will be located in /logs or /var/temp directory.

  • TIGASE_CONSOLE_LOG - Location of Tigase Server console log file if you wish to use a custom directory. Default will be located in /logs directory, failing that /dev/null.

After you’ve copied the script, in order to install sysinit script you have to add it to the configuration:

/sbin/chkconfig --add tigase

Service can be enabled or disabled service with:

/sbin/chkconfig tigase <on|off|reset>
Debian

As with other distributions you should copy init.d script to the correct location. Afterwards it should be edited and correct values for variables need to be set:

…
USERNAME=tigase
USERGROUP=tigase
NAME=tigase
DESC="Tigase XMPP server"

TIGASE_HOME=/usr/share/tigase
TIGASE_CONFIG=/etc/tigase/tigase.config
TIGASE_OPTIONS=
TIGASE_PARAMS=

PIDFILE=
TIGASE_CONSOLE_LOG=
…
  • USERNAME - Username running Tigase, should have su permissions.

  • USERGROUP - The usergroup of the username.

  • NAME - OS name for Tigase program.

  • DESC - Optional description.

  • TIGASE_HOME - The location of your Tigase Server installation directory.

  • TIGASE_CONFIG - The location of your tigase-server.xml file relative (old configuration format)

  • TIGASE_OPTIONS - command line arguments passed to Tigase server (which may include path to init.properies (if correct tigase.conf configuration will be found then it will translate to TIGASE_OPTIONS=" --property-file etc/config.tdsl "

  • TIGASE_PARAMS - Parameters passed to command line when launching Tigase.

  • PIDFILE - Location of Tigase PID file if you wish to use custom directory. Default will be located in /var/run/tigase/tigase.pid or under (in this case relative to tigase home directory)logs/tigase.pid.

  • TIGASE_CONSOLE_LOG - Location of Tigase Server console log file if you wish to use a custom directory. Default will be located in /logs directory, failing that /dev/null.

Afterwards we need to install service in the system with following command:

update-rc.d tigase defaults

6.7.2. Running Tigase as a system service

There are a number of benefits to running Tigase as a service, one of which is to ensure that the program will run even in the event of a power outage or accidental server restart, Tigase will always be up and running.

Once installation is complete, you should be able to start Tigase using the following command:

service tigase start

Tigase should begin running in the background. Since Tigase is now installed as a service, it can be controlled with any of the service commands, such as:

  • service tigase stop

  • service tigase restart

6.8. Shutting Down Tigase

Although Tigase XMPP Server can be terminated by ending the process, it is preferred and recommended to use it’s own shutdown scripts instead. Not only does this allow for a proper purge of Tigase form the system, but allows for all shutdown functions to operate, such as amending logs and completing statistics. To trigger a shutdown of Tigase server, the following command can be used from the tigase directory:

./scripts/tigase.sh stop

You may specify the config file if you want, but it will make no differences

This will:

  • Begin shutdown thread

  • Stop accepting new connections

  • Close all current connections

  • Collect runtime statistics

  • Write statistics to log

  • Dump full stacktrace to a file

  • Run GC and clear from memory

6.8.1. Shutdown statistics

Upon shutdown, statistics for the server’s runtime will be appended to the log file. For a description of the statistics and what they mean, refer to the Statistics Description portion of the documentation.

6.8.2. Shutdown StackTrace Dump

To aid with troubleshooting purposes, the full stacktrace will be dumped to a seperate file located at $serverdir/logs/threads-dump.log.# Stacktrace logs will follow the same log file numbering scheme described in Log file description.

This feature is enabled by default, however you may disable this by adding the following to your config.tdsl file:

'shutdown-thread-dump' = false

6.8.3. Shutting Down Cluster Nodes

Starting with v8.0.0 you can now shut down individual cluster nodes without shutting down the whole server. This command will use the SeeOtherHost strategy to direct traffic to other nodes and update the cluster map to gracefully shut down the single node

Shutting down individual nodes can be done VIA Ad-hoc command and fill out the response forms. The command is available from message-router as http://jabber.org/protocol/admin#shutdown.

6.9. Upgrading to v8.0.0 from v7.1.0

There have been a number of changes to the user and auth databases since v7.1.0. As a result, if you are upgrading from older versions, you will need to follow this guide.

Note
We recommend installing Tigase v8.0.0 in a separate directory.

6.9.1. Backup your data

As with any migration it is highly recommended that you backup your repository before conducting any upgrade operations.

For MySQL databases:

mysqldump [dbname] --routines -u [username] -p [password] > [filename].sql

6.9.2. Setup Tigase v8.0.0

After downloading tigase v8.0.0 from our website, or using wget, extract the files to a separate directory.

Copy the tigase.conf and init.properties files from the old directory to v8.0.0 directory.

cd tigase-server-8.0.0
cp ../tigase-server/etc/tigase.conf etc/
cp ../tigase-server/etc/init.properties etc/

Import the database.

mysql -h [host address] [dbname] -u [username] -p [password] < [filename].sql
mysql -h 198.27.120.213 tigase_tpub -u USERNAME -p <../tpub.2017-05-30.sql
Enter password:

6.9.3. Upgrade configuration file

Tigase XMPP Server has a utility that can be called using upgrade-config that will update your old init.properties file and create a new file using DSL.

./scripts/tigase.sh upgrade-config etc/tigase.conf
Configuration file etc/init.properties was converted to DSL format.
Previous version of a configuration file was saved at etc/init.properties.old

6.9.4. Connect new database

Edit your new config.tdsl file to connect to the new database you created during the import step.

dataSource {
    default () {
        uri = 'jdbc:mysql://localhost/tigase_tpub?user=tigase_user&password=mypass'
    }
}
userRepository {
    default () {}
}
authRepository {
    default () {}
}

6.9.5. Upgrade Database schema

Upgrading database schemas is now possible using the upgrade-schema option. Do this now.

./scripts/tigase.sh upgrade-schema etc/tigase.conf
Warning
Your database schema MUST be v8 or conversion will not occur properly!

You will be asked the following prompts:

Database root account username used to create tigase user and database at 198.27.120.213 :

Database root account password used to create tigase user and database at 198.27.120.213 :

Upon success, you should see the following:

=============================================================================
        Schema upgrade finished

  Data source: default with uri
jdbc:mysql://HOST/DATABASE?user=USERNAME&password=PASSWORD
        Checking connection to database ok
        Checking if database exists     ok
        Loading schema: Tigase XMPP Server (Core), version: 8.0.0       ok
        Loading schema: Tigase Message Archiving Component, version:
1.3.0      ok
        Loading schema: Tigase MUC Component, version: 2.5.0    ok
        Loading schema: Tigase PubSub Component, version: 3.3.0 ok
        Adding XMPP admin accounts      warning
                Message: Error: No admin users entered
        Post installation action        ok

=============================================================================

Start Tigase!

6.9.6. Help?

Both upgrade commands also have a build in help function, they can be called if needed from the command line. You can also run these commands for help.

scripts/tigase.sh upgrade-config etc/tigase.conf --help
scripts/tigase.sh upgrade-schema etc/tigase.conf --help

7. Configuration

When the user tries to setup the client for the first time he comes across 2 configuration files: tigase.conf and config.tdsl in the /etc folder. Here is a brief explanation what all those files are about and in other sections you can learn all the details needed to configure the server.

  1. config.tdsl file is a simple text file with server parameters in form: key = value. When the XML configuration file is missing the Tigase server reads config.tdsl file and uses parameters found there as defaults for generation of the XML file. Therefore if you change the config.tdsl file you normally have to stop the server, remove the XML file and start the server again. All the settings from the config.tdsl are read and applied to the XML configuration. The properties file is easy to read and very safe to modify. At the moment this is the recommended way change the server configuration.

  2. tigase.conf is the Tigase server startup configuration. It is actually not used by the server itself. It rather contains operating system settings and environment parameters to correctly run the Java Virtual Machine. It is only useful on the unix-like systems with Bash shell. If you run the server on MS Windows systems tigase.bat and wrapper.conf files are used instead. The tigase.conf file is read and loaded by the scripts/tigase.sh shell script which also scans the operating system environment for Java VM and other tools needed.

7.1. DSL file format

In previous Tigase XMPP Server releases configuration was stored in properties based configuration file. From Tigase XMPP Server 8.0.0 release it will be required to use new DSL based configuration file format. This file format was inspired by Groovy language syntax and new core feature of Tigase XMPP Server - Tigase Kernel Framework.

7.1.1. Why new format?

In properties configuration format each line contained key and value with optional definition of type of stored value:

c2s/ports[i]=5222,5223

where c2s/ports was name of property, [i] defined that type of value is array of integers, and 5222,5223 was comma separated list of values.

This format worked but in fact c2s/ports was not name of property you configured but key which was later split on / char to parts which defined by names path to property which name was in last part. From that you can see that it was domain based setting of properties.

Except from this multi-part keys we also used properties starting with -- which were global properties accessible for every part of application, i.e.: to add new component and set some properties you needed to write:

--comp-name-1=pubsub
--comp-class-1=tigase.pubsub.PubSubComponent
pubsub/test[B]=true
pubsub/pubsub-repo-url="jdbc:XXXX:XXXX/db_name"

This lead to mistakes like duplicated definition of name and class for same number of component or redefined property value in other place of a configuration file - especially in cases where configuration was big.

In this configuration structure it was hard to tell where is configuration for particular component or what databases this installation uses. This could be defined all over the file.

In this release we are introducing Tigase Kernel Framework, which allows to configure beans in configuration file and even define usage of new beans loaded from external jars which can modify behavior of Tigase components. This would make configuration file even more complex, difficult and less readable.

7.1.2. What is DSL?

DSL stands for domain-specific language - in this case language created for storage of configuration.

Now we use domain based configuration which means that our configuration file is not a flat key=value storage but it defines objects, it’s properties and assigned values.

To illustrate it better let’s start with a simple example. In properties file in order to configure PubSub component named pubsub you would use following properties:

--comp-name-1=pubsub
--comp-class-1=tigase.pubsub.PubSubComponent
pubsub/test[B]=true

In DSL based configuration this would be replaced by following block

pubsub (class: tigase.pubsub.PubSubComponent) {
    # comment
    test = true
}

in which we define bean with name pubsub and set it’s class inside () block to tigase.pubsub.PubSubComponent. We also use block between {} chars to define properties which are related to bean. Which means this properties will be passed only to this instance of Tigase PubSub Component, same as it was before where we needed to add prefix. Entries after # are comments, to pass # you need to wrap whole part containing it in '', ie. 'test#242'

Warning
If a string value assigned to a property contains any char from a following list =:,[]#+-*/ it needs to be wrapped in a ''.

7.1.3. Why DSL?

DSL configuration format provides a number of advantages over the old system of configuration. . All configurations for components are related in a single block, so they are not spread out over several different lines. . No need for long property names, no longer have to invoke a long string of settings for multiple values. . Support is provided for environment variables. . No longer need to escape certain characters, making settings far more readable at a glance. . Values may be set using basic calculations, such as 100 * 200 * 2 rather than 40000. . Parameter type values are no longer necessary, no more [i], [S], [B] etc.. . Comma separated values can now be simplified lists with separate entries being able to be in multiple lines.

Although the format may seem more complex, looking like a section of java code, the formatting is consistent and can be far more readable. After some experience with DSL format, you’ll find it’s far more intuitive and user friendly than it may appear. Of course if there’s any real confusion, Tigase can automatically convert old style properties files to the DSL format using the following command:

./scripts/tigase.sh upgrade-config etc/tigase.conf
Setting property

To set property you just write property name followed by = and value to set. This is always done in context of bean which configuration property you want to set.

test=true

It is also possible to set property in main context by placing property outside of any context. This sets property which value is available to access by any bean.

Setting global property

Like in properties file it is still possible to use property names starting with -- without any context or any other properties at global scope. Format is the same as in case of setting property but they are defined without scope (in global scope). This properties are global and accessible by any bean but also set as system property in JVM.

Defining bean

You can configure bean by using following format:

beanName (class: className, active: activeValue, exportable: exportableValue) {
    # scope of bean properties
}

where beanName is name under which you want to configure bean. beanName must be wrapped in '', if beanName contains characters like =:,[]#+-*/ and is recommended, if beanName is numeric only.

Inside block between ( and ) you can define:

  • class which will be used as a bean, in example above we set class as className. (default: if you try to configure bean under name which has default class assigned with it in Tigase framework then this assigned class will be used. In other case you need to pass name of class to use as a bean)

  • active (boolean) whether you want the bean to be active or not (beans with active set to false are not loaded). (default: true)

  • exportable (boolean) defines if this bean should be exported and available for use for beans in inner scopes. This is advanced option in most cases it is recommended to omit this field in configuration. (default: false)

Spaces between beanName and block between () is optional as well as space between block () and block {}. It is recommended that properties of bean would be placed in separate lines with indentation and first property will be placed in new line.

Important

Usage of () block is very important. When this block is used in configuration it automatically sets active property of bean definition for bean for which it is used to to true. This is done due to fact that default value of active is true.

If you omit it in configuration, you will set bean configuration but it may remain inactive. In this state bean will not be loaded and as a result will not be used by Tigase XMPP Server.

Configuring bean

If you know that bean is defined and you do not want to change it’s activity or class then you can just pass properties to configure bean in following way:

beanName {
    # scope of bean properties
    test = true
}

where beanName is name of bean to configure and test is name of property to set to true in this bean.

Format of values

In properties based configuration file every property was defined as a string and only by defining expected format it was properly converted to expected value. In DSL it is possible to set values in two ways:

as an object

Using this format you set list as a list and integer is set as an integer.

Type Description

string

Wrap it in '', ie. to set test as string you use 'test'

integer

Just put value, ie. to set 543 use 543

long

Put value and follow it with L, ie. to set 23645434 as long use 23645434L

float

Put value and follow it with f, ie. to set 231.342 use 231.342f

boolean

To set value just use true or false

list

Lists can be of many types and to make it simple we decided to use as a comma separated list of values in proper format wrapped in [].

  • of strings - [ 'alfa', 'beta', 'gamma' ]

  • of integers - [ 1, 2, 3, 4]

You can write it in multiple lines if you want:

[
    'alfa'
    'beta'
    'gamma'
]

map

Maps can be written as a block of properties wrapped in {}. This format of map is the same as used for passing configuration to bean properties. Keys and values can be written in separate lines (recommended):

{
    test = true
    ssl = false
    ssl-certificate = '/test/cert.pem'
    another-map = {
        key = 'value'
    }
}

or in single line (separation with spaces is not required):

{ test = true, ssl = false, ssl-certificate = '/test/cert.pem' }
as a plain string

Very similar to properties based configuration, in fact values are passed in same format and later are converted to correct type by checking type expected by bean. (Not recommended)

Type Description

string

Just put value, ie. to set test use test

integer

Just put value, ie. to set 543 use 543

long

Put value, ie. to set 23645434 as long use 23645434

float

Put value, ie. to set 231.342 use 231.342

boolean

To set value just use true or false

list

List needs to be written as comma separated list of values, ie. test,abc,efg or 1,2,3

map

Not possible

Using values from System Properties and Environment Variables

Now it is possible to use values of system properties and environment variables and assign them to bean properties. For this purpose we added functions which can be used in DSL and which will return values of:

system property

prop('property-name') or prop('property-name','default value')

environment variable

env('variable-name')

Example of setting value of system property and environment variable to bean user
user {
  name = env('USER')
  home = prop('user.home')
  paths = [ prop('user.home'), prop('user.dir') ]
}
Warning
For properties which accepts lists it is not allowed to set value using variable/property with comma separated values like value1,value2 wrapped in [], ie. property = [ env('some-variable') ]. It needs to be set in following way property = env('some-variable')
Computed values

With DSL configuration format we introduce support for computable values for properties. It is now possible to set value which is result of a computation, ie. concatenation of a strings or very simple mathematical expression. We currently support only following mathematical operations:

  • add

  • subtract

  • multiply

  • divide

Example of setting environment variable related path and computed timeout
bean {
  # setting path to `some-subdirectory` of user home directory
  path = prop('user.home') + '/some-subdirectory/'

  # setting timeout to 5 minutes (setting value in milliseconds)
  timeout = 5L * 60 * 1000
  # previously it would need to be configured in following way:
  # timeout = 300000L
}
Warning
For properties which accepts lists it is not allowed to set value using computed values with comma separated values like value1,value2 wrapped in [], ie. property = [ env('some-variable') + ',other-value' ]. It needs to be set in following way property = env('some-variable') + ',other-value'.

7.1.4. Example configuration file in DSL

# Enable cluster mode
--cluster-mode = true
# Enable debugging for server and xmpp.impl
--debug = 'server,xmpp.impl'
# Set list of virtual hosts (old way)
--virt-hosts = 'example.com,test-1.example.com,test-2.example.com'

# Configure list of administrator jids
admins = [ 'admin@zeus', 'http@macbook-pro-andrzej.local' ]
# Set config type
config-type = '--gen-config-def'

# Configure dataSource bean with database configuration
dataSource {
    # Configure default data source (using default implementation so class is omitted)
    default () {
        uri = 'jdbc:postgresql://127.0.0.1/tigase?user=test&password=test&autoCreateUser=true'
    }

    # Configure data source with name exaple.com (will be used by domain example.com)
    'example.com' () {
        uri = 'jdbc:mysq://127.0.0.1/example?user=test&password=test&autoCreateUser=true'
    }
}

# Configure C2S component
c2s {
    # Enable Stream Management bean
    'urn:xmpp:sm:3' () {}

    # Register tigase.server.xmppclient.SeeOtherHostDualIP as seeOtherHost bean
    seeOtherHost (class: tigase.server.xmppclient.SeeOtherHostDualIP) {}

    # Add additional port 5224 which is SSL port and disable port 5223
    connections () {
        '5224' () {
                 socket = ssl
              }
        '5223' (active: false) {}
    }
}

# Configure HTTP API component
http {
    # Set list of API keys
    api-keys = [ 'test1234', 'test2356' ]
    rest {
        # Set value of environment property as a path to look for REST scripts
        rest-scripts-dir = env('TIGASE_REST_SCRIPTS_DIR')
    }
}

# Register pubsub-2 (class is passed as pubsub-2 name do not have default class assigned)
pubsub-2 (class: tigase.pubsub.cluster.PubSubComponentClustered) {
    # Set configuration bean properties
    pubsubConfig {
        persistentPep = true
    }
    # Use tigase.pubsub.cluster.ClusteredNodeStrategy as advanced clustering strategy
    strategy (class: tigase.pubsub.cluster.ClusteredNodeStrategy) {}
}

# Configure Session Manager
sess-man {
    # Here we enable pep, urn:xmpp:mam:1 processors and disable message-archive-xep-0136 processor
    pep () {}
    'urn:xmpp:mam:1' () {}
    message-archive-xep-0136 (active: false) {}

    # Define class used as clustering strategy (it is different than default so class is required)
    strategy (class: tigase.server.cluster.strategy.OnlineUsersCachingStrategy) {}
}

7.1.5. Default configuration

Tigase XMPP Server is packaged with a basic config.tdsl file that tells the server to start up in setup mode.

'config-type' = 'setup'

http () {
    setup () {
        'admin-user' = 'admin'
    'admin-password' = 'tigase'
    }
}

This tells Tigase to operate in a setup mode, and tells the http component to allow login with the username and password admin/tigase. With this you can enter the setup process that is covered in this section.

There are other options for config-type: default, session-manager, connection-managers, and component. For more information, visit Config Type property description.

7.2. Startup File for tigase.sh - tigase.conf

Property file names for tigase.sh startup script is a second parameter for the startup script. It can be skipped if environmental variables are set in different location or in different way.

Config file for startup script simply sets number of environment variables with the location of required components. Possible variables to set in this file are:

  • JAVA_HOME - location of Java installation home directory. Must be set.

  • TIGASE_HOME - location of Tigase installation home directory. By default script try to find this location by searching directories from the location where the script has been run.

  • TIGASE_CONSOLE_LOG - file to which all console messages will be redirected if server is run in background. By default it will be: TIGASE_HOME/logs/tigase-console.log. If this file/directory is not writable by Tigase process all console messages will be redirected to /dev/null

  • TIGASE_PID location of the file with server PID number. By default it will be TIGASE_HOME/logs/tigase.pid.

  • JAVA_OPTIONS - options for JVM like size of RAM allocated for the JVM, properties and so on.

  • TIGASE_OPTIONS - additional options for Tigase server program. You can tweak initial parameters for your environment here.

Sample file to run Tigase with PostgreSQL database may look like:

ENC="-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8"
DRV="-Djdbc.drivers=org.postgresql.Driver"
JAVA_OPTIONS="${ENC} ${DRV} -server -Xms100M -Xmx100M "
CLASSPATH=""
TIGASE_CONFIG="tigase-pgsql.xml"
TIGASE_OPTIONS=" --property-file etc/config.tdsl "

Please note encoding settings. JVM by default uses encoding set in operating system environment. XMPP protocol, however uses UTF-8 for all data processing. So the ENC settings enforces UTF-8 encoding for all operations.

Another significant setting is \'CLASSPATH'. It is intentionally set to an empty string. The tigase.sh startup script builds the CLASSPATH on it’s own from files found in jars/ and libs/ directories. It is advised to set the CLASSPATH to the empty string because the Tigase server scans all available classes to find all components and plugins implementation. If the CLASSPATH contains lots of libraries which are not used anyway it can cause a long startup time and high system loads.

7.3. Linux Settings for High Load Systems

There are a few basic settings you have to adjust for high load systems to make sure the server has enough resources to handle a big number of network connections.

The main parameter is a maximum number of opened files allowed for the process to keep at the same time. Each network connection uses a file handler, therefore if the limit is too low you can quickly run out of handlers and the server can not accept any more connections.

This limit is set on 2 levels - on the kernel level (fs.file-max) and on the system level (nofile).

Another kernel property which can be important in certain configurations (like transports installations or when you use proxy for Bosh connections) is: net.ipv4.ip_local_port_range. This parameter can be set the same way as the fs.file-max property.

7.3.1. fs.file-max

The fs.file-max kernel property is set via sysctl command. You can see current settings by executing the command:

# sysctl fs.file-max
fs.file-max = 358920

If you plan to run high load service with large number of server connections, then this parameter should be at least as twice big as the number of network connections you expect to support. You can change this setting by executing the command:

# sysctl -w fs.file-max=360000
fs.file-max = 360000

7.3.2. net.ipv4.ip_local_port_range

You can see current settings by executing the command:

# sysctl net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 32768        61000

You can change this setting by executing the command:

# sysctl -w net.ipv4.ip_local_port_range="1024 65000"
net.ipv4.ip_local_port_range = 1024 65000

7.3.3. TCP_keepalive

According to blog.kolargol.eu or www.gnugk.org/ some keepalive settings should be changed to improve reliability.

# sysctl -w net.ipv4.tcp_keepalive_time="60"
net.ipv4.tcp_keepalive_time = 60
# sysctl -w net.ipv4.tcp_keepalive_probes="3"
net.ipv4.tcp_keepalive_probes = 3
# sysctl -w net.ipv4.tcp_keepalive_intvl="90"
net.ipv4.tcp_keepalive_intvl = 90

7.3.4. /etc/sysctl.conf

The above commands let the system remember new settings until the next system restart. If you want to make the change permanent you have to edit the file: /etc/sysctl.conf and add the property at the end of the file:

fs.file-max=360000
net.ipv4.ip_local_port_range=1024 65000
net.ipv4.tcp_keepalive_time=60
net.ipv4.tcp_keepalive_probes=3
net.ipv4.tcp_keepalive_intvl=90

It will be automatically loaded next time you start the server.

Command:

# sysctl -p

Causes the /etc/systcl.conf to be reloaded which is useful when you have added more parameters to the file and don’t want to restart the server.

7.3.5. nofile

This is the property used by the system limits. For example running the command ulimit -a shows you all limits set for the current user:

# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
pending signals                 (-i) 38912
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 40960
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 38912
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

To make it even more interesting and more complex, there are 2 types of system limits: soft limit which can be temporarily exceeded by the user and hard limit which can not be exceeded. To see your hard limit execute command:

# ulimit -a -H
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
pending signals                 (-i) 38912
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 40960
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
stack size              (kbytes, -s) unlimited
cpu time               (seconds, -t) unlimited
max user processes              (-u) 38912
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

The hard limits are usually bigger then the soft limits or sometimes the same.

For us the most important parameter is: open files. You can change the property in file: /etc/security/limits.conf. You have to append 2 following lines to the end of the file:

jabber               soft    nofile         350000
jabber               hard    nofile         350000

Where the jabber is the user name of the account running you IM service. You can also set the limits for all users on the machine in a following way:

*               soft    nofile         350000
*               hard    nofile         350000

For those changes to make an effect you have to logout from the modified account and login again. New limits should be applied.

7.3.6. su and init script

If one intends to use init scripts for startup purposes (or simply wants to be able to start the server utilizing su command) it’s necessary to adjust PAM configuration by modifying /etc/pam.d/su file and uncomment following line:

session    required   pam_limits.so

Afterwards the init scripts will respect configured limits.

7.4. JVM settings and recommendations

Tigase configuration file tigase.conf (described in more detail in Startup File for tigase.sh - tigase.conf) mentioned a couple of environmental variables which are related to the operation of the JVM. In this guide we would like to expound on those configuration options and provide hints for the optimal settings.

Settings included in the etc/tigase.conf are as follows:

#GC="-XX:+UseBiasedLocking -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:NewRatio=2 -XX:+CMSIncrementalMode -XX:-ReduceInitialCardMarks -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly"
#EX="-XX:+OptimizeStringConcat -XX:+DoEscapeAnalysis -XX:+UseNUMA"

#GC_DEBUG=" -XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:logs/jvm.log -verbose:gc "

#PRODUCTION_HEAP_SETTINGS=" -Xms5G -Xmx5G " # heap memory settings must be adjusted on per deployment-base!
JAVA_OPTIONS="${GC} ${GC_DEBUG} ${EX} ${ENC} ${DRV} ${JMX_REMOTE_IP} -server ${PRODUCTION_HEAP_SETTINGS} ${DNS_RESOLVER} ${INTERNAL_IP} ${EXTERNAL_IP}  -XX:MaxDirectMemorySize=128m "

And while this file utilizes bash variables, JVM configuration options can be used in the same manner on all operating systems.

The guide will consists of two main parts - memory settings and Garbage Collector tweaks descriptions and hints.

We recommend using -server JVM parameter in all cases.

7.4.1. Heap Sizing

For the non-production deployments (development or stating environments) we recommend using default memory settings of the JVM (which depends on the underlaying operating system), which result i automatic memory allocation and, by the rule of thumb - are the safest in such environments.

For the production environments we recommend a fixed size HEAP - both initial and maximum size, which can be set with (respectively)-Xms and -Xmx JVM flags - ideally to the same value (which should be roughly 95% of the available memory, if Tigase will be the only service on the machine) to avoid allocation and deallocation.

For convenience it’s possible to uncomment line with PRODUCTION_HEAP_SETTINGS and adjust parameters accordingly.

7.4.2. GC settings

Let’s start with stating that there is no "one to rule them all" - each deployment and use-case is different, however we will try to give a couple of pointers and recommendations proceed with short introduction to GC itself.

XMPP is quite specific in terms of memory allocation - short-lived objects (various types of stanzas) usually exceed number of long-lived objects (user connections and related data). This is important bit of information in the context of how usually JVM HEAP is organized and how Garbage Collector works. On the most basic level Heap is separated into couple of regions:

Generations
  • Young Generation, which is further divided in to:

    • Eden - the region when the objects are usually allocated when they are created;

    • Survivor Spaces - (to and from - one of which is always empty) - responsible for storing all live object remaining after collecting Young Generation (process is repeated several times until objects are finally considered old enough);

  • Old Generation - (Tenured Space) - responsible for live objects remaining after running GC on Survivor Spaces - those would be long-lived objects (usually user connections and associated data);

Minor, Major and Full GC - optimizing

General thinking suggests that: * Minor GC cleans Young generation; * Major GC cleans Tenured space; * Full GC cleans all heap.

However, while we can certainly state that Minor GC cleans Young generation it’s a bit more difficult to differentiate Major and Full GC, especially considering that Major GC can be quite often triggered by Minor GC and some garbage collectors can perform cleaning concurrently. Instead of focusing of distinguishing phases one should pay closer attention to actual operations of Garbage Collector itself - uncommenting the line GC_DEBUG=" -XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:logs/jvm.log -verbose:gc " in etc/tigase.conf (or adding same properties to the java commandline) and subsequently analyzing the results should prove more helpful. In addition monitoring GC operation using for example VisualVM (with VisualGC plugin) will also be helpful.

Settings for XMPP

Ideally we should limit both number of GC pauses as well as their duration. After running rather tests following conclusions were made:

  • Garbage Collection is the faster the more dead objects occupies given space, therefore on high-traffic installation it’s better to have rather large YoungGen resulting in lower promotion of the objects to the OldGen;

  • with JVM8 default sizing of Young / Old generation changed, even tho NewRatio is still defaulting to “2” - setting it explicitly to "2" brought back previous sizing;

  • Concurrent Mark and Sweep (CMS) enabled (applies to Tenured space only) with explicit configuration of NewRatio set to default value of 2 (i.e. -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:NewRatio=2) in general behaves best;

  • For small installations (few core CPU, less memory) with low traffic default Parallel collector may be a better solution;

  • Using Heap size adjusted to the actual usage is better as the larger the heap the larger are spaces over which collection needs to be performed thus resulting in longer pauses; in case of huge heaps G1 collector may be better solution to avoid longer pauses;

Considering all of the above using following options should be a good starting point toward further optimizing of Garbage Collection:

GC="-XX:+UseBiasedLocking -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSIncrementalMode -XX:-ReduceInitialCardMarks -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly"

GC settings worth considering

In addition to the general recommendation to use CMS collector, following options (or changes to the options) may be worth considering:

  • -XX:NewRatio=2 - defines the ratio between the young and tenured generation is 1:2. In other words, the combined size of the eden and survivor spaces will be one-third of the total heap size. The parameters NewSize and MaxNewSize bound the young generation size from below and above. Setting these to the same value fixes the young generation, just as setting -Xms and -Xmx to the same value fixes the total heap size.

  • -XX:CMSInitiatingOccupancyFraction=percent - sets the percentage of the old generation occupancy (0 to 100) at which to start a CMS collection cycle.

  • -XX:+UseCMSInitiatingOccupancyOnly - instructs the JVM not to base its decision when to start a CMS cycle on run time statistics but instead it uses the value of CMSInitiatingOccupancyFraction for every CMS cycle.

  • -XX:ParallelGCThreads=x - sets the number of threads used for parallel garbage collection in the young and old generations. The default value depends on the number of CPUs available to the JVM. If the Tigase JMV is the only one running on the installation default value is recommended.

  • -XX:ConcGCThreads=x - sets the number of threads used for concurrent GC. The default value depends on the number of CPUs available to the JVM. If the Tigase JMV is the only one running on the installation default value is recommended.

  • -XX:+UseBiasedLocking and -XX:+DoEscapeAnalysis - designed to eliminate locking overhead, however their effect on performance is unpredictable therefore testing is required; reduced locking should improve concurrency and, on current multi-core hardware, improve throughput.

  • -XX:+OptimizeStringConcat - enables the optimization of String concatenation operations. This option is enabled by default.

  • -XX:+UseNUMA - enables performance optimization of an application on a machine with nonuniform memory architecture (NUMA - most modern computers are based on NUMA architecture) by increasing the application’s use of lower latency memory. By default, this option is disabled and no optimization for NUMA is made. The option is only available when the parallel garbage collector is used (-XX:+UseParallelGC).

  • -XX:-UseCompressedOops — disables the use of compressed pointers. By default, this option is enabled, and compressed pointers are used when Java heap sizes are less than 32 GB. When this option is enabled, object references are represented as 32-bit offsets instead of 64-bit pointers, which typically increases performance when running the application with Java heap sizes less than 32 GB. This option works only for 64-bit JVMs.

7.4.3. What to use with Machine x, y, z?

Server class machine (non-VM), > 16GB, >= 8 core CPU

For such setup enabling CMS garbage collector is recommended. Depending on the traffic usage and particular use-case adjusting NewRatio may be needed. Adjusting Xms and Xms sizes for actual available memory is needed (or better yet, for the actual traffic!). Following should be used:

GC="-XX:+UseBiasedLocking -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:NewRatio=2 -XX:+CMSIncrementalMode -XX:-ReduceInitialCardMarks -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly"
EX="-XX:+OptimizeStringConcat -XX:+DoEscapeAnalysis -XX:+UseNUMA"

#GC_DEBUG=" -XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:logs/jvm.log -verbose:gc "

PRODUCTION_HEAP_SETTINGS=" -Xms15G -Xmx15G " # heap memory settings must be adjusted on per deployment-base!
JAVA_OPTIONS="${GC} ${GC_DEBUG} ${EX} ${ENC} ${DRV} ${JMX_REMOTE_IP} -server ${PRODUCTION_HEAP_SETTINGS} ${DNS_RESOLVER} ${INTERNAL_IP} ${EXTERNAL_IP}  -XX:MaxDirectMemorySize=128m "

For installation with lot of available memory and intention to utilize it all, using G1GC collector may be a better idea :

GC="-XX:+UseG1GC -XX:ConcGCThreads=4 -XX:G1HeapRegionSize=2 -XX:InitiatingHeapOccupancyPercent=35 -XX:MaxGCPauseMillis=100"
EX="-XX:+OptimizeStringConcat -XX:+DoEscapeAnalysis -XX:+UseNUMA"

#GC_DEBUG=" -XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:logs/jvm.log -verbose:gc "

PRODUCTION_HEAP_SETTINGS=" -Xms60G -Xmx60G " # heap memory settings must be adjusted on per deployment-base!
JAVA_OPTIONS="${GC} ${GC_DEBUG} ${EX} ${ENC} ${DRV} ${JMX_REMOTE_IP} -server ${PRODUCTION_HEAP_SETTINGS} ${DNS_RESOLVER} ${INTERNAL_IP} ${EXTERNAL_IP}  -XX:MaxDirectMemorySize=128m "
VM machine, 8GB of RAM, 4 core CPU equivalent

For such setup enabling CMS garbage collector is also recommended. Depending on the traffic usage and particular use-case adjusting NewRatio may be needed (and configuring NewRatio is a must!). Adjusting Xms and Xms sizes for actual available memory is needed (or better yet, for the actual traffic!). Following should be used:

GC="-XX:+UseBiasedLocking -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:NewRatio=2 -XX:+CMSIncrementalMode -XX:-ReduceInitialCardMarks -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly"
EX="-XX:+OptimizeStringConcat -XX:+DoEscapeAnalysis -XX:+UseNUMA"

#GC_DEBUG=" -XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:logs/jvm.log -verbose:gc "

PRODUCTION_HEAP_SETTINGS=" -Xms7G -Xmx7G " # heap memory settings must be adjusted on per deployment-base!
JAVA_OPTIONS="${GC} ${GC_DEBUG} ${EX} ${ENC} ${DRV} ${JMX_REMOTE_IP} -server ${PRODUCTION_HEAP_SETTINGS} ${DNS_RESOLVER} ${INTERNAL_IP} ${EXTERNAL_IP}  -XX:MaxDirectMemorySize=128m "
VM machine with 4GB or less of RAM, and less than 4 core CPU equivalent

Small installations with limited resources could operate better with default (for JVM versions up to 8, which is the most current at the moment of the writing). Again - depending on the traffic usage and particular use-case adjusting NewRatio may be needed. Adjusting Xms and Xms sizes for actual available memory is recommended (or better yet, for the actual traffic!). Following should be used (i.e. GC line should be commented so the defaults will be used):

#GC="-XX:+UseBiasedLocking -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:NewRatio=2 -XX:+CMSIncrementalMode -XX:-ReduceInitialCardMarks -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly"
EX="-XX:+OptimizeStringConcat -XX:+DoEscapeAnalysis -XX:+UseNUMA"

#GC_DEBUG=" -XX:+PrintTenuringDistribution -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:logs/jvm.log -verbose:gc "

PRODUCTION_HEAP_SETTINGS=" -Xms3G -Xmx3G " # heap memory settings must be adjusted on per deployment-base!
JAVA_OPTIONS="${GC} ${GC_DEBUG} ${EX} ${ENC} ${DRV} ${JMX_REMOTE_IP} -server ${PRODUCTION_HEAP_SETTINGS} ${DNS_RESOLVER} ${INTERNAL_IP} ${EXTERNAL_IP}  -XX:MaxDirectMemorySize=128m "

7.5. Session Manager

Tigase Session Manager is where most of Tigase basic options can be configured, and where many operations are controlled from. Changes to session manager can effect operations throughout an entire XMPP installation, so care must be made when changing settings here.

7.5.1. Mobile Optimizations

By default, Tigase employs XEP-0352 Client State Indication which allows for a more streamlined mobile experiencing by allowing the XMPP server to suppress or reduce the number of updates sent to a client thereby reducing the number of stanzas sent to a mobile client that is inactive. This employment is contained within the processor ClientStateIndication and is independent from the MobileV1, MobileV2, MobileV3 settings.

However, this can be fine tuned by using mobile plugins from Tigase which can be used at the same time by adding the following line to the config.tdsl file:

}
'sess-man' {
    'urn:xmpp:csi:0' {
        logic = 'tigase.xmpp.impl.MobileV1'
    }
}

Logic Options are:

MobileV1

Keeps all presence stanzas in queue until client is active.

MobileV2

This setting delays delivery of presences while client is in inactive state, but only keeps the last presence for each full jid. This is the default setting for CSI logic.

MobileV3

Keeps the same presence logic as MobileV2, but also queues Message Carbons. Currently not supported by CSI processor, will cause issues.

Disabling CSI

If you wish to not use the ClientStateIndication processor, set the following in your config.tdsl file:

'sess-man' () {
    'urn:xmpp:csi:0' (active: false) {}
}
A note about Mobile Plugins

Previously, you could enable Mobile optimization logic using `--sm-plugins=+Mobile_V1.

If you have used these in the past, it is recommended you change your system to use the CSI processor with the appropriate mobile processing logic.

If you require v3 logic, or do not wish to use CSI, be sure to disable it using the above option.

7.5.2. threads-pool

The threadsNo property allows you to fine-tune the SM plugin’s (processors) thread pool. With the default settings every plugin gets his own thread pool. This guarantees the best performance and optimal resource usage. The downside of this setting is that packets can arrive out of order if they are processed within different thread pools.

We can even fine tune this packet processing. Let’s say you want most of the plugins to be executed within a single thread pool to preserve packet ordering for them, but for some selected plugins that should execute within separate thread pools to improve performance. Let’s say, authentication packets and user registration can be actually executed in a separate thread pools as we do not worry about an order for them. Users cannot send or receive anything else before they authenticates anyway. The solution is to specify a number of threads for the selected plugin. For example, setting a common thread pool for all plugins but registration and authentication can be done with following configuration:

'sess-man' () {
    'amp' () {
        threadsNo = 30
    }
    'presence-state' () {
        threadsNo = 27
    }
}

This replaces the old --sm-threads-pool property, as well as specifying thread pools in --sm-plugins.

7.5.3. Thread Pool factor

Session manager can control the number of available thread pools for each processor. By adding the following line to the config.tdsl file, the global thread pool can be increased by a specified factor:

'sess-man' () {
    'sm-threads-factor' = 3
}

In this case, the global thread pools is increased by a factor or 3.

7.5.4. Strategy

The Strategy property allows users to specify Clustering Strategy class which should be used for handling clustering environment; by default SMNonCachingAllNodes is used.

Any class implementing tigase.cluster.strategy.ClusteringStrategyIfc interface may be used for this setting.

Example:

'sess-man' () {
    strategy (class: tigase.cluster.strategy.SMCachingAllNodes)
}

This replaces the old --sm-cluster-strategy-class setting from v7.1.

7.6. Virtual Hosts in Tigase Server

Tigase server supports multiple virtual hosts in a single server installation. Virtual hosts can be added or removed, enabled or disabled during runtime without restarting the service or disrupting normal operation.

This document describes how virtual hosts work in Tigase server and how to get the most out of this feature in your installation.

The 'virtual-hosts' property allows for configuration of virtual hosts in your config.tdsl file.

Virtual hosts may also be managed using ad-hoc commands, visit Specification for ad-hoc Commands Used to Manage Virtual Domains for more information.

If you have components that may not be able to handle multiple vhosts or cluster mode, we have developed a virtual component solution as well, details in the Virtual Components for the Tigase Cluster section.

You may also want to reference the Vhosts API for additional information: - API Description for Virtual Domains Management in Tigase Server.

7.6.1. Specification for ad-hoc Commands Used to Manage Virtual Domains

There are 3 ad-hoc commands for virtual domains management in the Tigase server:

  1. VHOSTS_RELOAD used to reload virtual domains list from the repository (database).

  2. VHOSTS_UPDATE used to add a new virtual domain or update information for existing one.

  3. VHOSTS_REMOVE used to remove an existing virtual host from the running server.

Syntax of the commands follows the specification described in XEP-0050. Extra information required to complete the command is carried as data forms described in XEP-0004.

All commands are accepted by the server only when send by the installation administrator. If the command is sent from any other account &lt;not-authorized /&gt; error is returned. To grant administrator rights to an account you have to set admins property in the config.tdsl configuration file.

Commands are sent to the 'vhost-man' server component and the 'to' attribute of the stanza must contain a full JID of the VHostManager on the server. The full JID consists of the component name: 'vhost-man' and the local domain, that is domain which is already on the list of virtual domains and is active. Assuming 'existing.domain.com' one of domains already activated for the server installation the JID is: 'vhost-man@existing.domain.com'.

Reloading the Domains List from the Database

In order to reload virtual domains from the permanent repository other than configuration file, you have to send VHOSTS_RELOAD ad-hoc command to the VHostManager on the server.

The reload command request is of the form:

<iq type="set"
    to="vhost-man@existing.domain.com"
    id="aac8a">
  <command xmlns="http://jabber.org/protocol/commands"
           node="VHOSTS_RELOAD" />
</iq>

The server sends a response upon successful completion of the command with current number of virtual domains server by the installation:

<iq from="vhost-man@existing.domain.com"
    type="result"
    to="cmd-sender-admin@existing.domain.com"
    id="aac8a">
  <command xmlns="http://jabber.org/protocol/commands"
           status="completed"
           node="VHOSTS_RELOAD">
    <x xmlns="jabber:x:data" type="result">
      <field type="fixed" var="Note">
        <value>Current number of VHosts: 123</value>
      </field>
    </x>
  </command>
</iq>

If the command is sent from an account other than admin, the server returns an error:

<iq from="vhost-man@existing.domain.com"
    type="error"
    to="cmd-sender-admin@existing.domain.com"
    id="aac8a">
  <command xmlns="http://jabber.org/protocol/commands"
           node="VHOSTS_RELOAD" />
  <error type="auth" code="401">
    <not-authorized xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
    <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"
          xml:lang="en">
      You are not authorized for this action.
    </text>
  </error>
</iq>

The response doesn’t have any special meaning other then end-user information. The client may ignore the response as it is sent after the command has been executed.

Adding a New Domain or Updating Existing One

In order to add a new domain or update existing one you have to send an ad-hoc command VHOSTS_UPDATE with at least one domain name in the command data form. You can also specify whether the domain is enabled or disabled but this is optional. Future releases may allow for setting additional parameters for the domain: maximum number of user accounts for this domain, anonymous login enabled/disabled for the domain, registration via XMPP enabled/disabled for this domain and some more parameters not specified yet.

The domain add/update command request is of the form:

<iq type="set"
    to="vhost-man@existing.domain.com"
    id="aacba">
  <command xmlns="http://jabber.org/protocol/commands"
           node="VHOSTS_UPDATE">
    <x xmlns="jabber:x:data" type="submit">
      <field type="text-single"
             var="VHost">
        <value>new-virt.domain.com</value>
      </field>
      <field type="list-single"
             var="Enabled">
        <value>true</value>
      </field>
    </x>
  </command>
</iq>

Please note: Character case in the command field variable names does matter.

Upon successful completion of the command the server sends a response back to the client with information of the existing number of virtual hosts on the server:

<iq from="vhost-man@existing.domain.com"
    type="result"
    to="cmd-sender-admin@existing.domain.com"
    id="aacba">
  <command xmlns="http://jabber.org/protocol/commands"
           status="completed"
           node="VHOSTS_UPDATE">
    <x xmlns="jabber:x:data" type="result">
      <field type="fixed" var="Note">
        <value>Current number of VHosts: 124</value>
      </field>
    </x>
  </command>
</iq>
Removing a Virtual Domain From the Server

In order to remove a virtual domain you have to send VHOSTS_REMOVE command to the server with the domain name.

The domain remove command is sent by the client:

<iq type="set"
    to="vhost-man@existing.domain.com"
    id="aacba">
  <command xmlns="http://jabber.org/protocol/commands"
           node="VHOSTS_REMOVE">
    <x xmlns="jabber:x:data" type="submit">
      <field type="text-single"
             var="VHost">
        <value>virt-nn.domain.com</value>
      </field>
    </x>
  </command>
</iq>

Upon successful completion of the command the server sends a response back to the client with information of the existing number of virtual hosts on the server:

<iq from="vhost-man@existing.domain.com"
    type="result"
    to="cmd-sender-admin@existing.domain.com"
    id="aacba">
  <command xmlns="http://jabber.org/protocol/commands"
           status="completed"
           node="VHOSTS_REMOVE">
    <x xmlns="jabber:x:data" type="result">
      <field type="fixed" var="Note">
        <value>Current number of VHosts: 124</value>
      </field>
    </x>
  </command>
</iq>

7.6.2. Virtual Components for the Cluster Mode

Let’s assume you have a cluster installation and you want to include a component in your installation which doesn’t support the cluster mode yet. If you put it on all nodes as a separate instances they will work out of sync and overall functionality might be useless. If you put on one node only it will work correctly but it will be visible to users connected to this one node only.

Ideally you would like to have a mechanism to install it on one node and put some redirections on other nodes to forward all packets for this component to a node where this component is working. Redirection on it’s own is not enough because the component must be visible in service discovery list and must be visible somehow to users connected to all nodes.

This is where the virtual components are handy. They are visible to users as a local normal component, they seem to be a real local component but in fact they just forward all requests/packets to a cluster node where the real component is working.

Virtual component is a very lightweight ServerComponent implementation in Tigase server. It can pretend to be any kind of component and can redirect all packets to a given address. They can mimic native Tigase components as well as third-party components connected over external component protocol (XEP-0114).

Configuration is very simple and straightforward, in fact it is very similar to configuration of any Tigase component. You set a real component name as a name of the component and a virtual component class name to load. Let’s say we want to deploy MUC component this way. The MUC component is visible as muc.domain.oug in the installation. Thus the name of the component is: muc

muc (class: tigase.cluster.VirtualComponent) {}

This is pretty much all you need to load a virtual component. A few other options are needed to point to correct destination addresses for packets forwarding and to set correct service discovery parameters:

}
muc (class: tigase.cluster.VirtualComponent) {
    'disco-category' = 'conference'
    'disco-features' = 'http://jabber.org/protocol/muc'
    'disco-name' = 'Multi User Chat'
    'disco-node' = ''
    'disco-type' = 'text'
    'redirect-to' = 'muc@cluster-node-with-real-muc.domain.our'
}

That’s it.

7.7. Settings for Custom Logging in Tigase

Logging can be an important tool to monitor your server’s health and performance. Logging may be controlled and customized on a per-component basis.

A logging bean has been implemented to allow more fine configuration of each component.

logging () {
    rootLevel = CONFIG
    loggers = {
        'tigase.server' = {
            level = ALL
        }
        'tigase.conf' = {
            level = FINEST
        }
    }
    handlers = {
        ' java.util.logging.FileHandler' = {
            level = ALL
            append = true
            count = 5
            formatter = 'tigase.util.LogFormatter'
            limit = 10000000
            pattern = 'logs/tigase.log'
        }
        'java.util.logging.ConsoleHandler' = {
            level = WARNING
            formatter = 'tigase.util.LogFormatter'
        }
    }
}

You only need to specify the settings you wish to customize, otherwise they will be left as default.

  • rootLevel - Defines the root level of logging for all components not otherwise defined. Default is CONFIG

  • loggers - Defines the level of logging for packages running in tigase server. This is similar to the --debug setting, however you must use tigase.{package} format. Default is NONE.

  • handlers - Defines the level of logging for File output and Console output.

    1. FileHandler - is the file output for log files, with the following options:

      1. level - specifies the level of logs to be written, default is ALL.

      2. append - whether to append to the log or replace it during restart. Default is true.

      3. count - number of individual log files to keep at set limit. Default is 5. (default settings will continue appending logs until 5 files at 10MB are reached, then the oldest file will be overwritten.)

      4. formatter - specifies the package to format logging output. Default is tigase.util.LogFormatter.

      5. limit - Byte limit for each log file. Default is 10000000 or 10MB.

      6. pattern - Directory and filename of the log file with respect to the Tigase installation directory. Default is logs/tigase.log.

    2. ConsoleHandler - Determines the formatting for Tigase output to console.

      1. level - specifies the level of logs to be written, default is WARNING.

      2. formatter - specifies the package to format logging output. Default is tigase.util.LogFormatter.

7.8. Tigase Advanced Options

This section is designed to include a number of advanced configuration options available within Tigase, but may not have a relevant section yet to house them.

7.8.1. Using CAPTCHA for in-band registration

To reduce false or spam registrations to Tigase XMPP Server, there is now the ability to add CAPTCHA forms as a part of the in-band registration. The CAPTCHA will generate a random math equation and ask the user registering a new account to answer it. This may be enabled as a sub-option of enabling registration in config.tdsl:

'sess-man' {
    'jabber:iq:register' {
        captchaRequired = 'true'
    }
}
Note
Because some clients do not refresh a registration form after an unsuccessful attempt, this option allows 3 retries with the same CAPTCHA.

3 unsuccessful attempts will result in the captcha being invalidated and a client will receive an error message.

7.8.2. Enabling Empty Nicknames

Tigase can now support users with empty nicknames. This can be enabled by adding the following code in config.tdsl.

'sess-man' {
    'jabber:iq:roster' {
        empty_name_enabled = 'true'
    }
}

7.8.3. Enable Silent Ignore on Packets Delivered to Unavailable Resources

You can now have Tigase ignore packets delivered to unavailable resources to avoid having a packet bounce around and create unnecessary traffic. You may set this globally, within standard message handling only, or within the AMP component using the following settings:

Globally:

'sess-man' {
    'silently-ignore-message' = 'true'
}

Message Processing Only:

'sess-man' {
    message {
        'silently-ignore-message' = 'true'
    }
}

AMP Component:

'sess-man' {
    amp () {
        'silently-ignore-message' = 'true'
}

7.8.4. Mechanism to count errors within Tigase

A new processor within statistics has been added to count the number of errors that Tigase returns. This processor, named error-counter, will count all errors returned by Tigase, however by default the number is always zero if it is not enabled. It can be found as an MBean object in JMX under ErrorStatistics and contains values for packets with ERROR and grouped by type. To enable counting of these errors, you must ensure the processor is included in your sess-man configuration:

'sess-man' {
    'error-counter' () {}
}
Including stream errors

Stream ERROR packets are not included in the above counter by default as they are processed separately. To enable this to be added to the counter, the following line must be in your config.tdsl file.

c2s {
    'stream-error-counter' () {
        active = true
    }
}
Stream resumption default & max-timeout

SteamManagementIOProcessor now has a setting that can be used to change the maximum timeout time it will wait for reconnection if a client does not send a time to wait. Two settings are now available:

c2s {
    'urn:xmpp:sm:3' {
        'resumption-timeout' = 90
    }
}

The above setting in config.tdsl file will change the default timeout period to 90 seconds.

c2s {
    'urn:xmpp:sm:3' {
        'max-resumption-timeout' = 900
    }
}

This setting will set the maximum time allowed for stream resumption to 900 seconds. This can be handy if you expect a number of mobile phones to connect to your server and want to avoid duplicate messages being sent back and forth.

You may setup a server to automatically approve presence subscriptions or roster authorizations for all users. Say you were hosting bots and wanted to automate the process. This can be done with the following settings:

'sess-man' {
    'jabber:iq:roster' {
        'auto-authorize' = 'true'
    }
    presence {
        'auto-authorize' = 'true'
    }
}

Both of these settings are false by default, and you may use them together or separately. The following behavior is followed when they are both activated:

  • Upon sending a subscription request - Both contacts will each others' subscription and be added to each others' roster. Presence information will immediately be exchanged between both parties.

  • Upon sending presence with type either unsubscribe or unsubscribed follows the rules defined in RFC regarding processing of these stanzas (i.e. adjusting subscription type of user/contact), but without forwarding those stanzas to the receiving entity to avoid any notifications to the client. However, a roster push is generated to reflect changes to presence in user roster in a seamless manner.

  • Simply adding an item to the roster (i.e. with <iq/> stanza with correct semantics) will also cause an automatic subscription between the user and the contact in a matter explained above.

7.9. Tigase Server Extras - mDNS support

7.9.1. Overview

Tigase mDNS component provides you with ability to publish domain name of your XMPP server (ending with .local) in the local network using multicast DNS (also known as DNS-SD, Zeroconf or Bonjour).

7.9.2. Enabling mDNS

To enable this component you need to add mDNS component to your configuration file:

mdns () {
}

This lines will enable mDNS support and will start broadcasting hostname of your host in the local network as hostname.local and will broadcast DNS records for XMPP server hosted at this domain.

7.9.3. Using different domain name

If you are hosting different domain than hostname of your server with .local suffix, then you can set it in mDNS component settings by setting serverHost property to the name of your domain without suffix .local.

Example of broadcasting mDNS for domain example.local
mdns () {
    serverHost = 'example'
}

7.9.4. Forcing single server for domain

It is possible to enforce Tigase mDNS component to check if there is no other host providing services for chosen domain name. By setting property singleServer to true. If this feature is enabled, then mDNS component checks if chosen domain is already in use (broadcasted in multicast DNS) and if so it stops startup of the server. This feature make it possible to start up Tigase and broadcast XMPP server mDNS information if already existing mDNS information resolves to the IP address of the host on which you are starting Tigase XMPP Server.

Example enabling single server mode
mdns () {
    singleServer = true
}

8. Security

The articles here cover advanced security features built into to Tigase Server, and some options for adding your own levels of security.

8.1. XEP-0191 Support

The simplest security feature, however, inside an XMPP server is the ability to block users and JIDS. XEP-0191 specifies the parameters of simple blocking without using privacy lists. Below is a breakdown and some sample commands you may find helpful. To enable this feature, be sure the following is in your init.properties file:

}
'sess-man' {
    'urn:xmpp:blocking' () {}
}

If you have other plugins running, then just add 'urn:xmpp:blocking' () {} to the list to activate this feature.

To confirm if your installation of Tigase supports this feature, a quick disco#info of your server should reveal the following feature:

<feature var='urn:xmpp:blocking'/>

Blocked users are stored on the server on a per-JID basis, so one user may only see his or her blocked JIDs. Lists of blocked JIDs will return as an IQ stanza with a list of <item> fields. To retrieve the blocklist, the following command is issued:

<iq type='get' id='blockedjids'>
  <blocklist xmlns='urn:xmpp:blocking'/>
</iq>

The server responds:

<iq type='result' id='blockedjids'>
  <blocklist xmlns='urn:xmpp:blocking'>
    <item jid='user1@domain.net'/>
    <item jid='admin@example.com'/>
  </blocklist>
</iq>

To block a JID, a similar stanza to the one above is sent to the server with the items of the blocked JIDs you wish to add:

<iq from='admin@domain.net' type='set' id='block'>
  <block xmlns='urn:xmpp:blocking'>
    <item jid='user2@domain.net'/>
  </block>
</iq>

The server will then push an unavailable presence to blocked contacts. Communication between a contact that is blocked, and an entity that blocked it will result in a <not-acceptable> error:

<message type='error' from='user2@domain.net' to='admin@domain.net'>
  <body>Hello, are you online?</body>
  <error type='cancel'>
    <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
    <blocked xmlns='urn:xmpp:blocking:errors'/>
  </error>
</message>

Unblocking a contact is just as easy as blocking, send an unblock stanza to the server:

<iq from='admin@domain.net' type='set' id='unblock'>
  <unblock xmlns='urn:xmpp:blocking'>
    <item jid='user2@domain.net'/>
  </unblock>
</iq>

The server will begin pushing presence information to unblocked contacts and resources so long as permissions have not changed between.

You may also opt to unblock all contacts and essentially clear out your blocked list using the following command:

<iq type='set' id='unblockall'>
  <unblock xmlns='urn:xmpp:blocking'/>
</iq>

8.2. Account Registration Limits

In order to protect Tigase servers from DOS attacks, a limit on number of account registrations per second has been implemented. This may be configured by adding the following line in the config.tdsl file:

'registration-throttling' () {
    limit = 10

This setting allows for 10 registrations from a single IP per second. If the limit is exceeded, a NOT_ALLOWED error will be returned.

It is possible to create two separate counters as well:

'registration-throttling' () {
    limit = 10
}
c2s {
    'registration-throttling' (class: tigase.server.xmppclient.RegistrationThrottling) {
        limit = 3
    }
}

Here we have one for c2s with a limit of 3, and a global for all other connection managers set at 10.

You can also set individual components limits as well:

ws2s {
    'registration-throttling' (class: tigase.server.xmppclient.RegistrationThrottling) {
        limit = 7
    }
}

8.3. Server Certificates

8.3.1. Creating and Loading the Server Certificate in pem Files

Server Certificates

Server certificates are needed when you use secure socket connections - SSL/TLS.

For secure socket connection a proper certificate is needed. You can either generate your own self-signed certificate or obtain certificate from trusted third party organization.

Here are steps how to obtain certificate from a trusted organization.

Generating your Own Certificates

Self-signed certificates can be generated easily on a Linux system. Although it may not be considered a 'trusted' certificate authority, it can be useful to test server installations. We do not recommend regular use of self-signed certificates.

Note that Tigase v5.0 and later can automatically create self signed PEM files if needed. However we will cover doing this process by hand.

This tutorial assumes you are running a Linux-based operating system with access to command shell, and the 'Openssl' package is installed on the system.

The process takes the following steps:
1. Create a local private key. This file ends with .key extension. It is recommended to create a new private key for the process.
2. Generate a certificate request. This file ends with the .csr extension and is the file sent to the Certificate Authority to be signed.
3. CA signs private key. This can be done by your own computer, but can also be done by private CAs for a fee.
4. Results are obtained from the CA. This is a .crt file which contains a separate public certificate.
5. Combine the .csr and .crt file into a unified .pem file. Tigase requires keys to be non-password protected PEM files.

Generate local private key
openssl genrsa -out[domain.com.key] 1024

This command generates a private key using a 1024 bit RSA algorithm. -out designates the name of the file, in this case it will be domain.com.key. The exact name is not important, and the file will be created in whatever directory you are currently in.

Generate a certificate request:
openssl req -nodes -key domain.com.key -out domain.com.csr

This command generates a certificate request using the file specified after -key, and the result file will be domain.com.csr. You will be asked a series of questions to generate the request.

Country Name (2 letter code) [AU]:AU
State or Province Name (full name) [Some-State]:Somestate
Locality Name (eg, city) []:Your city name
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Company name
Organizational Unit Name (eg, section) []:Department or any unit
Common Name (eg, YOUR name) []:*.yourdomain.com
Email Address []:your_email_address@somedomain.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Sign the Certificate Request:

Now the .csr file will be signed by a Certificate Authority. In this tutorial, we will be self-signging our certificate. This practice however is generally not recommended, and you will receive notifications that your certificate is not trusted. There are commercial offers from companies to sign your certificate from trusted sources. Please see the Certificate From Other Providers section for more information.

openssl x509 -req -days 365 -in domain.com.csr -signkey domain.com.key -out domain.com.crt

This command signs the certificate for 365 days and generates the domain.com.crt file. You can, of course use any number of days you like.

Generate PEM file

You should now have the following files in the working directory: ..\ domain.com.key domain.com.csr domain.com.crt

cat yourdomain.com.crt yourdomain.com.key > yourdomain.com.pem

If the certificate is issued by third-party authority you will have to attach the certificate chain, that being certificate of the authority who has generated your certificate. You normally need to obtain certificates for your chain from the authority who has generated your certificate. For example, if you have a certificate from XMPP federation you need to download StartCom root certificate and intermediate ICA certificate. In such cases the pem file is created using following command:

cat yourdomain.com.crt yourdomain.com.key sub.class1.xmpp.ca.crt ca.crt > yourdomain.com.pem

The result file should looks similar to:

-----BEGIN CERTIFICATE-----
MIIG/TCCBeWgAwIBAgIDAOwZMA0GCSqGSIb3DQEBBQUAMIGMMQswCQYDVQQGEwJJ
.
.
.
pSLqw/PmSLSmUNIr8yQnhy4=
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
WW91J3JlIGtpZGRpbmchISEKSSBkb24ndCBzaG93IHlvdSBvdXIgcHJpdmF0ZSBr
.
.
.
ZXkhISEhCkNyZWF0ZSB5b3VyIG93biA7KSA7KSA7KQo=
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
.
.
.
xV/stleh
-----END CERTIFICATE-----

For Tigase server as well as many other servers (Apache 2.x), the order is following; your domain certificate, your private key, authority issuing your certificate, root certificate.

Note! Tigase requires full certificate chain in PEM file (described above)! Different applications may require pem file with certificates and private key in different order. So the same file may not be necessarily used by other services like Web server or e-mail server. Currently, Tigase can automatically sort certificates in PEM file while loading it.

Installing/Loading Certificate To the Tigase Server

Installing and loading certificates is very easy. The server can load all certificates directly from pem files. You just need to create a separate pem file for each of your virtual domains and put the file in a directory accessible by the server. Tigase server can automatically load all pem files found in given directory. By default, and to make things easy, we recommend the Tigase/certs directory.

Certificate From Other Providers

There is number of certificate providers offering certificates either for free or for money. You can use any of them, however you have to be aware that sometimes certificates might not be recognized by all XMPP servers, especially if it’s one from a new provider. Here is an example list of providers:

  • CAcert - free certificates with an excellent Web GUI for managing generated certificates and identities.

  • Verisign - very expensive certificates comparing to above provides but the provider is recognized by everybody. If you have a certificate from Verisign you can be sure it is identified as a valid certificate.

  • Comodo Certificate Authority offers different kind of commercial certificates

To obtain certificate from a third party authority you have to go to its website and request the certificate using certificate request generated above. I cannot provide any instructions for this as each of the providers listed have different requirements and interfaces.

We highly recommend using LetsEncrypt keys to self-sign and secure your domain. Instructions are in the next section.

Using one certificate for multiple domains

By default, each virtual hosts will require it’s own certificate. However, if you choose to use one certificate for all virtual hosts, Tigase supports that option. For example, if you have host1.example.net, host2.example.net, and host3.example.net each vhost will need some configuration:

'certificate-container' {
    'custom-certificates' {
        'host1.example.net' = '/home/tigase/certs/host1.pem'
        'host2.example.net' = '/home/tigase/certs/host2.pem'
        'host3.example.net' = '/home/tigase/certs/host3.pem'
    }
}

This may be time consuming if you have many Vhosts, or expect to generate many more. The good news is, now one certificate can be used for ALL Vhosts using the following configuration line:

'certificate-container' {
    'custom-certificates' {
        '*.example.net' = '/home/tigase/certs/certificate.pem'
    }
}

Now any Vhosts created will use the same certificate located at /home/tigase/certs/certificate.pem.

Note
This is an all or nothing option, if you wish to customize each Vhost, you will need to do so individually.

8.3.2. Installing LetsEncrypt Certificates in Your Linux System

LetsEncrypt is a trusted CA that provides free security certificates. Unlike previously self-signed certificates, we can use LetsEncrypt Certificates to certify your domains from a trusted source. To do this, remote into the server hosting Tigase, or login to the computer locally and begin to install git if that is not already on the system.

sudo apt-get install git

Once the machine installs git, use the following command to download the LetsEncrypt Tools.

sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt

This will download the tools into the computers' /opt/letsencrypt directory. You will now need to generate the certificates using this tool using the next command.

sudo -H ./letsencrypt-auto certonly --standalone -d domain.com

where domain.com is your currently hosted domain. Be sure that port 443 is forwarded to this computer, and that proper A and DNS records are registered for your domain.

Note
Letsencrypt does not allow for wildcards in the domain name, you will need to generate certificates for each subdomain you wish certified by the CA.

Those certificates will be created and will be stored in /etc/letsencrypt/live/$domain and you will need admin privladges to see them.

sudo -i
**********
cd /etc/letsencrypt/live/$domain

ls

cert.pem chain.pem fullchain.pem privkey.pem

In that directory, you will find four certificates: - cert.pem - chain.pem - fullchain.pem - privkey.pem

For Tigase, we are only concerned with privkey.pem contents. Copy that certificate to another directory.

cp privkey.pem /home/user

At this point we will need to obtain the root and intermediate certificates, this can be done by downloading these certificates from the LetsEncrypt website.

Alternatively, you may obtain them using wget:

wget https://letsencrypt.org/certs/isrgrootx1.pem
wget https://letsencrypt.org/certs/letsencryptauthorityx3.pem

These are the root certificate, and the intermediate certificate signed by root certificate. NOTE: IdenTrust cross-signed certificate will not function properly.

Take the contents of your privkey.pem, and combine them with the contents of isrgrootx1.pem and letsencryptauthorityx3.pem into a single pem certificate. You may wish to name the file after your domain such as mydomain.com.pem. Your certificate should look something like this:

-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDAUAqqKu7Z4odo
...
og89F9AbWr1mNmyRoScyqMXo
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
...
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
FhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCBqwYIKwYBBQUHAgIwgZ4MgZtU
...
bmcgUGFydGllcyBhbmQgb25seSBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIENlcnRp
-----END CERTIFICATE-----

Place that certificate into your /certs folder of Tigase, and installation of this certificate is done.

You will need to do this for all subdomains you wish to have a certificate for, however, you may be able to import the root and intermediate certificates to your keystore to avoid having to paste the chain certificates for each subdomain.

Warning
LetsEncrypt certificates expire 90 days from issue and need to be renewed in order for them to remain valid!
Including letsencrypt cert.pem

For some installations, you may need to also include the cert.pem contents into your certificate chain to avoid handshake errors. You will then have 4 certificates in your domain.com.pem file. Be sure the order is as follows: cert.pem, privkey.pem, isgrootx1.pem, then letsencryptauthorityx3.pem

If you moved all certs to a single directry, you may combine them using the following command in a *nix operating system.

cat ./cert.pem ./privkey.pem ./letsencryptauthorityx3.pem ./isrgrootx1.pem > mydomain.com.pem

8.4. Custom Authentication Connectors

This article presents configuration options available to the administrator and describe how to set Tigase server up to use user accounts data from a different database.

The first thing to know is that Tigase server always opens 2 separate connections to the database. One connection is used for user login data and the other is for all other user data like the user roster, vCard, private data storage, privacy lists and so on…​

In this article we still assume that Tigase server keeps user data in it’s own database and only login data is retrieved from the external database.

At the moment Tigase offers following authentication connectors:

  • 'mysql', 'pgsql', 'derby' - standard authentication connector used to load user login data from the main user database used by the Tigase server. In fact the same physical implementation is used for all JDBC databases.

  • 'drupal' - is the authentication connector used to integrate the Tigase server with Drupal CMS.

  • 'libresource' - is the authentication connector used to integrate the Tigase server with Libresource Collaboration platform.

  • 'tigase-auth' - is the authentication connector which can be used with any database. It executes stored procedures to perform all actions. Therefore it is a very convenient way to integrate the server with an external database if you don’t want to expose the database structure. You just have to provide a set of stored procedures in the database. While implementing all stored procedures expected by the server might be a bit of work it allows you to hide the database structure and change the SP implementation at any time. You can add more actions on user login/logout without restarting or touching the server. And the configuration on the server side is very simple. For detailed description of this implementation please refer to Tigase Auth documentation.

  • 'tigase-custom' - is the authentication connector which can be used with any database. Unlike the 'tigase-auth' connector it allows you to define SQL queries in the configuration file. The advantage of this implementation is that you don’t have to touch your database. You can use either simple plain SQL queries or stored procedures. The configuration is more difficult as you have to enter carefully all SQL queries in the config file and changing the query usually involves restarting the server. For more details about this implementation and all configuration parameters please refer to Tigase Custom Auth documentation.

As always the simplest way to configure the server is through the init.properties file. In the article describing this file you can find long list with all available options and all details how to handle it. For the authentication connector setup however we only need 2 options:

dataSource {
    'default-auth' () {
        uri = 'database connection url'
    }
}
authRepository {
    default () {
        cls = 'connector'
        'data-source' = 'default-auth'
    }
}

For example if you store authentication data in a drupal database on localhost your settings would be:

dataSource {
    'default-auth' () {
        uri = 'jdbc:mysql://localhost/drupal?user=user&password=passwd'
    }
}
authRepository {
    default () {
        'data-source' = 'default-auth'
    }
}

You have to use a class name if you want to attach your own authentication connector.

Default is:

authRepository {
    default {
        cls = 'tigase.db.jdbc.TigaseAuth'
    }
}

In the same exact way you can setup connector for any different database type.

For example, drupal configuration is below

authRepository {
    default {
        cls = 'tigase.db.jdbc.DrupalWPAuth'
    }
}

Or tigase-custom authentication connector.

authRepository {
    default {
        cls = 'tigase-customs'
    }
}

The different cls or classes are:

  • drupal - tigase.db.jdbc.DrupalWPAuth

  • mySQL,derby,postGreSQL - tigase.db.jdbc.JDBCRepository

You can normally skip configuring connectors for the default Tigase database format: mysql, pgsql and derby as they are applied automatically if the parameter is missing.

One more important thing to know is that you will have to modify authRepository if you use a custom authentication connector. This is because if you retrieve user login data from the external database this external database is usually managed by an external system. User accounts are added without notifying Tigase server. Then, when the user logs in and tries to retrieve the user roster, the server can not find such a user in the roster database.

To keep user accounts in sync between the authentication database and the main user database you have to add following option to the end of the database connection URL: autoCreateUser=true.

For example:

dataSource {
    default () {
        uri = 'jdbc:mysql://localhost/tigasedb?user=nobody&password=pass&autoCreateUser=true'
    }
}

If you are interested in even further customizing your authentication connector by writing your own queries or stored procedures, please have a look at the following guides:

8.4.1. Tigase Auth Connector

The Tigase Auth connector with shortcut name: tigase-auth is implemented in the class: tigase.db.jdbc.TigaseAuth. It allows you to connect to any external database to perform user authentication. You can find more details how to setup a custom connector in the Custom Authentication Connectors guide.

To make this connector working you have to prepare your database to offer set of stored procedures for Tigase server to perform all the authentication actions. The best description is the example schema with all the stored procedures defined. Please refer to the Tigase SVN repository for the schema definition files.

Files with the stored procedures implementations are located in postgresql-schema-4.sql file for PostgreSQL database.

The absolute minimum of stored procedures you have to implement is:

  • TigUserLoginPlainPw - to perform user authentication. The procedure is always called when the user tries to login to the XMPP server. This is the only procedure which must be implemented and actually must work.

  • TigUserLogout - to perform user logout. The procedure is always called when the user logouts or disconnects from the server. This procedure must be implemented but it can be empty and can do nothing. It just needs to exist because Tigase expect it to exist and attempts to call it.

With these 2 above stored procedures you can only perform user login/logouts on the external database. You can’t register a user account, change user password or remove the user. In many cases this is fine as all the user management is handled by the external system.

If you however want to allow for account management via XMPP you have to implement also following procedures:

  • TigAddUserPlainPw - to add a new user account

  • TigRemoveUser - to remove existing user account

  • TigUpdatePasswordPlainPw - to change a user password for existing account

8.4.2. Tigase Custom Auth Connector

The Tigase Custom Auth connector with shortcut name: tigase-custom is implemented in the class: tigase.db.jdbc.TigaseCustomAuth. It allows you to connect to any external database to perform user authentication and use a custom queries for all actions.

You can find more details how to setup a custom connector in the Custom Authentication Connectors guide.

The basic configuration is very simple:

authRepository {
    default () {
        cls = 'tigase.db.jdbc.TigaseCustomAuth'
        'data-source' = 'default-auth'
    }
}

That’s it.

The connector loads correctly and starts working using predefined, default list of queries. In most cases you also might want to define your own queries in the configuration file. The shortest possible description is the following example of the content from the config.tdsl file:

This query is used to check connection to the database, whether it is still alive or not

authRepository {
    default () {
        'conn-valid-query' = 'select 1'
    }
}

This is database initialization query, normally we do not use it, especially in clustered environment

authRepository {
    default () {
        'init-db-query' = 'update tig_users set online_status = 0'
    }
}

Below query performs user authentication on the database level. The Tigase server does not need to know authentication algorithm or password encoding type, it simply passes user id (BareJID) and password in form which was received from the client, to the stored procedure. If the authentication was successful the procedure returns user bare JID or null otherwise. Tigase checks whether the JID returned from the query matches JID passed as a parameter. If they match, the authentication is successful.

authRepository {
    default () {
        'user-login-query' = '{ call TigUserLoginPlainPw(?, ?) }'
    }
}

Below query returns number of user accounts in the database, this is mainly used for the server metrics and monitoring components.

authRepository {
    default () {
      'users-count-query' = '{ call TigAllUsersCount() }'
    }
}

The Below query is used to add a new user account to the database.

authRepository {
    default () {
        'add-user-query' = '{call TigAddUserPlainPw(?, ?) }'
    }
}

Below query is used to remove existing account with all user’s data from the database.

authRepository {
    default () {
        'del-user-query' = '{ call TigRemoveUser(?) }'
    }
}

This query is used for the user authentication if user-login-query is not defined, that is if there is no database level user authentication algorithm available. In such a case the Tigase server loads user’s password from the database and compares it with data received from the client.

authRepository {
    default () {
        'get-password-query' = 'select user_pw from tig_users where user_id = ?'
    }
}

Below query is used for user password update in case user decides to change his password.

authRepository {
    default () {
        'update-password-query' = 'update tig_users set user_pw = ? where user_id = ?'
    }
}

This query is called on user logout event. Usually we use a stored procedure which records user logout time and marks user as offline in the database.

authRepository {
    default () {
        'update-logout-query' = 'update tig_users, set online_status = online_status - 1 where user_id = ?'
    }
}

This configuration specifies what non-sasl authentication mechanisms to expose to the client

authRepository {
    default () {
        'non-sasl-mechs' = [ 'password', 'digest' ]
    }
}

This setting to specify what sasl authentication mechanisms expose to the client

authRepository {
    default () {
        'sasl-mechs' = 'PLAIN,DIGEST-MD5'
    }
}

Queries are defined in the configuration file and they can be either plain SQL queries or stored procedures. If the query starts with characters: { call then the server assumes this is a stored procedure call, otherwise it is executed as a plain SQL query. Each configuration value is stripped from white characters on both ends before processing.

Please don’t use semicolon ; at the end of the query as many JDBC drivers get confused and the query may not work.

Some queries can take arguments. Arguments are marked by question marks ? in the query. Refer to the configuration parameters description for more details about what parameters are expected in each query.

This example shows how to use a stored procedure to add a user as a query with 2 required parameters (username, and password).

authRepository {
    default () {
        'add-user-query' = '{call TigAddUserPlainPw(?, ?) }'
    }
}

The same query with plain SQL parameters instead:

'add-user-query' = 'insert into users (user_id, password) values (?, ?)'

The order of the query arguments is important and must be exactly as described in specification for each parameter.

Query Name Description Arguments Example Query

conn-valid-query

Query executed periodically to ensure active connection with the database.

Takes no arguments.

select 1

init-db-query

Database initialization query which is run after the server is started.

Takes no arguments.

update tig_users set online_status = 0

add-user-query

Query adding a new user to the database.

Takes 2 arguments: (user_id (JID), password)

insert into tig_users (user_id, user_pw) values (?, ?)

del-user-query

Removes a user from the database.

Takes 1 argument: (user_id (JID))

delete from tig_users where user_id = ?

get-password-query

Retrieves user password from the database for given user_id (JID).

Takes 1 argument: (user_id (JID))

select user_pw from tig_users where user_id = ?

update-password-query

Updates (changes) password for a given user_id (JID).

Takes 2 arguments: (password, user_id (JID))

update tig_users set user_pw = ? where user_id = ?

user-login-query

Performs user login. Normally used when there is a special SP used for this purpose. This is an alternative way to a method requiring retrieving user password. Therefore at least one of those queries must be defined: user-login-query or get-password-query. If both queries are defined then user-login-query is used. Normally this method should be only used with plain text password authentication or sasl-plain. Tigase expects a result set with user_id to be returned from the query if login is successful and empty results set if the login is unsuccessful.

Takes 2 arguments: (user_id (JID), password)

select user_id from tig_users where (user_id = ?) AND (user_pw = ?)

user-logout-query

This query is called when user logs out or disconnects. It can record that event in the database.

Takes 1 argument: (user_id (JID))

update tig_users, set online_status = online_status - 1 where user_id = ?

non-sasl-mechs

Comma separated list of NON-SASL authentication mechanisms. Possible mechanisms are: password and digest. The digest mechanism can work only with get-password-query active and only when password are stored in plain text format in the database.

sasl-mechs

Comma separated list of SASL authentication mechanisms. Possible mechanisms are all mechanisms supported by Java implementation. The most common are: PLAIN, DIGEST-MD5, CRAM-MD5. "Non-PLAIN" mechanisms will work only with the get-password-query active and only when passwords are stored in plain text format in the database.

8.4.3. Drupal Authentication

Currently, we can only check authentication against a Drupal database at the moment. Full Drupal authentication is not implemented as of yet.

As Drupal keeps encrypted passwords in database the only possible authorization protocols are those based on PLAIN passwords.

To protect your passwords Tigase server must be used with SSL or TLS encryption.

Implementation of a Drupal database based authorization is located in tigase.db.jdbc.DrupalAuth class. Although this class is capable of adding new users to the repository I recommend to switch in-band registration off due to the caching problems in Drupal. Changes in database are not synchronized with Drupal yet. Functionality for adding new users is implemented only to ease user accounts migration from different repository types from earlier Tigase server installations.

The purpose of that implementation was to allow all accounts administration tasks from Drupal like: account creation, all accounts settings, like e-mail, full name, password changes and so on.

Tigase server uses following fields from Drupal database: name (user account name), pass (user account password), status (status of the account). Server picks up all changes instantly. If user status is not 1 then server won’t allow user to login trough XMPP even if user provides valid password.

There is no Roster management in Drupal yet. So Roster management have to be done from the XMPP client.

8.4.4. LDAP Authentication Connector

Tigase XMPP Server offers support for authenticating users against an LDAP server in Bind Authentication mode.

Configuration for the LDAP support is really simple you just have to add a few lines to your config.tdsl file.

authRepository {
    default () {
        cls = 'tigase.db.ldap.LdapAuthProvider'
        uri = 'ldap://ldap.tigase.com:389'
        'user-dn-pattern' = 'cn=USER_ID,ou=people,dc=tigase,dc=org'
    }
}

Please note the USER_ID element, this is a special element of the configuration which is used to authenticate particular user. Tigase LDAP connector replaces it with appropriate data during authentication. You can control what Tigase should put into this part. In your configuration you must replace this string with one of the following:

  1. %1$s - use user name only for authentication (JabberID’s localpart)

  2. %2$s - use domain name only for authentication (JabberID’s domain part)

  3. %3$s - use the whole Jabber ID (JID) for authentication

8.4.5. Configuration of SASL EXTERNAL

In order to enable SASL External add following line to the config.tdsl file

c2s {
    clientCertCA = '/path/to/cacert.pem'
}

File cacert.pem contains Certificate Authority certificate which is used to sign clients certificate.

Client certificate must include user’s Jabber ID as XmppAddr in subjectAltName:

As specified in RFC 3920 and updated in RFC 6120, during the stream negotiation process an XMPP client can present a certificate (a “client certificate”). If a JabberID is included in a client certificate, it is encapsulated as an id-on-xmppAddr Object Identifier (“xmppAddr”), i.e., a subjectAltName entry of type otherName with an ASN.1 Object Identifier of “id-on-xmppAddr” as specified in Section 13.7.1.4 of RFC 6120, XEP-0178.

It is possible to make client certificate required:

c2s {
    clientCertRequired = true
}

If this option will be enabled, then client must provide certificate. This certificate will be verified against clientCertCA. If client does not provide certificate or certificate will be invalid, TLS handshake will be interrupted and client will be disconnected.

Using this options does not force client to use SASL EXTERNAL. Client still may authenticate with other SASL mechanisms.

8.5. Packet Filtering

Tigase offers different ways to filter XMPP packets flying through the server. The most common use for packet filtering is to restrict users from sending or receiving packets based on the sender or received address.

There are also different possible scenarios: time based filtering, content filtering, volume filtering and so on.

All pages in this section describe different filtering strategies.

8.5.1. Domain Based Packet Filtering

Domain based packet filtering is a simple filter allowing to restrict user communication based on the source/destination domain name. This is especially useful if we want to limit user communication within a single - own domain only or a list of domains.

A company might not wish to allow employers to chat during work hours with anybody in the world. A company may also have a few different domains used by different branches or departments. An administrator may restrict communication to a list of domains.

Introduction

The restriction is on a per-user basis. So the administrator can set a different filtering rules for each user. There is also a per-domain configuration and global-installation setting (applied from most general to most specific, i.e. from installation to user).

Regular users can not change the settings. So this is not like a privacy list where the user control the filter. Domain filter can not be changed or controlled by the user. The system administrator can change the settings based on the company policy.

There are predefined rules for packet filtering:

  1. ALL - user can send and receive packets from anybody.

  2. LOCAL - user can send and receive packets within the server installation only and all it’s virtual domains.

  3. OWN - user can send and receive packets within his own domains only

  4. BLOCK - user can’t communicate with anyone. This could be used as a means to temporarily disable account or domain.

  5. LIST - user can send and receive packets within listed domains only (i.e. whitelist).

  6. BLACKLIST - user can communicate with everybody (like ALL), except contacts on listed domains.

  7. CUSTOM - user can communicate only within custom created rules set.

Whitelist (LIST) and blacklist (BLACKLIST) settings are mutually exclusive, i.e. at any given point of time only one of them can be used.

Those rules applicable to particular users are stored in the user repository and are loaded for each user session. If there are no rules stored for a particular user server tries to apply rules for a VHost of particular user, and if there is no VHost filtering policy server uses global server configuration. If there is no filtering policy altogether server applies defaults based on following criteria:

  1. If this is Anonymous user then LOCAL rule is applied

  2. For all other users ALL rule is applied.

Configuration

Filtering is performed by the domain filter plugin which must be loaded at startup time. It is loaded by default if the plugins list is not set in the configuration file. However if you have a list of loaded plugins in the configuration file make sure domain-filter is on the list.

There is no other configuration required for the plugin to work.

Administration, Rules Management

Although controlling domain filtering rules is possible for each user separately, it is not practical for large installations. In most cases users are stored in the database and a third-party system keeps all the user information.

To change the rule for a single user you can use loadable administration scripts feature and load UserDomainFilter.groovy script. It enables modifying rules for a given user JID.

Implementation

If you have a third party system which keeps and manages all user information than you probably have your own UserRepository implementation which allows the Tigase server to access user data. Filtering rules are loaded from user repository using following command:

repo.getData(user_id, null, DomainFilter.ALLOWED_DOMAINS_KEY, null)
repo.getData(user_id, null, DomainFilter.ALLOWED_DOMAINS_LIST_KEY, null)

Where user_id is user Jabber ID without resource part, DomainFilter.ALLOWED_DOMAINS_KEY is a property key: "allowed-domains". The user repository MUST return one of following only:

  1. ALL - if the user is allowed to communicate with anybody

  2. LOCAL - if the user is allowed to communicate with users on the same server installation.

  3. OWN - if the user is allowed to communicate with users within his own domain only.

  4. LIST - list of domains within which the user is allowed to communicate with other users. No wild-cards are supported. User’s own domain should be included too.

  5. BLACKLIST - list of domains within which the user is NOT allowed to communicate with other users. No wild-cards are supported. User’s own domain should NOT be included.

  6. CUSTOM - list of rules defining custom communication permissions (server processes stanza according to first matched rule, similar to XEP-0016) in the following format:

ruleSet = rule1;rule2;ruleX;

rule = order_number|policy|UID_type[|UID]

order_number = any integer;
policy = (allow|deny);
UID_type = [jid|domain|all];
UID = user JID or domain, for example pubsub@test.com; if UID_type is ALL then this is ignored.

For example:

1|allow|self;
2|allow|jid|admin@test2.com;
3|allow|jid|pubsub@test.com;
4|deny|all;
  1. null - a java null if there are no settings for the user.

In case of LIST and BLACKLIST filtering options, it’s essential to provide list of domains for the whitelisting/blacklisting. DomainFilter.ALLOWED_DOMAINS_LIST_KEY is a property key: "allowed-domains-list". The user repository MUST return semicolon separated list of domains: domain1.com;domain2.com,domain3.org

The filtering is performed by the tigase.xmpp.impl.DomainFilter plugin. Please refer to source code for more implementation details.

8.6. Access Control Lists in Tigase

Tigase offers support for Access Control List (ACL) to allow for fine grained access to administration commands on the server.

By default, all administration commands are only accessible (visible through service discovery and can be executed) by the service administrators. Service administrators are existing accounts with JIDs (BareJIDs) listed in the init.properties file under --admins.

Additionally, other XMPP users and entities can be assigned permissions to execute a command or commands using Tigase’s ACL capabilities.

The following is a list of possible ACL modifiers for administrator command accessibility:

  • ALL - Everybody can execute the command, even users from different federated servers.

  • ADMIN - Local server administrators can execute the command, this is a default setting if no ACL is set for a command.

  • LOCAL - All users with accounts on the local server can execute the command. Users from other, federated servers will not be able to execute the command.

  • NONE - No one will be allowed to execute this command

  • DOMAIN_OWNER - Only user which is owner of the domain which items are being manipulated is allowed to execute the comment. If script is not checking permissions for the manipulated item, this value will behave in the same way as LOCAL.

  • DOMAIN_ADMIN - Only user which is one of the domain administrators will be able to execute the command manipulating items related to the domain. If script is not checking permissions for the manipulated item, this value will behave in the same way as LOCAL.

  • exampl.com - Only users with accounts on the selected domain will be able to execute the command. It may be useful to setup a domain specifically for admin accounts, and automatically all users within that domain would be able to run the command.

  • user@example.com - Comma separated list of JIDs of users who can execute the command.

In any case, regardless of ACL settings, any command can be executed and accessed by the designated service wide administrators, that is accounts listed as admins in the init.properties file.

Multiple ACL modifiers can be combined and applied for any command. This may not always makes sense. For example ALL supersedes all other settings, so it does not make sense to combine it with any other modifier. However, most others can be combined with JID to broaden access to specific accounts.

On Tigase server the Access Control List is checked for the first matching modifier. Therefore if you combine ALL with any other modifier, anybody from a local or remote service will always be able to execute the command, no matter what other modifiers are added.

Please note, the ACL lists work on the command framework level. Access is verified before the command is actually executed. There might be additional access restrictions within a command itself. In many cases, even if all local users are permitted to execute a command (LOCAL modifier), some commands allow only to be executed by a domain owner or a domain administrator (and of course by the service-wide administrators as well). All the commands related to a user management such as adding a new user, removing a user, password changes, etc… belong to this category. When conducting domain (vhost) management, creation/registration of a new domain can be done by any local user (if LOCAL ACL modifier is set) but then all subsequent domain management tasks such as removing the vhost, updating its configuration, setting SSL certificate can be done by the domain owner or administrator only.

The ACL list is set for a specific Tigase component and a specific command. Therefore the configuration property must specify all the details. So the general format for configuring ACL for a command is this:

comp-id () {
    commands {
        'command-id' = [ 'ACL_modifier', 'ACL_modifier', 'ACL_modifier' ]
    }
}

The breakdown is as such:

  • comp-id is the Tigase server component ID such as: sess-man, vhost-man, c2s, etc..

  • commands is a static text which indicates that the property is for component’s command settings.

  • command-id is a command ID for which we set the ACL such as query-dns, http://jabber.org/protocol/admin#add-user, user-roster-management, etc…

Here are a few examples:

Allowing local users to create and manage their own domains

'vhost-man' () {
    commands {
        'comp-repo-item-add' = 'LOCAL'
        'comp-repo-item-remove' = 'LOCAL'
        'comp-repo-item-update' = 'LOCAL'
        'ssl-certificate-add' = 'LOCAL'
    }
}

In fact all the commands except item-add can be executed by the domain owner or administrator.

Allowing local users to execute user management commands:

'sess-man' () {
    'commands' {
        'http://jabber.org/protocol/admin#add-user' = 'LOCAL'
        'http://jabber.org/protocol/admin#change-user-password' = 'LOCAL'
        'http://jabber.org/protocol/admin#delete-user' = 'LOCAL'
        'http://jabber.org/protocol/admin#get-online-users-list' = 'LOCAL'
        'http://jabber.org/protocol/admin#get-registered-user-list' = 'LOCAL'
        'http://jabber.org/protocol/admin#user-stats' = 'LOCAL'
        'http://jabber.org/protocol/admin#get-online-users-list' = 'LOCAL'
    }
}

As in the previous example, the commands will by executed only by local users who are the specific domain administrators.

Allowing users from a specific domain to execute query-dns command and some other users for given JIDs from other domains:

'vhost-man' () {
    'commands' {
        'query-dns' = [ 'tigase.com', 'admin@tigase.org', 'frank@example.com' ]
    }
}

To be able to set a correct ACL property you need to know component names and command IDs. Component IDs can be found in the service discovery information on running server or in the server logs during startup. A command ID can be found in the command script source code. Each script contains a list of metadata at the very beginning of it’s code. One of them is AS:CommandId which is what you have to use for the ACL setting.

9. Database Management

Tigase is coded to perform with multiple database types and numbers. Owing to it’s versatile nature, there are some tools and procedures that may be of use to certain administrators.

As of v8.0.0 here are the minimum and recommended versions of databases for use with Tigase:

Database Recommended Version Minimum Version Additional Information

DerbyDB

10.12.1.1

10.12.1.1

Included with Tigase XMPP Server

MySQL

5.7

5.6.4

Required to properly support timestamp storage with millisecond precision

SQLServer

2014

2012

2012 needed so we can count use fetch-offset pagination feature.

PostgreSQL

9.5

9.4

New UA schema requires at least 9.4

MongoDB

3.2

3.0

MariaDB

?

10.0.12

Basic features works with 10.0.12-MariaDB Homebrew, but is not fully tested.

Although Tigase may support other versions of databases, these are the ones we are most familiar with in offering support and advice. Use of databases outside these guidelines may result in unforeseen errors.

9.2. Database Watchdog

It is possible to have Tigase test availability and existence of database periodically only when db connections are idle. By default this ping is sent once every 60 minutes to each connected repository. However this can be overridden as a part of the dataSource property:

dataSource {
    default () {
        uri = '....'
    }
    'test' () {
        uri =  '...'
        'watchdog-frequency' = 'PT30M'
    }
}

This setting changes frequency to 30 minutes.

dataSource {
    default () {
        uri = '...'
    }
    'watchdog-frequency' = 'PT15M'
}

This one changes to 15 minutes.

9.3. Using modified database schema

If you are using Tigase XMPP Server with modified schema (changed procedures or tables) and you do not want Tigase XMPP Server to maintain it and automatically upgrade, you can disable schema-management for any data source. If schema-management is disable for particular data source then Tigase XMPP Server will not update or modify database schema in any way. Moreover it will not check if schema version is correct or not.

Disabling schema-management for default data source
dataSource {
    default () {
        uri = '...'
        'schema-management' = false
    }
}
Warning
If schema-management is disabled, then it is administrator responsibility to maintain database schema and update it if needed (ie. if Tigase XMPP Server schema was changed).

9.4. Database Preparation

Tigase uses generally the same database schema and the same set of stored procedures and functions on every database. However, the schema creation scripts and code for stored procedures is different for each database. Therefore the manual process to prepare database is different for each database system.

Starting with v8.0.0, most of the database tasks have been automated and can be called using simple text, or using interactive question and answer style. We DO NOT RECOMMEND going through manual operation, however we have kept manual activation of different databases to the Appendix. If you are interested in how we manage and update our database schemas, you may visit the Schema Maintenance section of our Redmine installation for more detailed information.

Appendix entries

9.4.1. Schema Utility

With the release of v8.0.0 calling the Tigase dbSchemaLoader utility now can be done using tasks instead of calling the specific method. Support for Derby, MySQL, PostgreSQL, MSSQL, and MongoDB is available.

In order to use this utility with any of the databases, you will need to first have the database environment up and running, and have established user credentials. You may use root or an account with administrator write privileges.

Operation & Variables

Operation Operating the schema utility is quite easy! To use it run this command from the installation directory:

./scripts/tigase.sh [task] [params_file.conf] [options]

Operations are now converted to tasks, of which there are now three: install-schema, upgrade-schema, and destroy-schema.

  • upgrade-schema: Upgrade the schema of the database specified in your config.tdsl configuration file. (options are ignored for this option)

  • install-schema: Install a schema to database.

  • destroy-schema: Destroy database and schemas. DANGEROUS

Options

Use the following options to customize. Options in bold are required, {potential options are in brackets}.
  • --help Prints the help for the task.

  • -I or --interactive enables interactive mode which will prompt for parameters not defined.

  • -T or --dbType database_type {derby, mongodb, mysql, postgresql, sqlserver}.

  • -C or --components= Allows the specification of components for use when installing a schema.

Usage
upgrade-schema

This task will locate any schema versions above your current one, and will install them to the database configured in the config.tdsl file.

Note
To use this utility, you must have Tigase XMPP server fully setup with a configured configuration file.
./scripts/tigase.sh upgrade-schema etc/tigase.conf

Windows users will need to run the command using the following command:

java -cp "jars/*" tigase.db.util.SchemaManager "upgrade-schema" --config-file=etc/config.tdsl
install-schema

This task will install a schema using the parameters provided.

If you are setting up a server manually, we HIGHLY recommend using this method

./scripts/tigase.sh install-schema [Options]

This command will install tigase using a Derby database on one named tigasedb hosted on localhost. The username and password editing the database is tigase_pass and root. Note that -J explicitly adds the administrator, this is highly recommended with the -N passing the password.

If you are using a windows system, you need to call the program directly:

java -cp "jars/*" tigase.db.util.SchemaManager "install-schema" [options]

Options Options for schema installation are as follows, required options are in bold

  • --help, Outputs the help.

  • -I, --interactive, Enables interactive mode, which will result in prompting for any missing parameters.

  • -C, --components=, List of enabled components identifiers (+/-), possible values: [amp, bosh, c2s, eventbus, ext-disco, http, mdns, message-archive, monitor, muc, pubsub, push, s2s, socks5, test, unified-archive, upload, ws2s] (default: amp,bosh,c2s,eventbus,http,message-archive,monitor,muc,pubsub,s2s,ws2s). This is required for certain components like socks5.

  • -T, --dbType=, Database server type, possible values are: [derby, mongodb, mysql, postgresql, sqlserver]

  • -D, --dbName=, Name of the database that will be created (by default it is tigasedb).

  • -H, --dbHostname=, Address of the database instance (by default it is localhost).

  • -U, --dbUser=, Name of the user that will be created specifically to access Tigase XMPP Server database (default is tigase_user).

  • -P, --dbPass=, Password of the user that will be created specifically to access Tigase XMPP Server database (default is tigase_pass).

  • -R, --rootUser=, Database root account username used to create user and database (default is root).

  • -A, --rootPass=, Database root account password used to create user and database (default is root).

  • -S, --useSSL, Enable SSL support for database connection (if the database supports it) (default is false).

  • -F, --file=value, Comma separated list of SQL files that will be processed.

  • -Q, --query=, Custom queries to be executed, see Query function for details.

  • -L, --logLevel=, Logger level used during loading process (default is CONFIG).

  • -J, --adminJID=, Comma separated list of administrator JID(s).

  • -N value, --adminJIDpass=, Password that will be used for the entered JID(s) - one password for all configured JIDs.

  • --getURI=, Generate database URI (default is false).

  • --ignoreMissingFiles=, Force ignoring missing files errors (default is false).

Query function

Should you decide to customize your own functions, or have specific information you want to put into the database, you can use the -query function to perform a single query step.

./scripts/tigase.sh install-schema -T mysql -D tigasedb -R root -A root -Q "CREATE TABLE tigasedb.EXTRA_TABLE (id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, name VARCHAR(10) NOT NULL)"

Of course this would break the schema for tigasedb by adding an unexpected table, you will receive the following message:

tigase.db.util.DBSchemaLoader       printInfo          WARNING       Database schema is invalid

But this is a demonstration how you may run a query through the database without the need to use another tool. Note that you will need to select the specific database for each query.

destroy-schema

This will destroy the database specified in the configuration file. WARNING: THIS ACTION IS NOT REVERSIBLE

./scripts/tigase.sh destroy-schema etc/config.tdsl

Only use this if you wish to destroy a database and not have the information recoverable.

Windows users will need to call the method directly:

java -cp "jars/*" tigase.db.util.SchemaManager "destroy-schema" etc/config.tdsl
A note about MySQL

If you are using these commands, you may result in the following error:

tigase.util.DBSchemaLoader       validateDBConnection    WARNING    Table 'performance_schema.session_variables' does not exist

If this occurs, you will need to upgrade your version of MySQL using the following command:

mysql_upgrade -u root -p --force

After entering the password and upgrading MySQL the schema error should no longer show when working with Tigase databases.

9.5. Hashed User Passwords in Database

Warning
This feature is still available, but passwords are stored encrypted by default since v8.0.0. We do not recommend using these settings.

By default, user passwords are stored in plain-text in the Tigase’s database. However, there is an easy way to have them encoded in either one of already supported ways or to even add a new encoding algorithm on your own.

Storing passwords in hashed format in the database makes it possible to avoid using a plain-text password authentication mechanism. You cannot have hashed passwords in the database and non-plain-text password authentication. On the other hand, the connection between the server and the client is almost always secured by SSL/TLS so the plain-text password authentication method is perhaps less of a problem than storing plain-text passwords in the database.

Nevertheless, it is simple enough to adjust this in Tigase’s database.

9.5.1. Shortcut

Connect to your database from a command line and execute following statement for MySQL database:

call TigPutDBProperty('password-encoding', 'encoding-mode');

Where encoding mode is one of the following:

  • MD5-PASSWORD the database stores MD5 hash code from the user’s password.

  • MD5-USERID-PASSWORD the database stores MD5 hash code from concatenated user’s bare JID and password.

  • MD5-USERNAME-PASSWORD the database stores MD5 hash code from concatenated user’s name (localpart) and password.

For example:

call TigPutDBProperty('password-encoding', 'MD5-PASSWORD');

9.5.2. Full Route

The way passwords are stored in the DB is controlled by Tigase database schema property. Properties in the database schema can be set by a stored procedure called: TigPutDBProperty(key, value). Properties from the DB schema can be retrieved using another stored function called: TigGetDBProperty(key).

The simplest way to call them is via command-line interface to the database.

For the purpose of this guide let’s say we have a MySQL database and a test account: test@example.com with password test77.

By default, most of DB actions for Tigase, are performed using stored procedures including user authentication. So, the first thing to do is to make sure the stored procedures are working correctly.

Create a Test User Account

To add a new user account we use a stored procedure: TigAddUserPlainPw(bareJid, password). As you can see there is this strange appendix to the procedure name: PlainPw. This procedure accepts plain passwords regardless how it is stored in the database. So it is safe and easy to use either for plain-text passwords or hashed in the DB. There are also versions of procedures without this appendix but they are sensitive on the data format and always have to pass password in the exact format it is stored in the database.

So, let’s add a new user account:

call TigAddUserPlainPw('test@example.com', 'test77');

If the result was 'Query OK', then it means the user account has been successfully created.

Test User Authentication

We can now test user authentication:

call TigUserLoginPlainPw('test@example.com', 'test77');

If authentication was successful the result looks like this:

+--------------------+
| user_id            |
+--------------------+
| 'test@example.com' |
+--------------------+
1 row in set (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

If authentication was unsuccessful, the result looks like this:

+---------+
| user_id |
+---------+
|    NULL |
+---------+
1 row in set (0.01 sec)

Query OK, 0 rows affected (0.01 sec)
Password Encoding Check

TigGetDBProperty is a function, not a procedure in MySQL database so we have to use select to call it:

select TigGetDBProperty('password-encoding');

Most likely output is this:

+---------------------------------------+
| TigGetDBProperty('password-encoding') |
+---------------------------------------+
| NULL                                  |
+---------------------------------------+
1 row in set, 1 warning (0.00 sec)

Which means a default password encoding is used, in plain-text and thus no encoding. And we can actually check this in the database directly:

select uid, user_id, user_pw from tig_users where user_id = 'test@example.com';

And expected result with plain-text password format would be:

+-----+--------------------+---------+
| uid | user_id            | user_pw |
+-----+--------------------+---------+
|  41 | 'test@example.com' | test77  |
+-----+--------------------+---------+
1 row in set (0.00 sec)
Password Encoding Change

Now let’s set password encoding to MD5 hash:

call TigPutDBProperty('password-encoding', 'MD5-PASSWORD');

'Query OK', means the password encoding has been successfully changed. Of course we changed the property only. All the existing passwords in the database are still in plain-text format. Therefore we expect that attempt to authenticate the user would fail:

call TigUserLoginPlainPw('test@example.com', 'test777');
+---------+
| user_id |
+---------+
|    NULL |
+---------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

We can fix this by updating the user’s password in the database:

call TigUpdatePasswordPlainPw('test@example.com', 'test777');
Query OK, 1 row affected (0.01 sec)

mysql> call TigUserLoginPlainPw('test@example.com', 'test777');
+--------------------+
| user_id            |
+--------------------+
| 'test@example.com' |
+--------------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

9.6. Preparing Tigase for MongoDB

Tigase now supports MongoDB for auth, settings, and storage repositories. If you wish to use MongoDB for Tigase, please use this guide to help you.

9.6.1. Dependencies

To run Tigase MongoDB support library requires drivers for MongoDB for Java which can be downloaded from here. This driver needs to be placed in /jars directory located in Tigase XMPP Server installation directory. If you are using a dist-max distribution, it is already included.

9.6.2. Configuration

Note that fresh installations of MongoDB do not come with users or databases installed. Once you have setup MongoDB you will need to create a user to be used with Tigase. To do this, bring up the mongo console by running mongo.exe in a cmd window for windows, or run mongo in linux. Once connected, enter then following:

>use admin
switched to admin
>db.createUser (
... {
... user: "tigase"
... pwd: "password"
... roles: [ "root" ]
... }
... )

Press shift + Enter to create new lines in the command and the shell will automatically add the three ellipses. Be sure to give this user a root role in order to properly write to the database. Once you receive a user successfully created message, you are ready to install tigase on MongoDB.

Configuration of user repository for Tigase XMPP Server

To configure Tigase XMPP Server to use MongoDB you need to set dataSource in etc/config.tdsl file to proper MongoDB URI pointing to which MongoDB database should be used (it will be created by MongoDB if it does not exist). userRepository property should not be set to let Tigase XMPP Server auto-detect proper implementation of UserRepository. Tigase XMPP Server will create proper collections in MongoDB if they do not exist so no schema files are necessary.

Example configuration of XMPP Server pointing to MongoDB database tigase_test in a local instance:

dataSource {
    default () {
        uri = 'mongodb://user:pass@localhost/tigase_test'
    }
}
userRepository {
    default () {}
}
authRepository {
    default () {}
}

If Tigase Server is not able to detect a proper storage layer implementation, it can be forced to use one provided by Tigase using the following lines in etc/config.tdsl file:

userRepository {
    default () {
        cls = 'tigase.mongodb.MongoRepository'
    }
}
authRepository {
    default () {
        cls = 'tigase.mongodb.MongoRepository'
    }
}

Every component should be able to use proper implementation to support MongoDB using this URI. Also MongoDB URI can be passed as any URI in configuration of any component.

Configuration for MUC

By default, MUC component will use MongoDB to store data if Tigase is configured to use it as a default store. However, if you would like to use a different MongoDB database to store MUC message archive, you can do this by adding the following lines to etc/config.tdsl file:

muc {
    'history-db-uri' = 'mongodb://user:pass@localhost/tigase_test'
}

If MUC components fails to detect and use a proper storage layer for MongoDB, you can force it to use one provided by Tigase by using the following line in the config.tdsl file:

muc {
    'history-db' = 'tigase.mongodb.muc.MongoHistoryProvider'
}
Configuration for PubSub

By default, PubSub component will use MongoDB to store data if Tigase is configured to use it as a default store. However, if you would like to use a different MongoDB database to store PubSub component data, you can do this by adding the following lines to etc/config.tdsl file:

pubsub {
    'pubsub-repo-url' = 'mongodb://user:pass@localhost/tigase_test'
}

If the PubSub components fails to detect and use a proper storage layer for MongoDB, you can force it to use one provided by Tigase by using the following line in the config.tdsl file:

pubsub {
    'pubsub-repo-class' = 'tigase.mongodb.pubsub.PubSubDAOMongo'
}
Configuration for Message Archiving

By default, the Message Archiving component will use MongoDB to store data if Tigase is configured to use it as a default store. However, if you would like to use a different MongoDB database to store message archives, you can do this by adding the following lines to etc/config.tdsl file:

'message-archive' {
    'archive-repo-uri' = 'mongodb://user:pass@localhost/tigase_test'
}

If Message Archiving component fails to detect and use a proper storage layer for MongoDB, you can force it to use one provided by Tigase by using the following line in the config.tdsl file:

'message-archive' {
    'archive-repo-class' = 'tigase.mongodb.archive.MongoMessageArchiveRepository'
}

9.6.3. Schema Description

This description contains only basic description of schema and only basic part of it. More collections may be created if additional components of Tigase XMPP Server are loaded and configured to use MongoDB.

Tigase XMPP Server Schema

Basic schema for UserRespository and AuthRepository consists of two collections: . tig_users - contains list of users . tig_nodes - contains data related to users in tree-like way

tig_users collection contains the following fields:

Table 2. tig_users
Name Description

_id

id of user which is SHA256 hash of users jid (raw byte array).

user_id

contains full user jid.

domain

domain to which user belongs for easier lookup of users by domain.

password

password of user (will be removed after upgrade to 8.0.0).

tig_nodes collection contains the following fields

Table 3. tig_nodes
Name Description

_id

id of row auto-generated by MongoDB.

uid

id of user which is SHA256 hash of users jid (raw byte array).

node

full path of node in tree-like structure separated by / (may not exist).

key

key for which value for node is set.

value

value which is set for node key.

Tigase XMPP Server also uses additional collections for storage of Offline Messages

Table 4. msg_history collection
Name Description

from

full user jid of message sender.

from_hash

SHA256 hash of message sender jid as raw byte array.

to

full users jid of message recipient.

to_hash

SHA256 hash of message recipient full jid as raw byte array.

ts

timestamp of message as date.

message

serialized XML stanza containing message.

expire-at

timestamp of expiration of message (if message contains AMP expire-at set).

Additions for v8.0 Schema

Due to changes in authentication and credentials storage in AuthRepository, we moved password field from tig_users collection to a newly created collection called tig_user_credentials.

This new collection has following fields:

Name Description

_id

id of document automatically generated by MongoDB

uid

SHA256 hash of a user for which credentails are stored

username

username provided during authentication (or default)

account_status

name of an account state (copy of value stored in user document from`tig_users`)

Additionally for each mechanism we store separate field in this object, so for:

  • PLAIN we have PLAIN field with value for this mechanism

  • SCRAM-SHA-1 we have SCRAM-SHA-1 field with value for this mechanism

  • etc…​

Upgrade is not done in one step, and rather will be done once a particular user will log in. During authentication if there is no data in tig_user_credentials, Tigase XMPP Server will check if password field in tig_user exists. If it does, and it is filled credentials will be migrated to the new collection.

9.7. Tigase Server and Multiple Databases

Splitting user authentication data from all other XMPP information such as roster, vcards, etc…​ was almost always possible in Tigase XMPP Server. Possible and quite simple thing to configure. Also it has been always possible and easy to assign a different database for each Tigase component (MUC, PubSub, AMP), for recording the server statistics. Almost every data type or component can store information in a different location, simple and easy to setup through the configuration file.

However it is much less known that it is also possible to have a different database for each virtual domain. This applies to both the user repository and authentication repository. This allows for very interesting configuration such as user database sharing where each shard keeps users for a specific domain, or physically split data based on virtual domain if each domain refers to a different customer or group of people.

How can we do that then?

This is very easy to do through the Tigase’s configuration file.

dataSource {
    default () {
        uri = 'jdbc:mysql://db2.tigase/dbname?user&password'
    }
    'default-auth' () {
        uri = 'jdbc:mysql://db1.tigase/dbname?user&password'
    }
}
userRepository {
    default () {}
}
authRepository {
    default () {
        cls = 'tigase.db.jdbc.TigaseCustomAuth'
        'data-source' = 'default-auth'
    }
}

This configuration defines just a default databases for both user repository and authentication repository. Default means it is used when there is no repository specified for a particular virtual domain. However, you can have a separate, both user and authentication repository for each virtual domain.

Here is, how it works:

First, let’s define our default database for all VHosts

dataSource {
    default () {
        uri = 'jdbc:mysql://db2.tigase/dbname?user&password'
    }
    'default-auth' () {
        uri = 'jdbc:mysql://db1.tigase/dbname?user&password'
    }
}
userRepository {
    default () {}
}
authRepository {
    default () {
        cls = 'tigase.db.jdbc.TigaseCustomAuth'
        'data-source' = 'default-auth'
    }
}

Now, we have VHost: domain1.com User authentication data for this VHost is stored in Drupal database

dataSource {
  'domain1.com-auth' () {
    uri = jdbc:mysql://db7.tigase/dbname?user&password'
  }
}
authRepository {
  domain1.com () {
    cls = 'tigase/db/jdbc.TigaseCustomAuth'
    'data-source' = 'domain1.com-auth'
  }
}

All other user data is stored in Tigase’s standard database in MySQL

dataSource {
  'domain1.com' () {
    uri = jdbc:mysql://db4.tigase/dbname?user&password'
  }
}
userRepository {
  domain1.com () {}
}

Next VHost: domain2.com User authentication is in LDAP server but all other user data is stored in Tigase’s standard database

authRepository {
    domain2.com () {
        cls = 'tigase.db.ldap.LdapAuthProvider'
        uri = 'ldap://ldap.domain2.com:389'
        'data-source' = 'default'
    }
}

Now is something new, we have a custom authentication repository and separate user settings for a single domain. Please note how we define the VHost for which we set custom parameters

authRepository {
    domain2.com {
        'user-dn-pattern' = 'cn=,ou=,dc=,dc='
    }
}

All other user data is stored in the same as default repository

userRepository {
    domain2.com () {}
}
dataSource {
    domain2.com () {
        uri = 'jdbc:mysql://db2.tigase/dbname?user&password'
    }
}

When combined, the DSL output should look like this:

dataSource {
    domain2.com () {
        uri = 'jdbc:mysql://db2.tigase/dbname?user&password'
    }
}
userRepository {
    domain2.com () {}
}
authRepository {
    domain2.com () {
        cls = 'tigase.db.ldap.LdapAuthProvider'
        uri = 'ldap://ldap.domain2.com:389'
        'user-dn-pattern' = 'cn=,ou=,dc=,dc='
    }
}

Next VHost: domain3.com Again user authentication is in LDAP server but pointing to a different LDAP server with different access credentials and parameters. User information is stored in a postgreSQL database.

dataSource {
    domain3.com () {
        uri = 'jdbc:pgsql://db.domain3.com/dbname?user&password'
    }
}
userRepository {
    domain3.com () {}
}
authRepository {
    domain3.com () {
        cls = 'tigase.db.ldap.LdapAuthProvider'
        uri = 'ldap://ldap.domain3.com:389'
        'user-dn-pattern' = 'cn=,ou=,dc=,dc='
    }
}

For VHost: domain4.com all the data, both authentication and user XMPP data are stored on a separate MySQL server with custom stored procedures for both user login and user logout processing.

dataSource {
    domain4.com () {
        uri = 'jdbc:mysql://db14.domain4.com/dbname?user&password'
    }
}
userRepository {
    domain4.com () {}
}
authRepository {
    domain4.com () {
        cls = 'tigase.db.jdbc.TigaseCustomAuth'
        'user-login-query' = '{ call UserLogin(?, ?) }'
        'user-logout-query' = '{ call UserLogout(?) }'
        'sasl-mechs' = [ 'PLAIN', 'DIGEST-MD5' ]
    }
}

As you can see, it requires some writing but flexibility is very extensive and you can setup as many separate databases as you need or want. If one database (recognized by the database connection string) is shared among different VHosts, Tigase still uses a single connection pool, so it won’t create an excessive number of connections to the database.

9.8. Importing User Data

You can easily copy data between Tigase compatible repositories that is repositories for which there is a database connector. However, it is not that easy to import data from an external source. Therefore a simple data import functionality has been added to repository utilities package.

You can access repository utilities through command ./bin/repo.sh or ./scripts/repo.sh depending on whether you use a binary package or source distribution.

-h parameter gives you a list of all possible parameters:

./scripts/repo.sh -h

Parameters:
 -h          this help message
 -sc class   source repository class name
 -su uri     source repository init string
 -dc class   destination repository class name
 -du uri     destination repository init string
 -dt string  data content to set/remove in repository
 -u user     user ID, if given all operations are only for that ID
             if you want to add user to AuthRepository parameter must
             in form: "user:password"
 -st         perform simple test on repository
 -at         simple test for adding and removing user
 -cp         copy content from source to destination repository
 -pr         print content of the repository
 -n          data content string is a node string
 -kv         data content string is node/key=value string
 -add        add data content to repository
 -del        delete data content from repository
 ------------
 -roster     check the user roster
 -aeg [true|false]  Allow empty group list for the contact
 -import file  import user data from the file of following format:
         user_jid, password, roser_jid, roster_nick, subscription, group



Note! If you put UserAuthRepository implementation as a class name
      some operation are not allowed and will be silently skipped.
      Have a look at UserAuthRepository to see what operations are
      possible or what operation does make sense.
      Alternatively look for admin tools guide on web site.

The most critical parameters are the source repository class name and the initialization string. Therefore there are a few example preset parameters which you can use and adjust for your system. If you look inside the repo.sh script you can find at the end of the script following lines:

XML_REP="-sc tigase.db.xml.XMLRepository -su ../testsuite/user-repository.xml_200k_backup"
MYSQL_REP="-sc tigase.db.jdbc.JDBCRepository -su jdbc:mysql://localhost/tigase?user=root&password=mypass"
PGSQL_REP="-sc tigase.db.jdbc.JDBCRepository -su jdbc:postgresql://localhost/tigase?user=tigase"

java $D -cp $CP tigase.util.RepositoryUtils $MYSQL_REP $*

You can see that the source repository has been set to MySQL database with tigase as the database name, root the database user and mypass the user password.

You can adjust these settings for your system.

Now to import data to your repository simply execute the command:

./bin/repo.sh -import import-file.txt

Note, the import function is available from b895

The format of the import file is very simple. This is a flat file with comma separated values:

jid,password,roster_jid,roster_nick,subscriptio,group

To create such a file from MySQL database you will have to execute a command like this one:

SELECT a, b, c, d INTO OUTFILE 'import-file.txt'
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
FROM test_table;

9.9. Importing Existing Data

Information about importing user data from other databases.

9.9.1. Connecting the Tigase Server to MySQL Database

Please before continuing reading of this manual have a look at the initial MySQL database setup. It will help you with database preparation for connecting with Tigase server.

The easiest way to setup Tigase server for connecting with MySQL database is to use the configuration wizards (configuration generators) which release you from manually editing the XML configuration file and allow you quickly regenerate the XML configuration file in case of problems.

The article describes an older way for using configuration generators which is a bit more difficult and doesn’t work on Windows systems. The guide below describes a new way to use them which is simpler and can be applied to Windows systems as well. It is using the config.tdsl file where you can put all your initial configuration parameters.

This guide describes MySQL database connection parameters.

This guide is actually very short as there are example configuration files which can be used and customized for your environment.

dataSource {
    default () {
        uri = 'jdbc:mysql://localhost/tigasedb?user=tigase_user&password=mypass'
    }
}
userRepository {
    default () {}
}
authRepository {
    default () {}
}

This is the basic setup for setting up an SQL repository for Tigase. dataSource contains the uri for default which is the mysql database. MySQL connector requires connection string in the following format: jdbc:mysql://[hostname]/[database name]?user=[user name]&password=[user password]

Edit the config.tdsl file for your environment.

Start the server using following command:

./scripts/tigase.sh start etc/tigase.conf

9.9.2. Integrating Tigase Server with Drupal

Tigase supports integration with Drupal on many levels. At the moment this guide can work with Drupal version 4.x and 5.x. They may also work with Drupal 6.x but this version hasn’t been tested.

First of all, Tigase can authenticate users against a Drupal database which means you have the same user account for both Drupal website and the XMPP server. Moreover in such a configuration all account management is done via Drupal web interface like account creation, password change update user details and so on. Administrator can temporarily disable user account and this is followed by Tigase server too.

Connecting to Drupal Database

The best way to setup Tigase with Drupal database is via the config.tdsl file where you can put initial setting for Tigase configuration.

If you look in etc/ directory of your Tigase installation you should find a the file there.

All you need to connect to Drupal database is set the following:

dataSource {
    'default-auth' () {
        uri = 'jdbc:mysql://localhost/drupal?user=drupalusr&password=drupalpass'
    }
}
authRepository {
    default () {
        cls = 'tigase.db.jdbc.DrupalWPAuth'
        'data-source' = 'default-auth'
    }
}

Typically, you will need to have drupal for authentication, and another for user repository. In this case, we will use SQL for user DB.

dataSource {
    default () {
        uri = 'jdbc:mysql://localhost/tigasedb?user=tigase_user&password=mypass'
    }
    'default-auth' () {
        uri = 'jdbc:mysql://localhost/drupal?user=drupalusr&password=drupalpass'
    }
}
userRepository {
    default () {}
}
authRepository {
    default () {
        cls = 'tigase.db.jdbc.DrupalWPAuth'
        'data-source' = 'default-auth'
    }
}

In theory you can load Tigase database schema to Drupal database and then both db-uris would have the same database connection string. More details about setting up and connecting to MySQL database can be found in the MySQL guide.

Now run the Tigase server.

./scripts/tigase.sh start etc/tigase.conf

Now you can register an account on your Drupal website and connect with an XMPP client using the account details.

Note
You have to enable plain password authentication in your XMPP client to connect to Tigase server with Drupal database.

9.9.3. Integrating Tigase Server With LibreSource

This document is still not finished.

Taken directly from LibreSource page:

LibreSource is a collaborative platform dedicated to both software development and community building. Based on Java/J2EE technology, LibreSource is a modular web server that users can customize online by combining resources and rights: wiki pages, forum, trackers, files, download areas, etc. All the tools are included and integrated.

Short Introduction

Integration between Tigase server and LibreSource is on a database level. It is implemented in the same way as integration with Drupal but with slightly more functions available.

Basically LibreSource system maintains own database with all it’s data and Tigase connects to LibreSource database to authenticate users. All user data specific to XMPP service are kept in separate tables which can be located in the same database as LibreSource data or in different database.

Current list of features included in the integration:

  • XMPP users authentication against user data stored in LibreSource database.

  • Recording XMPP user on-line status in LibreSource database. This can be displayed on the Web page as additional user info.

  • Recording user last login time and this information can also be available on Web page.

  • Checking user account status. So if the user account is disabled in LibreSource system then this user will not be able to login to XMPP service too.

  • User account creation. This feature might be useful during testing time or user data transition from an old Tigase installation to LibreSource system. Please note! This feature should be normally disabled on live system. All user account management should be done from LibreSource system because of data caching.

  • User account deletion. Please note! This feature should be normally disabled on live system. All user account management should be done from LibreSource system because of data caching.

A few assumptions:

  1. LibreSource data are kept in PostgreSQL database - libresource and database user is demo.

  2. For use in cases where Tigase data are stored in MySQL database name is tigase, database user is dbuser and database user password is dbpass

How to set Tigase up

Now we will focus on setting things up to have both services up and running together. Below is example of the most complex environment to run where LibreSource is using PostgreSQL database and Tigase is using a MySQL database. All basic user data needed for authentication is kept by LibreSource, so Tigase has to connect to PostgreSQL database also in order to authenticate users.

  1. First you need LibreSource system up and running. Please refer to LS documentation for details.

  2. Install Tigase server in the normal way including loading Tigase database schema. Database tables used by Tigase server use different naming convention so you can simply load Tigase DB schema to the same database as LibreSource data. It is also possible and recommended to keep Tigase data in separate database.

  3. Using configuration wizards generate configuration for Tigase server to connect to LibreSource database. Here is the sample file with parameters for configuration wizard assuming following setup:

    • LibreSource data are kept in PostgreSQL database: libresource, user: demo

    • Tigase data are kept in MySQL database: tigase, user: dbuser, password: dbpass

    • No external components are connected to Tigase server

    • Tigase works for domain: domain.net

'virt-hosts' = 'domain.net,localhost'
dataSource {
    default () {
        uri = 'jdbc:mysql://localhost/tigase?user=dbuser&password=dbpass&autoCreateUser=true'
        cls = 'com.mysql.jdbc.Driver:org.postgresql.Driver'
    }
    'default-auth' () {
        uri = 'jdbc:postgresql://localhost/libresource?user=demo'
        cls = 'com.mysql.jdbc.Driver:org.postgresql.Driver'
    }
}
userRepository {
    default () {}
}
authRepository {
    default () {
        'data-source' = 'default-auth'
    }
}
  1. A simpler example where all data (LibreSource and Tigase) are stored in the same database:

    • LibreSource data are kept in PostgreSQL database: libresource, user: demo

    • Tigase data is also kept in PostgreSQL database: libresource, user: demo

    • No external components are connected to Tigase server

    • Tigase works for domain: domain.net

'-virt-hosts' = 'domain.net,localhost'
dataSource {
    default () {
        uri = 'jdbc:postgresql://localhost/libresource?user=demo&autoCreateUser=true'
    }
    'default-auth' () {
        uri = 'jdbc:postgresql://localhost/libresource?user=demo'
    }
}
userRepository {
    default () {}
}
authRepository {
    default () {
        cls = 'tigase.db.jdbc.LibreSourceAuth'
        'data-source' = 'default-auth'
    }
}

Now, you can run Tigase as normal and it all works.

Note! You have to load Tigase database schema for user data. Please refer to guide for specific database: MySQL or PostgreSQL.

Migration From an old Tigase Installation to LibreSource

Tigase package includes additional tools to make it easier to manage and control you installation. One is used to change configuration settings - config.sh and another is used to manipulate user data in repository - repo.sh.

Depending on whether you use Tigase version built from sources or binary version these scripts might be available in either scripts/ or bin/ subdirectories. To make things simpler let’s assume they are stored in scripts/ directory.

Assuming you have an old Tigase server installation with number of users in MySQL database and you want to migrate all of them to LibreSource there are 2 steps involved:

  1. User data migration

  2. Changing your existing configuration

Data Migration

First we need to migrate user data used for authentication. That data will be used by both services: LibreSource and Tigase and they normally stored in LibreSource database. Therefore we have to use LibreSource database connector to handle the data (write or read). Tigase server will be using LibreSource database for reading only but during migration time we need to write user accounts to LS database. Sample command to migrate user accounts looks like this:

./scripts/repo.sh -sc tigase.db.jdbc.JDBCRepository \
  -su "jdbc:mysql://localhost/tigase?user=dbuser&password=dbpass" \
  -dc tigase.db.jdbc.LibreSourceAuth \
  -du "jdbc:postgresql://localhost/libresource?user=demo" \
  -cp

The above command will copy all user accounts from MySQL tigase database to LibreSource database. Please refer to repository management tool documentation for information how to migrate single or selected user accounts.

If you want to keep all Tigase server data in the same database you have to copy also all other user data like rosters, vCards and so on.

First thing we have to do is load the database schema for Tigase data. Because Tigase tables have distinct names from LibreSource, there is no danger for any conflict. As in the above example let’s assume LibreSource’s data is stored in libresource database and database user name is demo:

psql -q -U demo -d libresource -f database/postgresql-schema.sql

Now we can load and transfer all user data from MySQL database to LibreSource:

./scripts/repo.sh -sc tigase.db.jdbc.JDBCRepository \
  -su "jdbc:mysql://localhost/tigase?user=dbuser&password=dbpass" \
  -dc tigase.db.jdbc.JDBCRepository \
  -du "jdbc:postgresql://localhost/libresource?user=demo" \
  -cp

This command looks similar to the previous one. Just a Java class used for handling destination database is different.

9.9.4. PostgreSQL Database Use

This guide describes how to configure Tigase server to use PostgreSQL database as a user repository.

If you used an XML based user repository before you can copy all user data to PostgreSQL database using repository management tool. All steps are described below.

PostgreSQL Database Preparation

Create new database user account which will be used to connect to your database:

# createuser
Enter name of user to add: tigase
Shall the new user be allowed to create databases? (y/n) y
Shall the new user be allowed to create more new users? (y/n) y

Now using new database user account create database for your service:

# createdb -U tigase tigasedb
CREATE DATABASE

Now you can load the database schema:

# psql -U tigase -d tigasedb -f postgresql-schema.sql

Now the database is ready for Tigase server to use.

Server Configuration

Server configuration is almost identical to MySQL database setup. The only difference is the connection string which usually looks like:

dataSource {
    default () {
        uri = 'postgresql://localhost/tigasdb?user=tigase'
    }
}

9.10. Schema Updates

This is a repository for Schema updates in case you have to upgrade from older installations.

9.10.1. Changes to Schema in v8.0.0

For version 8.0.0 of Tigase XMPP Server, we decided to improve authentication and security that was provided. In order to do this, implementation of repository and database schemas needed to be changed to achieve this goal. This document, as well one in the HTTP API, will describe the changes to the schemas in this new version.

Reasons

Before version 8.0.0, user passwords were stored in plaintext in user_pw database field within tig_users table, but in plaintext. It was possible to enable storage of the MD5 hash of the password instead, however this limited authentication mechanism SASL PLAIN only. However an MD5 hash of a password is not really a secure method as it is possible to revert this mechanism using rainbow tables.

Therefore, we decided to change this and store only encrypted versions of a password in PBKDF2 form which can be easily used for SCRAM-SHA-1 authentication mechanism or SCRAM-SHA-256. SASL PLAIN mechanism can also used these encrypted passwords. The storage of encrypted passwords is now enabled by default in v8.0.0 of Tigase.

Summary of changes
Added support for storage of encrypted password

Passwords are no longer stored in plaintext on any database.

Using same salt for any subsequent authentications

This allows clients to reuse calculated credentials and keep them instead of storing plaintext passwords.

Disabled usage of stored procedure for authentication

In previous versions, Tigase used stored procedures TigUserLoginPlainPw and TigUserLogin for SASL PLAIN authentication. From version 8.0.0, those procedures are no longer used, but they are updated to use passwords stored in tig_user_credentials table.

It is still possible to use this procedures for authentication, but to do that you need add:

'user-login-query' = '{ call TigUserLoginPlainPw(?, ?) }'

to configuration block of every authentication repository.

To enable this for default repository, the authRepository configuration block will look like this:

authRepository () {
    default () {
        'user-login-query' = '{ call TigUserLoginPlainPw(?, ?) }'
    }
}
Deprecated API

Some methods of AuthRepository API were deprecated and should not be used. Most of them were used for authentication using stored procedures, retrieval of password in plaintext or for password change.

For most of these methods, new versions based on tig_user_credentials table and user credentials storage are provided where possible.

Deprecated storage procedures

Stored procedures for authentication and password manipulation were updated to a new form, so that will be possible to use them by older versions of Tigase XMPP Server during rolling updates of a cluster. However, these procedures will not be used any more and will be depreciated and removed in future versions of Tigase XMPP Server.

Usage of MD5 hashes of passwords

If you have changed password-encoding database property in previous versions of Tigase XMPP Server, then you will need to modify your configuration to keep it working. If you wish only to allow access using old passwords and to store changed passwords in the new form, then you need to enable credentials decoder for the correct authentication repository. In this example we will provided changes required for MD5-PASSWORD value of password-encoding database property. If you have used a different one, then just replace MD5-PASSWORD with MD5-USERNAME-PASSWORD or MD5-USERID-PASSWORD.

Usage of MD5 decoder
authRepository () {
    default () {
        credentialDecoders () {
            'MD5-PASSWORD' () {}
        }
    }
}

If you wish to store passwords in MD5 form then use following entries in your configuration file:

Usage of MD5 encoder
authRepository () {
    default () {
        credentialEncoders () {
            'MD5-PASSWORD' () {}
        }
    }
}
Enabling and disabling credentials encoders/decoders

You may enable which encoders and decoders used on your installation. By enabling encoders/decoders you are deciding in what form the password is stored in the database. Those changes may impact which SASL mechanisms may be allowed to use on your installation.

Enabling PLAIN decoder
authRepository () {
    default () {
        credentialDecoders () {
            'PLAIN' () {}
        }
    }
}
Disabling SCRAM-SHA-1 encoder
authRepository () {
    default () {
        credentialEncoders () {
            'SCRAM-SHA-1' (active: false) {}
        }
    }
}
Warning
It is strongly recommended not to disable encoders if you have enabled decoder of the same type as it may lead to the authentication issues, if client tries to use a mechanism which that is not available.
Schema changes

This change resulted in a creation of the new table tig_user_credentials with following fields:

uid

id of a user row in tig_users.

username

username used for authentication (if authzid is not provided or authzid localpart is equal to authcid then row with default value will be used).

mechanism

name of mechanism for which this credentials will be used, ie. SCRAM-SHA-1 or PLAIN.

value

serialized value required for mechanism to confirm that credentials match.

Warning
During execution of upgrade-schema task, passwords will be removed from tig_users table from user_pw field and moved to tig_user_credentials table.
Added password reset mechanism

As a part of Tigase HTTP API component and Tigase Extras, we developed a mechanism which allows user to reset their password. To use this mechanism HTTP API component and its REST module must to be enabled on Tigase XMPP Server installation.

Note
Additionally this mechanism need to be enabled in the configuration file. For more information about configuration of this mechanism please check Tigase HTTP API component documentation.

Assuming that HTTP API component is configured to run on port 8080 (default), then after accessing address http://localhost:8080/rest/user/resetPassword in the web browser it will present a web form. By filling and submitting this form, the user will initiate a password reset process. During this process, Tigase XMPP Server will send an email to the user’s email address (provided during registration) with a link to the password change form.

Upgrading from v7.1.x

When upgrading from previous versions of Tigase, it is recommended that you first backup the database. Refer to the documentation of your database software to find out how to export a copy. Once the backup is made, it will be time to run the schema upgrade. Be sure that your schema is up to date, and should be v7.1.0 Schema.

To upgrade, use the new 'upgrade-schema' task of SchemaManager:

In linux

./scripts/tigase.sh install-schema etc/tigase.conf

In Windows

java -cp "jars/*" tigase.db.util.SchemaManager "install-schema"

You will need to configure the following switches:

  • -T Specifies Database Type
    Possible values are: mysql, derby, sqlserver, postgresql, mongodb

  • -D Specifies Databse Name
    The explicit name of the database you wish to upgrade.

  • -H Specifies Host address
    By default, this is localhost, but may be set to IP address or FQDNS address.

  • -U Specifies Username
    This is the username that is authorized to make changes to the database defined in -D.

  • -P Specifies Password
    The password for username specified in -U.

  • -R Password for Administrator or Root DB account.

  • -A Password for Administrator or Root DB account.

  • -J Jid of user authorized as admin user from Tigase.

  • -N Password for user specified in -J.

  • -F Points to the file that will perform the upgrade.
    Will follow this form database/{dbname}-server-schema-8.0.0.sql

9.10.2. Tigase Server Schema v7.2 Updates

FOR ALL USERS UPGRADING TO v8.0.0 FROM A v7.0.2 INSTALLATION

The schema has changed for the main database, and the pubsub repository. In order to upgrade to the new schemas, you will need to do the following:

  1. Upgrade the Main database schema to v7.1 using the database/${DB_TYPE}-schema-upgrade-to-7-1.sql file

  2. Upgrade the Pubsub Schema to v3.1.0 using the database/${DB_TYPE}-pubsub-schema-3.1.0.sql file

  3. Upgrade the Pubsub Schema to v3.2.0 using the database/${DB_TYPE}-pubsub-schema-3.2.0.sql file

  4. Upgrade the Pubsub Schema to v3.3.0 using the database/${DB_TYPE}-pubsub-schema-3.3.0.sql file

All three commands may be done at the same time in that order, it is suggested you make a backup of your current database to prevent data loss.

Tigase Schema Change for v7.1

Tigase has made changes to its database to include primary keys in the tig_pairs table to improve performance of the Tigase server. This is an auto-incremented column for Primary Key items appended to the previous schema.

You MUST update your database to be compliant with the new schema. If you do not, Tigase will not function properly.

This change will affect all users of Tigase using v7.1.0 and newer.

If you are installing a new version of v8.0.0 on a new database, the schema should automatically be installed.

First, shut down any running instances of Tigase to prevent conflicts with database editing. Then from command line use the DBSchemaLoader class to run the -schema-upgrade-to-7.1.sql file to the database. The command is as follows:

In a linux environment

java -cp "jars/*" tigase.db.util.DBSchemaLoader -dbHostname ${HOSTNAME} -dbType ${DB_TYPE} -rootUser ${ROOT_USER} -dbPass ${DB_USER_PASS} -dbName ${DB_NAME} -schemaVersion ${DB_VERSION} -rootPass ${ROOT_USER_PASS} -dbUser ${DB_USER}  -adminJID "${ADMIN_JID}" -adminJIDpass ${ADMIN_JID_PASS}  -logLevel ALL -file database/${DB_TYPE}-schema-upgrade-to-7-1.sql

In a windows environment

java -cp jars/* tigase.db.util.DBSchemaLoader -dbHostname ${HOSTNAME} -dbType ${DB_TYPE} -rootUser ${ROOT_USER} -dbPass ${DB_USER_PASS} -dbName ${DB_NAME} -schemaVersion ${DB_VERSION} -rootPass ${ROOT_USER_PASS} -dbUser ${DB_USER}  -adminJID "${ADMIN_JID}" -adminJIDpass ${ADMIN_JID_PASS}  -logLevel ALL -file database/${DB_TYPE}-schema-upgrade-to-7-1.sql

All variables will be required, they are as follows:

  • ${HOSTNAME} - Hostname of the database you wish to upgrade.

  • ${DB_TYPE} - Type of database [derby, mysql, postgresql, sqlserver].

  • ${ROOT_USER} - Username of root user.

  • ${ROOT_USER_PASS} - Password of specified root user.

  • ${DB_USER} - Login of user that can edit database.

  • ${DB_USER_PASS} - Password of the specified user.

  • ${DB_NAME} - Name of the database to be edited.

  • ${DB_VERSION} - In this case, we want this to be 7.1.

  • ${ADMIN_JID} - Bare JID of a database user with admin privileges. Must be contained within quotation marks.

  • ${ADMIN_JID_PASS} - Password of associated admin JID.

Please note that the SQL file for the update will have an associated database with the filename. i.e. postgresql-update-to-7.1.sql for postgresql database.

A finalized command will look something like this:

java -cp "jars/*" tigase.db.util.DBSchemaLoader -dbHostname localhost -dbType mysql -rootUser root -rootPass root -dbUser admin -dbPass admin -schemaVersion 7.1 -dbName Tigasedb -adminJID "admin@local.com" -adminJIDPass adminpass -logLevel ALL -file database/mysql-schema-upgrade-to-7.1.sql

Once this has successfully executed, you may restart you server. Watch logs for any db errors that may indicate an incomplete schema upgrade.

Changes to Pubsub Schema

Tigase has had a change to the PubSub Schema, to upgrade to PubSub Schema v7.1 without having to reform your databases, use this guide to update your databases to be compatible with the new version of Tigase.

NOTE Current PubSub Schema is v3.3.0, you will need to repeat these instructions for v3.1.0, v3.2.0 and then v3.3.0 before you run Tigase V7.1.0.

The PubSub Schema has been streamlined for better resource use, this change affects all users of Tigase. To prepare your database for the new schema, first be sure to create a backup! Then apply the appropriate PubSub schema to your MySQL and it will add the new storage procedure.

All these files should be in your /database folder within Tigase, however if you are missing the appropriate files, use the links below and place them into that folder.

The MySQL schema can be found Here.

The Derby schema can be found Here.

The PostGRESQL 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.

You can use a utility in Tigase to update the schema using the following command from the Tigase root: Linux

java -cp "jars/*" tigase.db.util.DBSchemaLoader

or from a Windows environment

java -cp jars/* tigase.db.util.DBSchemaLoader

NOTE: Some variation may be necessary depending on how your java build uses -cp option

Use the following options to customize. Options in bold are required.
  • [-dbType database_type {derby, mysql, postgresql, sqlserver}]

  • [-schemaVersion schema version {4, 5, 5-1} ]

  • [-dbName database name]

  • [-dbHostname database hostname] (default is localhost)

  • [-dbUser tigase username]

  • [-dbPass tigase user password]

  • [-rootUser database root username]

  • [-rootPass database root password]

  • [-file path to sql schema file]

  • [-query sql query to execute]

  • [-logLevel java logger Level]

  • [-adminJID comma separated list of admin JIDs]

  • [-adminJIDpass password (one for all entered JIDs]

Arguments take following precedent: query, file, whole schema

As a result your final command should look something like this:

java -cp "jars/*" tigase.db.util.DBSchemaLoader -dbType mysql -dbName tigasedb -dbUser root -dbPass password -file database/mysql-pubsub-schema-3.1.0.sql

9.10.3. Tigase 5.1 Database Schema Upgrade

We had to make a small change to the database schema for Tigase version 5.1.0.

It does not affect data or data structure, only the way in which some data is accessed in database. We added one more stored procedure which has to be installed in database if you upgrade your installation from a previous Tigase version

The schema upgrade is very simple and safe but make sure the current database schema is in version 4.0. If you happen to use ancient version of Tigase earlier than 4.0 and you want to upgrade to 5.1, you have to run 4.0 upgrade script first.

Please follow detailed guide for the database applicable to your installation: Derby, MySQL, PostgreSQL.

10. Components

The only step is to tell the server what components to load, how to name them and optionally give some extra parameters. To do so open the config.tdsl file you use in your installation.

Let’s say you want to just add PubSub for now. All you need to do is add the following to the properties file:

pubsub (class: tigase.pubsub.PubSubComponent) {}

Normally, this is not necessary since pubsub is loaded by default, however this is just an example of loading a class with the DSL format.

'pubsub-priv' (class: tigase.pubsub.PubSubComponent) {}

As you can see, we can customize the name of a component in the deceleration, here we are using pubsub-priv.

Although this may be rare, it allows for wide compatibility and platform stability.

Normally, however we want to load few different components like PubSub, MUC, MSN Transport and so on…​. Therefore instead of the above second PubSub we can load the MUC component:

muc (class: tigase.muc.MUCComponent) {}
pubsub (class: tigase.pubsub.PubSubComponent) {}

Changes to the config.tdsl file will take effect upon server restart.

10.1. HTTP API component

Tigase HTTP API component is a generic container used to provide other HTTP related features as modules. It is configured by default to run under name of http. Installations of Tigase XMPP Server run this component enabled by default under the same name even if not configured.

10.1.1. Available modules

Admin UI module

This is very simple module for administration of Tigase XMPP Server using HTTP browser. It allows administrators to execute ad-hoc commands from HTTP browser allowing to change some configuration options at runtime. It can be accessed by pointing your browser to http://server.address:8080/admin/ and logging in with admin credentials.

Index module

This module is deployed at / by default and provides list of installed and available modules for the virtual host when requested.

REST module

This module provides REST-like API for accessing Tigase XMPP Server. It uses Groovy scripts to process HTTP requests and prepare responses.

Server status module
Warning
This module is still a work in progress!

This module is designed to present current server status and report possible issues.

Setup module

Module is created to act as a web based installer and configuration utility for Tigase XMPP Server. Allows you to modify basic Tigase XMPP Server settings, ie. related to database access. Changes may be saved to configuration file from this module.

Web UI module

This module contains full web client based on Tigase JaXMPP client library allowing user to chat, manage contacts list (roster), browse message archive, etc. For more information on this module, consult the Administration Guide.

10.1.2. Common module configuration

Enabling/disabling module

Every module can be activated or disabled by adjusting it’s activity in following way:

http {
    %module_id% (active: false) {}
}
Note
You need to replace %module_id% with the id of module which you want to change activity (in this case, it will disable module).
Disabling REST module
http {
    rest (active: false) {}
}
Context path

This property allows you to change the context path that is used by module. In other words, it allows you to change the prefix used by module. By default every module (with exception of the Index module) uses a context path that is the same as module id. For example, the REST module ID results in the context path /rest

Changing context path for REST module to /api
http {
    rest {
        context-path = '/api'
    }
}
List of virtual hosts

This provides the ability to limit modules to be available only on listed virtual hosts, and allows to set context path to / for more than one module. Property accepts list of strings, which in the case of config.tdsl file format is list of comma separated domain names and in DSL it is written as list of strings (see Complex Example).

Moving the REST module to be available only for requests directed to api.example.com
http {
    rest {
        vhosts = [ 'api.example.com' ]
    }
}
Complex example

In this example we will disable the Index module and move REST module to http://api.example.com/ and http://rest.example.com.

http {
    index (active: false) {}
    rest {
        context-path = '/'
        vhosts = [ 'api.example.com', 'rest.example.com' ]
    }
}

10.1.3. Module specific configuration

Tigase will try to start a standalone Jetty HTTP server at port 8080 and start up the default modules, including RestModule which will add context for REST API in the /rest path. RestModule will also load all groovy scripts located in scripts/rest/* directories and will bind them to proper actions for the /rest/* paths.

NOTE: Scripts that handle HTTP requests are available in the component repository in src/scriopts/groovy/tigase/rest/ directory.

Tigase’s REST Component comes with two modules that can be enabled, disabled, and configured separately. Common settings for modules for component properties are used in the following format: component_name (module: value) {} the following settings are available for both listed modules:

  • active - Boolean values true/false to enable or disable the module.

  • context-path - Path of HTTP context under which the module should be available.

  • vhosts - Comma separated list of virtual hosts for which the module should be available. If not configured, the module will be available for all vhosts.

Rest Module

This is the Module that provides support for the REST API. Available properties:

  • rest-scripts-dir - Provides ability to specify path to scripts processing REST requests if you do not wish to use default (scripts/rest).

  • api-keys - Comma separated list of strings which would be possible to use as keys to pass api-key parameter to request authorization for request execution. If nothing is passed, then no request will be allowed. To allow any request, this property needs to be set using the following:

This setting is used to provide API-keys that will provide access to the REST module. By default all access to REST module is blocked and nobody can access REST interface.

To allow access for specific clients you should create a list of API keys here and add one of the API keys listed here as the api-key HTTP request parameter sent to server. You can also allow anyone to access REST API by setting this to open_access, however this may leave your server vulnerable.

While configuring the API key, it is possible to set specific api keys for specific domains or vhosts. These API keys will only be valid for the specified vhost and the path that matches the configured value. For example:

Example of API keys
api-keys = [
    'test1',
    'test2:domain=api.example.com;rest.example.com:regex=/rest/*',
    'open_access:regex=/rest/test/.*'
]

does the following:

  1. sets API key test1 which will be valid for any vhost and for any request.

  2. sets API key test2 which will be valid only for requests to vhost api.example.com or rest.example.com and with a path matching the regular expression /rest/*

  3. sets open to everyone access to any domain/vhost with a request path matching the regular expression /rest/test/.*

Requests made to the HTTP service must conclude with one of the listed keys: http://localhost:8080/rest/adhoc/sess-man@domain.com?api-key=test1

Example

Configure API keys for the REST module:

http {
    rest {
        api-keys = [
            'test1',
            'test2:domain=api.example.com;rest.example.com:regex=/rest/*',
            'open_access:regex=/rest/test/.*'
        ]
    }
}
DNS Web Service module

For web based XMPP clients it is not possible to execute DNS SRV requests to find address of XMPP server hosting for particular domain. To solve this the DNS Web Service module was created.

It handles incoming HTTP GET request and using passed domain and callback HTTP parameters executes DNS requests as specified in XEP-0156: Discovering Alternative XMPP Connection Methods. Results are returned in JSON format for easy processing by web based XMPP client.

By default it is deployed at dns-webservice

Parameters
domain

Domain name to look for XMPP SRV client records.

callback

Due to security reasons web based client may not be able to access some DNS Web Service due to cross-domain AJAX requests. Passing optional callback parameter sets name of callback for JSONP requests and results proper response in JSONP format.

Discover way to connect to XMPP server hosting sure.im domain.

Sending HTTP GET request to http://our-xmpp-server:8080/dns-webservice/?domain=sure.im&version=2 you will receive following response:

{
  domain: 'sure.im',
  c2s: [
    {
      host: 'tigase.me',
      ip: ['198.100.157.101','198.100.157.103','198.100.153.203'],
      port: 5222,
      priority: 5
    }
  ],
  bosh: [
    {url:'http://blue.sure.im:5280/bosh'},
    {url:'http://green.sure.im:5280/bosh'},
    {url:'http://orange.sure.im:5280/bosh'}
  ],
  websocket: [
    {url:'ws://blue.sure.im:5290/'},
    {url:'ws://green.sure.im:5290/'},
    {url:'ws://orange.sure.im:5290/'}
  ]
}

As you can see in here we have names and IP address of XMPP servers hosting sure.im domain as well as list of URI for establishing connections using BOSH or WebSocket.

This module is activated by default. However, if you are operating in a test environment where you may not have SRV and A records setup to the domain you are using, you may want to disable this in your config.tdsl file with the following line:

rest {
    'dns-webservice' (active: false) {}
}
Enabling password reset mechanism

It is possible to provide users with a mechanism for a password change in case if they forgot their password to the XMPP account. To do that you need to have tigase-extras.jar in your classpath (it is part of -dist-max distribution package), enable mailer and account-email-password-resetter.

Example configuration
account-email-password-resetter () {}
mailer (class: tigase.extras.mailer.Mailer) {
    'mailer-from-address' = 'email-address@to-send-emails-from'
    'mailer-smtp-host' = 'smtp.email.server.com'
    'mailer-smtp-password' = 'password-for-email-account'
    'mailer-smtp-port' = '587' # Email server SMTP port
    'mailer-smtp-username' = 'username-for-email-account'
}
Note
You need to replace example configuration parameters with correct ones.

With this configuration in place and after restart of Tigase XMPP Server at url http://localhost:8080/rest/user/resetPassword will be available web form which may be used for password reset.

Note
This mechanism will only work if user provided real email address during account registration and if user still remembers and has access to email address used during registration.

10.1.4. Admin UI Guide

The Admin User Interface is an HTTP-based interface that sends REST commands to the server to update configurations, change settings, and retrieve statistics.

A Note about REST

REST stands for REpresentational State Transfer which is a stateless communication method that in our case passes commands using HTTP GET, PUT, POST, and DELETE commands to resources within the Tigase server.

Configuration

Allows you to configure some of the servers settings, such as message of the day, welcome message or initialize shutdown of the cluster node.

Example Scripts

This is a list of script examples that can be run and do menial functions for each component. They may not have particular value themselves, but are present to be used as reference when writing custom scripts. Get list of available commands is one script, that is present for every component that is active on the server, and as its title implies, will provide a list of all commands for that component. Lastly, the two scripts from the Scripting section of this guide. Generally, there is not much needed to see in this section.

Notifications

This section has one simple command: to be able to send a mass message to all logged in users. There are three types of messages that can be sent from this section: - normal Messages will show as a pop-up in most clients. - headline Certain clients will take headline messages and insert them into MUC or chats between users, otherwise it will create a pop-up like normal messages. - chat Chat messages will open up a chat dialog with users.

Other

This section contains a considerable list of options and settings affecting server functions.

Activate log tracker for a user

This allows you to set a log file to track a specific user. Set the bare or full JID of the user you want to log, and a name of the files you wish the log to be written to. The files will be written in the root Tigase directory unless you give a directory like logs/filename. The log files will be named with a .0 extension and will be named .1, .2, .3 and so on as each file reaches 10MB by default. filename.0 will always be the most recent. Logging will start once the command has been issued, and cease once the server restarts.

Add SSL certificate

Here you can add SSL certificates from PEM files to specific virtual hosts. Although Tigase can generate its own self-signed certificates, this will override any default certificates. The certificates cannot contain a passphrase, or be encrypted. Be sure that the contents contain both the certificate and private key data. You also have the option to save the certificate to disk, making the change permanent.

Add listener script

This section allows you to create a custom function for the eventbus component. These scripts can have the server conduct certain operations if set criteria are met. You may write the script in either Groovy or EMCAscript. Please see the eventbus section for more details.

Add Monitor Task

You can write scripts for Groovy or ECMAScript to add to monitor tasks here. This only adds the script to available scripts however, you will need to run it from another prompt. Note that these scripts may only work with the monitor component.

Add Monitor Timer Task

This section allows you to add monitor scripts in Groovy while using a delay setting which will delay the start of the script.

Add New Item - ext

Depending on whether you have any external components loaded or not, this may show. This allows you to add additional external components to the running instance of Tigase.

Add New Item - Vhost

This allows you to add new virtual hosts to the XMPP server. A breakdown of the fields is as follows:

  • Domain name: the full domain name of the new vhost. Tigase will not add anything to this domain, so if it is ti be a subdomain of example.com, you will need to enter sub.domain.com.

  • Enabled: Whether the domain is turned on or off.

  • Anonymous enabled: Allow anonymous logins.

  • In-band registration: Whether or not to allow users to register accounts upon login.

  • TLS required: Require logins to the vhost to conduct a TLS handshake before opening streams.

  • S2S secret: a server-generated code to differentiate traffic between servers, typically there is no need to enter your own, but you may if you need to get into low level code.

  • Domain filter policy: Sets the filter policy for this domain, see This section for a description of the rules.

  • Domain filter domains: a specific setting to restrict or control cross domain traffic.

  • Max users: maximum users allowed to be registered to the server.

  • Allowed C2S, BOSH, Websocket ports: Comma separated list of ports that this vhost will check for all of these services.

  • Presence forward address: specific address where presence information is forwarded too. This may be handy if you are looking to use a single domain for presence processing and handling.

  • Message forward address: Specific address where all messages will be sent too. This may be useful to you if you have a single server handling AMP or message storage and want to keep the load there.

  • Other Parameters: Other settings you may wish to pass to the server, consider this a section for options after a command.

  • Owner: The owner of the vhost who will also be considered an administrator.

  • Administrators: comma separated list of JIDs who will be considered admins for the vhost.

  • XEP-0136 Message Archiving Enabled: Whether to turn on or off this feature.

  • XEP-0136 Required store method: If XEP-0136 is turned on, you may restrict the portion of message that is saved. This is required for any archiving, if null, any portion of the message may be stored.

  • Client certificate required: Whether the client should submit a certificate to login.

  • Client certificate CA: The Certificate Authority of the client certificate.

  • XEP-0136 retention period: integer of number of days message archives will be set.

  • Trusted JIDs: Comma separated list of JIDs who will be added to the trusted list, these are JIDS that may conduct commands, edit settings, or other secure work without needed secure logins.

  • XEP-0136 retention type: Sets the type of data that retention period will use. May be User defined (custom number type), Unlimited, or Number of Days.

  • XEP-0136 - store MUC messages: Whether or not to store MUC messages for archiving. Default is user, which allows users to individually set this setting, otherwise true/false will override.

  • see-other-host redirection enabled: in servers that have multiple clusters, this feature will help to automatically repopulate the cluster list if one goes down, however if this is unchecked, that list will not change and may attempt to send traffic to a down server.

  • XEP-0136 Default store method: The default section of messages that will be stored in the archive.

Change user inter-domain communication permission

Here you can restrict users to be able to communicate on specific domains, this works similar to the domain filtering policy using the same rule sets. For more details, see Domain Based Packet Filtering section for rule details and specifics. Note that the changes may be made to multiple JIDs at the same time.

Connections Time

Lists the longest and average connection time from clients to servers.

Create Node

This section allows you to create a new node for the pubsub component. Here is a breakdown of the fields:

  • The node to create: this is the name of the node that will be created.

  • Owner JID: user JID who will be considered the owner of the node.

  • pubsub#node type: sets the type of node the the new node will be. Options include:

    • leaf Node that can publish and be published too.

    • collection A collection of other nodes.

  • A friendly name for the node: Allows spaces and other characters to help differentiate it from other nodes.

  • Whether to deliver payloads with event notifications: as it says, to publish events or not.

  • Notify subscribers when the configuration changes: default is false

  • Persist items to storage: whether or not to physically store items in the node.

  • Max # of items to persist: Limit how many items are kept in the node archive.

  • The collection with which the node is affiliated: If the node is to be in a collection, place that node name here.

  • Specify the subscriber model: Choose what type of subscriber model will be used for this node. Options include:

    • authorize - Requires all subscriptions to be approved by the node owner before items will be published to the user. Also only subscribers may retrieve items.

    • open - All users may subscribe and retrieve items from the node.

    • presence - Typically used in an instant message environment. Provides a system under which users who are subscribed to the owner JID’s presence with a from or both subscription may subscribe from and retrieve items from the node.

    • roster - This is also used in an instant message environments, Users who are both subscribed to the owners presence AND is placed in specific allowed groups by the roster are able to subscribe to the node and retrieve items from it.

    • whitelist - Only explicitly allowed JIDs are allowed to subscribe and retrieve items from the node, this list is set by the owner/administrator.

  • Specify the Publisher model: Choose what type of publisher model will be used for this node. Options include:

    • open - Any user may publish to this node.

    • publishers - Only users listed as publishers may be able to publish.

    • subscribers - Only subscribers may publish to this node.

  • When to send the last published item: This allows you to decide if and when the last published item to the node may be sent to newly subscribed users.

    • never - Do not send the last published item.

    • on_sub - Send the last published item when a user subscribes to the node.

    • on_sub_and_presence - Send the last published item to the user after a subscription is made, and the user is available.

  • The domains allowed to access this node: Comma separated list of domains for which users can access this node. By default is is blank, and there is no domain restriction.

  • Whether to deliver items to available users only: Items will only be published to users with available status if this is selected.

  • Whether to subscription expired when subscriber going offline: This will make all subscriptions to the node valid for a single session and will need to be re-subscribed upon reconnect.

  • The XSL transformation which can be applied to payloads in order to generate an appropriate message body element: Since you want a properly formatted <body> element, you can add an XSL transformation here to address any payloads or extra elements to be properly formatted here.

  • The URL of the XSL transformation which can be applied to payloads in order to generate an appropriate message body element: This would be the URL of the XSL Transform, e.g. http://www.w3.org/1999/XSL/Transform.

  • Roster groups allowed to subscribe: a list of groups for whom users will be able to subscribe. If this is blank, no user restriction will be imposed.

  • Notify subscribers when owner changes their subscription or affiliation state: This will have the node send a message in the case of an owner changing affiliation or subscription state.

  • Allows get list of subscribers for each subscriber: Allows subscribers to produce a list of other subscribers to the node.

  • Whether to sort collection items by creation date or update time: options include

    • byCreationDate - Items will be sorted by the creation date, i.e. when the item was made.

    • byUpdateTime - Items will be sorted by the last update time, i.e. when the item was last edited/published/etc..

DNS Query

A basic DNS Query form.

Default config - Pubsub

Here you may set the default configuration for any new pubsub node. These changes will be made for all future nodes, but will not affect currently active nodes.

Default room config

This page allows admins to set the default configuration for any new MUC rooms that may be made on the server.

Delete Monitor Task

This removes a monitor task from the list of available monitor scripts. This action is not permanent as it will revert to initial settings on server restart.

Delete Node

Provides a space to remove a node from the server. It must be the full name of the node, and only one node can be removed at a time.

Deleting ALL Nodes

This page allows the logged in admin to delete all nodes from the associated vhost. This change is irreversible, be sure to read and check the box before submitting the command.

Fix User’s Roster

You can fix a users roster from this prompt. Fill out the bare JID of the user and the names you wish to add or remove from the roster. This will NOT edit a user’s roster, but rather compare client roster to database and fix any errors between them.

Fix User’s Roster on Tigase Cluster

This does the same as the Fix User’s Roster, but can apply to users who may not be logged into the local vhost, but are logged into a clustered server.

Get User Roster

As the title implies this gets a users' roster and displays it on screen. You can use a bare or full JID to get specific rosters.

Get any file

Enables you to see the contents of any file in the tigase directory. By default you are in the root directory, if you wish to go into directory use the following format: logs/tigase.log.0

Get Configuration File

If you don’t want to type in the location of a configuration file, you can use this prompt to bring up the contents of either tigase.conf or config.tdsl.

Get config.tdsl File

Will output the current config.tdsl file, this includes any modifications made during the current server session.

Get list available commands

This may be listed multiple times for different components, but this will do as the section suggest and list available commands for that particular component.

Load test

Here you can run a test with the pubsub component on any node to test functionality and proper settings for the node.

Load Errors

Will display any errors the server encounters in loading and running. Can be useful if you need to address any issues.

New command script

This space allows you to create a new command script that will work within the associated component. Note that under the hyperlinked title, there is a listing of muc.server.org or pubsub.server.org, use these to determine where the new command will operate.

OAuth Credentials

This allows the setting of new custom OAuth credentials for the server, and you can also require the use of OAuth tokens for users when they login. This is a setting for the specific host you are logged into. If you are logged into xmpp1.domain.com, it will not affect settings for xmpp2.domain.com.

Pre-Bind BOSH user session

This allows a JID to be paired with a BOSH session before that user logs in, can reduce CPU use if you have a user that logs in via BOSH on a regular basis, or a web client that will regularly connect. You may also specify HOLD and WAIT integers to affect how BOSH operates with the associated JID.

Publish item to node

This window allows you to not only test, but publish an item to the specified node. All fields must be filled in in order to avoid the server dropping an improperly formatted stanza.

Read ALL nodes

This will load a tree of pubsub nodes in memory, it will not output anything as it is mainly for developer use.

Rebuild database

This will force Tigase to rebuild databases for the pubsub component, this may be useful for pubsub subscribers who continue to get pushed events after they unsubscribe.

Reload component repository

This will reload any vhosts that the server is running. This may be useful if one is disconnected or broken during runtime.

Remove an item

This will remove a running vhost from the server, you will be presented with a list to pick from.

Remove command script

Like new command script, take a look at the subheading to determine which component you want to remove the script from. Once there, select the command you wish to remove from the server. If remove from disk is selected, then the change will be permanent. Otherwise, the command will be removed until the next server restart.

Remove listener script

Select from a list the listener script you wish to remove. This will only affect custom listener scripts added to the eventbus component.

Remove room

This provides fields to remove a room from the MUC component. you may suggest an alternative room which will move occupants to the alternative room once the current one is removed.

Retrieve items

Here you can retrieve items from PubSub nodes, this simulates the get IQ stanza from the pubsub component. - Service name - The address of the pubsub component. - Node name - Item node to retrieve items from. - Item ID - The item ID of the item you wish to retrieve. - Items Since - UTC timestamp to start search from: YYYY-MM-DDTHH:MM:SSZ

S2S Bad State Connections

This will list any connections to other servers that are considered bad or stale. This will populate very rarely as Tigase automatically adjusts around clustered servers that go down. In the event a connection stays bad, it is recommended to reset those connections in the next space.

S2S Reset Bad State Connections

This will reset the connections with other servers that are considered bad and have shown up in the S2S Bad State Connections page.

S2S Get CID Connection State

For internal developer use only.

Subscribe to a node

This provides a space for an administrator to manually have a JID subscribe to a particular node.

Unsubscribe from node

Here you can unsubscribe users from a particular node. Users can be a comma separated list.

Update item configuration

Typically you will see only one item for vhost-man, but some additional components (ie. ext) may provided them as well. They each have their own sections, but provide for a plethora of server options. Changes to the server are done in real time, and may not be permanent.

vhost-man

You will be presented with a list of domains that Tigase is currently hosting, you will be able to change settings for one domain at a time using this function. Once a domain is selected, you will be able to set or change the following settings:

  • Domain name: the full domain name of the new vhost. Tigase will not add anything to this domain, so if it is ti be a subdomain of example.com, you will need to enter sub.domain.com.

  • Enabled: Whether the domain is turned on or off.

  • Anonymous enabled: Allow anonymous logins.

  • In-band registration: Whether or not to allow users to register accounts upon login.

  • TLS required: Require logins to the vhost to conduct a TLS handshake before opening streams.

  • S2S secret: a server-generated code to differentiate traffic between servers, typically there is no need to enter your own, but you may if you need to get into low level code.

  • Domain filter policy: Sets the filter policy for this domain, see This section for a description of the rules.

  • Domain filter domains: a specific setting to restrict or control cross domain traffic.

  • Max users: maximum users allowed to be registered to the server.

  • Allowed C2S, BOSH, Websocket ports: Comma separated list of ports that this vhost will check for all of these services.

  • Presence forward address: specific address where presence information is forwarded too. This may be handy if you are looking to use a single domain for presence processing and handling.

  • Message forward address: Specific address where all messages will be sent too. This may be useful to you if you have a single server handling AMP or message storage and want to keep the load there.

  • Other Parameters: Other settings you may wish to pass to the server, consider this a section for options after a command.

  • Owner: The owner of the vhost who will also be considered an administrator.

  • Administrators: comma separated list of JIDs who will be considered admins for the vhost.

  • XEP-0136 Message Archiving Enabled: Whether to turn on or off this feature.

  • XEP-0136 Required store method: If XEP-0136 is turned on, you may restrict the portion of message that is saved. This is required for any archiving, if null, any portion of the message may be stored.

  • Client certificate required: Whether the client should submit a certificate to login.

  • Client certificate CA: Client Certificate Authority.

  • XEP-0136 retention period: Integer of number of days message archives will be set.

  • Trusted JIDs: Comma separated list of JIDs who will be added to the trusted list, these are JIDS that may conduct commands, edit settings, or other secure work without needed secure logins.

  • XEP-0136 retention type: Sets the type of data that retention period will use. May be User defined (custom number type), Unlimited, or Number of Days.

  • XEP-0136 - store MUC messages: Whether or not to store MUC messages for archiving. Default is user, which allows users to individually set this setting, otherwise true/false will override.

  • see-other-host redirection enabled: in servers that have multiple clusters, this feature will help to automatically repopulate the cluster list if one goes down, however if this is unchecked, that list will not change and may attempt to send traffic to a down server.

  • XEP-0136 Default store method: The default section of messages that will be stored in the archive.

Update user roster entry

This section allows admins to edit individual users rosters, although it provides similar functionality to fix users roster, this is designed for precision editing of a user roster.

  • Roster owner JID: The BareJID of the user roster you wish to edit.

  • JID to manipulate: The specific BareJID you want to add/remove/change.

  • Comma separated groups: Groups you wish to add the JID too.

  • Operation Type: What function will be performed?

    • Add - Add the JID to manipulate to the owner JID’s roster and groups.

    • Remove - Remove the JID to manipulate from the owner JID’s roster and groups.

  • Subscription type: The type of subscription stanza that will be sent to the server, and subsequently between the two users will be employed.

    • None - Select this if neither the owner or the user to be manipulated wishes to receive presence information.

    • From - The Roster Owner will not receive presence information from the JID to manipulate, but the opposite will be true.

    • To - The JID to manipulate will not receive presence information from the Roster Owner, but the opposite will be true.

    • Both - Both JIDs will receive presence information about each other.

Update user roster entry extended version

This section is an expanded version of the previous one, all fields already specified are the same with these additions:

  • Roster owner name: A friendly name or nickname if you wish to change/create one. not required

  • Comma separated of owner groups: Groups that the user wants to join/leave. not required

  • Roster item JID: The specific JID that needs to be edited.

  • Roster item name: A friendly name or nickname that will be changed/created. not required

  • Comma separated list of item groups: A group or list of groups that the roster item JID will be added to/removed from.

  • Action:

    • Add/update item - Will add or update the item JID in the roster owner’s roster.

    • Remove item - Will remove the item JID from the roster owner’s roster.

    • Add/update both rosters - Will add or update the item in both roster owner and roster item’s roster.

    • Remove from both rosters - Will remove the item from both roster owner and roster item’s roster.

Scripts

This section will enable administrators to custom write or enter their own scripts for specific components. Each active component will have an entry for new and remove command scripts and scripts written there will be for that component.

New Command Script
  • Description: A friendly name of the script, will be the title of the link in the menu on the left.

  • Command ID: Internal command that Tigase will use when referencing this script.

  • Group: The group for the script, which may be any of the headings on the left (Configuration, Example scripts, Notifications, Other etc..) or your own. If no group exists, a new one will be created.

  • Language: The language the script is written in. Currently Tigase supports Groovy and EMCAScript.

  • Script text: the fulltext of the script.

  • Save to disk: Scripts that are saved to disk will be permanently stored in the server’s directory /scripts/admin/[Component]/commandID.js NOTE Scripts that are NOT saved to disk will not survive a server restart.

Remove Command Script

As with New Command Script, there is an entry for each component. This page will provide a space to remove commands for the selected component. You will be provided a list of scripts associated with that component. You also have the open to remove from disk, which will permanently delete the script from the hard drive the server is on. If this is unchecked, the script will be unavailable until the next restart.

Statistics

This section is more useful to test statistics scripts and components, as many of them produce very small amounts of information, however these may be collected by other components or scripts for a better information display.

Get User Statistics

Provides a script output of user statistics including how many active sessions are in use, number of packets used, specific connections and their packet usage and location. All resources will return individual stats along with IP addresses.

Get Active User List

Provides a list of active users under the selected domain within the server. An active user is considered a user currently logged into the XMPP server.

Get list of idle users

Provides a list of users who are idle on the server.

Get list of online users

Provides a list of users who are currently online.

Get number of active users

Provides a list of active users, users who are not idle or away.

Get number of idle users

Provides a number of idle users.

Get top active users

Will produce a list of user-limited users who are considered most active in packets sent.

Users
Add User

Here you can add new users to any domain handled by vHosts, users are added to database immediately and are able to login. NOTE: You cannot bestow admin status to these users in this section.

Change User Password

This enables you to change the password of any user in the database. Although changes will take effect immediately, users currently logged in will not know the password has been changed until they try to log in again.

Delete User

This removes the user or users (comma separated) from the database. The deleted users will be kicked from the server once submit is clicked.

End user session

Disconnects the current selected user by ending their session with the server.

Get User Info

This section allows admins to get information about a specific user including current connections as well as offline and online messages awaiting delivery.

Get registered user list

This will display all registered users for the selected domain up to the number specified.

Modify User

Allows you to modify some user details including E-mail and whether it is an active user.

10.1.5. Tigase Web Client

Tigase now has a fully featured XMPP client built right into the HTTP interface. Everything you would expect from an XMPP client can now be done from the comfort of your browser window with no software install required!

The web client is active and available by default on servers v7.2.0 and later.

To access the client, point a browser to the following address: xmpp.your-server.net:8080/ui/

It will ask you for a login, any bare JID of users registered with the server will work. NOTE: Use your bare JID for login

Once you have logged in successfully, you will be presented with the following screen.

WebUI-Home

The commands are broken into categories shown here. All changes made in these sections are instant and should be seen the same as if you were using an external XMPP client like Psi.

NOTE The BOSH client will automatically translate all requests to the server name. In some rare cases this may not be resolvable by the browser and you will be unable to login. Should that happen, you may disable that feature using the following line in your config.tdsl:

bosh {
    'send-node-hostname' = false
}

You may have to specifically designate the bosh URL when using the advanced tag in the login screen.

Chat

This is the default window, and your main interface for chatting inside XMPP with this server. NOTE: you can only communicate to users logged onto the current server, or connected clusters Users from your roster will be on the left panel, the right all active discussions and MUCs, as well as the currently selected chat will be available.

WebUI-Chat

Users that are logged in and on your roster will be displayed on the left side. Double-clicking will bring up a new chat window with the user. You can Right-click on them to bring up a sub menu with the following;

WebUI-Usersubmenu

  • Chat replicates a double-click and opens a new window for chat.

  • Modify brings up a dialogue that allows you to change the JID of the contact, a nickname, and group.

  • Delete removes the user from your roster. This will also remove subscription authorization for the selected user to receive presence information effectively removing you from their roster. NOTE: this will not block user packets from your JID

  • Info brings up the User Info (this is the disco#info command for the selected user)

The top right section has a few icons with specific functionality, they are;

WebUI-Chat-Add-New adds a new user to your roster.

WebUI-Chat-NewMUC creates a new Multi-user chatroom.

WebUI-Chat-Profile allows you to edit your user information such as picture and nickname.

WebUI-Chat-CloseWindow closes the active chat window.

WebUI-Chat-settings provides a place to change your password or publish changes to your user info. NOTE: you are limited to changing the General fields

Discovery

This is your service discovery panel, which breaks down by component in the sidebar. Each component name and its associated JID is listed to help you find what you need. Most components give you an option to Execute commands with a few exceptions allowing browsing and the ability to join a MUC.

Browse allows you to dig deeper into certain components; for example list the chatrooms available in the MUC component. At the top of the page the specific JID of the component are you in will be displayed. This is a text field, and can be edited to reflect the JID of the component (or just the server name) to navigate.

WebUI-Browse-Comp

Join to Room will join you to a MUC room that is selected. Alternatively, selecting Join to Room while MUC component is selected, you can join and start a new MUC room.

Execute Command Provides a hierarchy of commands and options to view and edit settings, run commands and scripts, view contents of files, and see statistics. Since each Component can have a unique structure it is best to explore each to see what options are available.

Management

This is an advanced window for settings and management for the XMPP server.

Configuration

Here you can manage some of the server settings.

Notifications

This section has one simple command: to be able to send a mass message to all logged in users. You may choose to change the type of message to headline or Normal which will show as a pop-up in most XMPP clients. Chat messages will open up a chat dialog with users.

Other

This section contains a considerable list of options and settings affecting server functions.

Activate log tracker for a user

This allows you to set a log file to track a specific user. Set the bare or full JID of the user you want to log, and a name of the files you wish the log to be written to. The files will be written in the root Tigase directory unless you give a directory like logs/filename. The log files will be named with a .0 extension and will be named .1, .2, .3 and so on as each file reaches 10MB by default. filename.0 will always be the most recent. Logging will cease once the server restarts.

Add SSL certificate

Here you can add SSL certificates from PEM files to specific virtual hosts. Although Tigase can generate its own self-signed certificates, this will override those default certificates.

Add Monitor Task

You can write scripts for Groovy or ECMAScript to add to monitor tasks here. This only adds the script to available scripts however, you will need to run it from another prompt.

Add Monitor Timer Task

This section allows you to add monitor scripts in Groovy while using a delay setting which will delay the start of the script.

Add New Item - ext

Provides a method to add external components to the server. By default you are considered the owner, and the Tigase load balancer is automatically filled in.

Add New Item - Vhost

This allows you to add new virtual hosts to the XMPP server. A breakdown of the fields is as follows:

  • Domain name: the full domain name of the new vhost. Tigase will not add anything to this domain, so if it is ti be a subdomain of example.com, you will need to enter sub.domain.com.

  • Enabled: Whether the domain is turned on or off.

  • Anonymous enabled: Allow anonymous logins.

  • In-band registration: Whether or not to allow users to register accounts upon login.

  • TLS required: Require logins to the vhost to conduct a TLS handshake before opening streams.

  • S2S secret: a server-generated code to differentiate traffic between servers, typically there is no need to enter your own, but you may if you need to get into low level code.

  • Domain filter policy: Sets the filter policy for this domain, see This section for a description of the rules.

  • Domain filter domains: a specific setting to restrict or control cross domain traffic.

  • Max users: maximum users allowed to be registered to the server.

  • Allowed C2S, BOSH, Websocket ports: Comma separated list of ports that this vhost will check for all of these services.

  • Presence forward address: specific address where presence information is forwarded too. This may be handy if you are looking to use a single domain for presence processing and handling.

  • Message forward address: Specific address where all messages will be sent too. This may be useful to you if you have a single server handling AMP or message storage and want to keep the load there.

  • Other Parameters: Other settings you may wish to pass to the server, consider this a section for options after a command.

  • Owner: The owner of the vhost who will also be considered an administrator.

  • Administrators: comma separated list of JIDs who will be considered admins for the vhost.

  • XEP-0136 Message Archiving Enabled: Whether to turn on or off this feature.

  • XEP-0136 Required store method: If XEP-0136 is turned on, you may restrict the portion of message that is saved. This is required for any archiving, if null, any portion of the message may be stored.

  • Client certificate required: Whether the client should submit a certificate to login.

  • Client certificate CA: The Certificate Authority of the client certificate.

  • XEP-0136 retention period: integer of number of days message archives will be set.

  • Trusted JIDs: Comma separated list of JIDs who will be added to the trusted list, these are JIDS that may conduct commands, edit settings, or other secure work without needed secure logins.

  • XEP-0136 retention type: Sets the type of data that retention period will use. May be User defined (custom number type), Unlimited, or Number of Days.

  • XEP-0136 - store MUC messages: Whether or not to store MUC messages for archiving. Default is user, which allows users to individually set this setting, otherwise tue/false will override.

  • see-other-host redirection enabled: in servers that have multiple clusters, this feature will help to automatically repopulate the cluster list if one goes down, however if this is unchecked, that list will not change and may attempt to send traffic to a down server.

  • XEP-0136 Default store method: The default section of messages that will be stored in the archive.

Change user inter-domain communication permission

You can restrict users to only be able to send and receive packets to and from certain virtual hosts. This may be helpful if you want to lock users to a specific domain, or prevent them from getting information from a statistics component.

Connections Time

Lists the longest and average connection time from clients to servers.

DNS Query

A basic DNS Query form.

Default config - Pubsub

This section enables you to change the default pubsub node configuration for all future nodes. Note: these changes will be reset on server restart. - pubsub#node type: sets the type of node the the new node will be. Options include:

  • leaf Node that can publish and be published too.

  • collection A collection of other nodes.

    • A friendly name for the node: Allows spaces and other characters to help differentiate it from other nodes.

    • Whether to deliver payloads with event notifications: as it says, to publish events or not.

    • Notify subscribers when the configuration changes: default is false

    • Persist items to storage: whether or not to physically store items in the node.

    • Max # of items to persist: Limit how many items are kept in the node archive.

    • The collection with which the node is affiliated: If the node is to be in a collection, place that node name here.

    • Specify the subscriber model: Choose what type of subscriber model will be used for this node. Options include:

  • authorize - Requires all subscriptions to be approved by the node owner before items will be published to the user. Also only subscribers may retrieve items.

  • open - All users may subscribe and retrieve items from the node.

  • presence - Typically used in an instant message environment. Provides a system under which users who are subscribed to the owner JID’s presence with a from or both subscription may subscribe from and retrieve items from the node.

  • roster - This is also used in an instant message environments, Users who are both subscribed to the owners presence AND is placed in specific allowed groups by the roster are able to subscribe to the node and retrieve items from it.

  • whitelist - Only explicitly allowed JIDs are allowed to subscribe and retrieve items from the node, this list is set by the owner/administrator.

    • Specify the Publisher model: Choose what type of publisher model will be used for this node. Options include:

  • open - Any user may publish to this node.

  • publishers - Only users listed as publishers may be able to publish.

  • subscribers - Only subscribers may publish to this node.

    • When to send the last published item: This allows you to decide if and when the last published item to the node may be sent to newly subscribed users.

  • never - Do not send the last published item.

  • on_sub - Send the last published item when a user subscribes to the node.

  • on_sub_and_presence - Send the last published item to the user after a subscription is made, and the user is available.

    • The domains allowed to access this node: Comma separated list of domains for which users can access this node. If left blank there is no domain restriction.

    • Whether to deliver items to available users only: Items will only be published to users with available status if this is selected.

    • Whether to subscription expired when subscriber going offline: This will make all subscriptions to the node valid for a single session and will need to be re-subscribed upon reconnect.

    • The XSL transformation which can be applied to payloads in order to generate an appropriate message body element: Since you want a properly formatted <body> element, you can add an XSL transformation here to address any payloads or extra elements to be properly formatted here.

    • The URL of the XSL transformation which can be applied to payloads in order to generate an appropriate message body element: This would be the URL of the XSL Transform, e.g. http://www.w3.org/1999/XSL/Transform.

    • Roster groups allowed to subscribe: a list of groups for whom users will be able to subscribe. If this is blank, no user restriction will be imposed.

    • Notify subscribers when owner changes their subscription or affiliation state: This will have the node send a message in the case of an owner changing affiliation or subscription state.

    • Allows get list of subscribers for each subscriber: Allows subscribers to produce a list of other subscribers to the node.

    • Whether to sort collection items by creation date or update time: options include

  • byCreationDate - Items will be sorted by the creation date, i.e. when the item was made.

  • byUpdateTime - Items will be sorted by the last update time, i.e. when the item was last edited/published/etc..

Default room config

Allows you to set the default configuration for new MUC rooms. This will not be able to modify current in use and persistent rooms.

Delete Monitor Task

This removes a monitor task from the list of available monitor scripts. This action is not permanent as it will revert to initial settings on server restart.

Fix User’s Roster

You can fix a users roster from this prompt. Fill out the bare JID of the user and the names you wish to add or remove from the roster. You can edit a users roster using this tool, and changes are permanent.

Fix User’s Roster on Tigase Cluster

This does the same as the Fix User’s Roster, but can apply to users in clustered servers.

Get User Roster

As the title implies this gets a users' roster and displays it on screen. You can use a bare or full JID to get specific rosters.

Get any file

Enables you to see the contents of any file in the tigase directory. By default you are in the root directory, if you wish to go into directory use the following format: logs/tigase.log.0

Get Configuration File

If you don’t want to type in the location of a configuration file, you can use this prompt to bring up the contents of either tigase.conf or config.tdsl.

Get config.tdsl File

Will output the current config.tdsl file, this includes any modifications made during the current server session.

Load Errors

Will display any errors the server encounters in loading and running. Can be useful if you need to address any issues.

New command script - Monitor

Allows you to write command scripts in Groovy and store them physically so they can be saved past server restart and run at any time. Scripts written here will only be able to work on the Monitor component.

New command script - MUC

Allows you to write command scripts in Groovy and store them physically so they can be saved past server restart and run at any time. Scripts written here will only be able to work on the MUC component.

OAUth credentials

Uses OAuth to set new credentials and enable or disable a registration requirement with a signed form.

Pre-Bind BOSH user session

Allows admins to pre-bind a BOSH session with a full or bare JID (with the resource automatically populated on connection). You may also specify HOLD or WAIT parameters.

Reload component repository

This will show if you have any external components and will reload them in case of any stuck threads.

Scripts

This section provides a list of command scripts for all active components. Each component has the following options - New command script provides a method to author new command scripts for specific components written in EMCAScript or Groovy. You do have an option to save the script to disk which will make the script permanent within the server. - Remove command script allows you to remove the selected script from the repository. If Remove from disk is not checked, the script will be unavailable until server restart. If it is, it will be permanently removed from the server.

Newly made commands will be listed under the Group listing in the left column.

Statistics

These statistics might be more useful as script results yield small bits of data, but you may find them useful when looking for server loads or finding user issues.

Get User Statistics

Provides a script output of user statistics including how many active sessions are in use, number of packets used, specific connections and their packet usage and location. All resources will return individual stats along with IP addresses.

Get Active User List

Provides a list of active users under the selected domain within the server. An active user is considered a user currently logged into the XMPP server.

Get list of idle users

This will list all idle users separated by vhost.

Get list of online users

This will list users separated by the vhost they are connected to. The list will include the bare JID as well as any resources for that JID.

Get number of active users

This displays the number of current active users.

Get number of idle users

This section returns the number of active users per specific vhost.

Get top active users

This will list the top number of active users by packets sent and online time. This list will only be built with users currently online and from all vhosts.

Users
Add New User

Here you can add new users to any domain handled by vHosts, users are added to database immediately and are able to login. NOTE: You cannot bestow admin status to these users in this section.

Change user password

Allows for admins to change the password of a specific user without needing to know the original password for the selected bare JID. Users currently logged in will not know password has been changed until they attempt to re-login.

Delete user

Provides a text window for admins to input the bare JID of the user they wish to remove from the server.

Get User Info

This section allows admins to get information about a specific user including current connections as well as offline and online messages awaiting delivery.

Get registered user list

Provides a list of vhosts to search and a maximum number of users to list. Once run, the script will display a list of registered bare JIDs of users from the selected vhost.

Modify User

Allows you to modify some user details including E-mail and whether it is an active user.

10.2. HTTP File Upload component

Tigase’s HTTP File Upload component is an implementation of XEP-0363 HTTP File Upload specification. This allows file transfer between XMPP clients by uploading a file to HTTP server and sending only link to download file to recipient.

This implementation makes use of the HTTP server used by Tigase XMPP Server and Tigase HTTP API component to provide web server for file upload and download.

By default this component is disabled and needs to be enabled in configuration file before it can be used. Another requirement is that the proper database schema needs to be applied to database which will be used by component.

10.2.1. Enabling HTTP File Upload Component

Configuration
upload() {}

10.2.2. Metadata repository

Running the component requires a repository where it can store information about allocated slots. For this, a metadata repository is used. It is possible to specify a specific implementation of FileUploadRepository for every domain.

By default, metadata for all domains will be stored in the default repository. Implementation of which will be selected based on kind of data source defined as default.

DummyFileUploadRepository

This is very simple repository which does not store any data. Due to that, it can be very fast! However, it is not able to remove old uploads and apply any upload limits.

JDBCFileUploadRepository

This repository implementation stores data in database used to store procedures and functions. By default, data should be stored in the tig_hfu_slots table but it can be changed by modification of stored procedures or reconfiguration of the repository implementation to use different stored procedures and functions than provided.

10.2.3. Storage

Component contains a pluggable storage mechanism, which means that it is relatively easy to implement custom storage provisions. By default DirectoryStore based storage is used.

Currently following storage providers are available out of the box.

DirectoryStore

This storage mechanism places files in subdirectories with names that correspond to the id of allocated slot. If required, it is possible to group all slot directories allocated by single user in a directory containing this user name.

By default there is no redundancy if this store is used in clustered environment. Every file will be stored on a single cluster node.

Available properties:

path

Contains path to directory in which subdirectory with files will be created on the local machine. (default: data/upload)

group-by-user

Configures if slots directories should be grouped in user directories. (default: false)

10.2.4. Logic

Logic is responsible for generation of URI and applying limits. It groups all configuration settings related to allocation of slots, etc.

Available properties:

local-only

Allow only users with accounts on the local XMPP server to use this component for slot allocation. (default: true)

max-file-size

Set maximum size of a single allocated slot (maximum file size) in bytes. (default: 5000)

port

Specifies the port which should be used in generating the upload and download URI. If it is not set, then secured (HTTPS) server port will be used if available, and plain HTTP in other case. (default: not set)

protocol

Protocol which should be used. This is only used in conjunction with port. Possible values are:

  • http

  • https

serverName

Server name to use as domain part in generated URI. (default: server hostname)

upload-uri-format

Template used in generation of URI for file upload. (default: {proto}://{serverName}:{port}/upload/{userJid}/{slotId}/{filename})

download-uri-format

Template used in generation of URI for file download. (default: {proto}://{serverName}:{port}/upload/{slotId}/{filename})

URI template format

Every block in the template between { and } is a named part which will be replaced by the property value during generation of URI for slot.

Blocks possible to use:

proto

Name of protocol.

serverName

Domain name of server.

port

Port on which HTTPS (or HTTP) server is listening.

userJid

JID of user requesting slot allocation.

domain

Domain of user requesting slot allocation.

slotId

Generated ID of slot.

filename

Name of file to upload.

Note
slotId and filename are required to be part of every URI template.
Warning
Inclusion of userJid or domain will speed up the lookup for slot id during upload and download operation if more than one metadata repository is configured. However, this may lead to leak of user JID or user domain if message with URI containing this part will be send to recipient which is unaware of the senders' JID (ie. in case of anonymous MUC room).

10.2.5. File upload expiration

From time to time it is required to remove expired file to make place for new uploads. This is done by the expiration task.

Available properties:

expiration-time

How long the server will keep uploaded files. Value in Java Period format (default: P30D - 30 days)

period

How often the server should look for expired files to remove. Value in Java Period format (default: P1D - 1 day)

delay

Time since server start up before the server should look for expired files to remove. Value in Java Period format (default: 0)

limit

Maximum number of files to remove during a single execution of expiration. (default: 10000)

10.2.6. Examples

Complex configuration example

Configuration with a separate repository for metadata to example.com pointing to file_upload data source, custom upload and download URI, maximum file size set to 10MB, expiration done every 6 hours and grouping of slot folders by user jid.

Complex configuration example
upload() {
    logic {
        local-only = false
        max-file-size = 10485760
        upload-uri-format = '{proto}://{serverName}:{port}/upload/{userJid}/{slotId}/{filename}'
        download-uri-format = '{proto}://{serverName}:{port}/upload/{domain}/{slotId}/{filename}'
    }

    expiration {
        period = P6H
    }

    repositoryPool {
        'example.com' () {
            data-source = "file_upload"
        }
    }

    store {
        group-by-user = true
    }
}
Example configuration for clustering with HA

Configuration for high availability in a cluster with common storage at /mnt/shared and both servers available as upload.example.com

Example configuration with HA
upload() {
    logic {
        upload-uri-format = '{proto}://upload.example.com:{port}/upload/{userJid}/{slotId}/{filename}'
        download-uri-format = '{proto}://upload.example.com:{port}/upload/{domain}/{slotId}/{filename}'
    }

    store {
        path = '/mnt/shared/upload'
    }
}

10.3. HTTP server

HTTP server instance is provided as httpServer by default. The server will only be active and enabled if either the HTTP API component or HTTP File Upload component is enabled. This project uses the default implementation of an http server provided by HttpServer found embedded in Java JDK.

Note
This implementation is good only for small installations of if there is no requirement for a high performance HTTP server. If this is do not match your requirements, it is recommended to use Jetty as the embedded HTTP server using Tigase HTTP API - Jetty HTTP Server project.

10.3.1. Dependencies

The default HTTP server implementation requires almost no dependencies as most calls are already embedded within JDK 8. However as a common API for processing HTTP requests is needed, as is the same for HTTP server from JDK and Jetty, we have decided to use HTTP Servlet API in version 3.1.

The required files can be downloaded from Tigase HTTP API project section or using following link servlet-api-3.1.jar

Please note that this file is included in dist-max, exe, and jar installer distributions of Tigase XMPP server.

10.3.2. Configuration Properties

The HTTP server can be configured using any of all of the following properties. Note that these settings only apply to the default implementation provided by Tigase HTTP API.

ports

This property is used to configure on which ports on HTTP server should listen for incoming connections. If it is not set then default port 8080 will be used

connections

It is used to group configurations passed to ports

{port}

For every {port} you can pass separate configuration. To do so you will need to replace {port} with port number, ie. 8080. For every port you can pass following properties:

socket

Sets type of socket used for handling incoming connections. Accepted values are:

  • plain - port will work in plain HTTP mode (default)

  • ssl - port will work in HTTPS mode

domain

This property is used to configure domain name of SSL certificate which should be used by HTTP server running on this port (if socket is set to ssl). If it is not set (or it will be omitted) then Tigase XMPP Server will try to use SSL certificate for the host to which client tries to connect. If there will be no SSL certificate for that domain name, then default SSL certificate of Tigase XMPP Server will be used.

Additional properties of embedded HTTP server

With embedded HTTP server, you have a few additional properties within executor section, which you can pass to adjust this HTTP server.

executor

Name of the subsection

threads

This property is used to configure the number of threads used to handle HTTP requests, ie. 10

request-timeout

Property used to set timeout for processing a single HTTP request (in milliseconds), ie. 30000

accept-timeout

Property used to set timeout for reading HTTP request headers (in milliseconds), ie. 2000

10.3.3. Examples

Below are few examples for use in DSL based configuration format and older properties based format.

HTTPS on port 8443 with SSL certificate for example.com

In configuration file httpServer related configuration should look like this:

httpServer {
    connections {
        8443 () {
            socket = ssl
            domain = 'example.com'
        }
    }
}
Changing port from 8080 to 8081
httpServer {
    connections {
        8080 (active: false) {}
        8081 () {}
    }
}
Usage of Jetty HTTP server as HTTP server

As mentioned before it is possible to use Jetty as HTTP server for improved performance. Jetty API can be used in one of two forms: Standalone and OSGi.

Standalone

In this case the Jetty instance is created and configured internally by Tigase HTTP API. This allows for the same configuration properties used as for default HTTP server configuration.

Configuration with use of standalone Jetty HTTP Server
httpServer (class: tigase.http.jetty.JettyStandaloneHttpServer) {
    ...
}
OSGi

This can only be used when Tigase is running inside OSGi container. If this is used Tigase HTTP API will try to retrieve Jetty HTTP server from OSGi container and use it.

Note
Jetty HTTP server instance is not configured by Tigase. We would only use this instance for deployment.
Configuration in OSGi mode with use of Jetty HTTP Server
httpServer (class: tigase.http.jetty.JettyOSGiHttpServer) {
    ...
}

10.4. Tigase Message Archiving Component

Tigase Team <team@tigase.net> :toc: :numbered: :website: http://tigase.net :Date: 2016-11-11

Welcome to Tigase Message Archiving component guide

10.4.1. Tigase Message Archiving Component

Tigase Message Archiving Component originated as implementation of XEP-0136: Message Archiving to add support for archiving of messages exchanged using Tigase XMPP Server. In current version component supports also XEP-0313: Message Archive Management specification to allow easier access to archived messages.

10.4.2. Announcement

Major changes

Tigase Message Archiving component has undergone a few major changes to our code and structure. To continue to use Tigase Message Archiving component, a few changes may be needed to be made to your systems. Please see them below:

Database schema changes

We decided to no longer use in-code database upgrade to update database schema of Message Archiving component and rather provide separate schema files for every supported database.

Additionally we moved from in-code generated SQL statements to stored procedures which are now part of provided database schema files.

To continue usage of new versions of Message Archiving component it is required to manually load new component database schema, see Preparation of database section for informations about that.

Warning
Loading of new database schema is required to use new version of Message Archiving component.
New features
Support for Message Archive Management protocol

Now Tigase Message Archiving component supports searching of archived message using XEP-0313: Message Archive Management protocol.

For details on how to enable this feature look into Support for MAM

Support for using separate database for different domains

Since this version it is possible to use separate archived messages based on domains. This allows you to configure component to store archived message for particular domain to different database.

For more informations please look into Using separate store for archived messages

10.4.3. Additional features

Tigase Message Archiving Component contains few additional features useful for working with message archives.

Querying in all messages

Feature allows user to search all of his archived messages without a need to specify who was send/receiver of this message. To search in all messages, request sent to retrieve archived messages should not contain with attribute. As a result, when with attribute is omitted <chat/> element of response will not contain with attribute but every <to/> and <from/> element will contain with attribute.

Querying by part of message body

This feature allows user to query for messages or collections containing messages which in body of a message contained text passed by user.

To execute request in which user wants to find messages with "test failed" string XMPP client needs to add following element

<query xmlns="http://tigase.org/protocol/archive#query">
    <contains>test failed</contains>
</query>

as child element of @retrieve@ or @list@ element of request.

Example query requests
Example 1

Retrieving messages with "test failed" string with user juliet@capulet.com between 2014-01-01 00:00:00 and 2014-05-01 00:00:00

<iq type="get" id="query2">
    <retrieve xmlns='urn:xmpp:archive'
        with='juliet@capulet.com'
        from='2014-01-01T00:00:00Z'
        end='2014-05-01T00:00:00Z'>
          <query xmlns="http://tigase.org/protocol/archive#query">
              <contains>test failed</contains>
          </query>
    </retrieve>
</iq>
Example 2

Retrieving collections containing messages with "test failed" string with user juliet@capulet.com between 2014-01-01 00:00:00 and 2014-05-01 00:00:00

<iq type="get" id="query2">
    <list xmlns='urn:xmpp:archive'
        with='juliet@capulet.com'
        from='2014-01-01T00:00:00Z'
        end='2014-05-01T00:00:00Z'>
          <query xmlns="http://tigase.org/protocol/archive#query">
              <contains>test failed</contains>
          </query>
    </list>
</iq>
Querying by tags

This feature adds support for tagging messages archived by Message Archiving component and by default is disabled (to learn how to enable this feature please see Enabling support for tags section).

Tagging can be done only by user sending message as to tag message tag needs to be included in message content (message body to be exact).

Currently there are 2 types of tags supported:

  • hashtag - words prefixed by "hash" (#) are stored with prefix and used as tag, i.e. #Tigase

  • mention - words prefixed by "at" (@) are stored with prefix and used as tag, i.e. @Tigase

Custom feature allows user to query/retrieve messages or collections from archive only containing particular tag or tags. To execute request in which user wants to retrieve only messages tagged with @User1 and #People XMPP client executing request needs to add following element as child element of <retrieve/> element or <list/> element:

<query xmlns="http://tigase.org/protocol/archive#query">
    <tag>#People</tag>
    <tag>@User1</tag>
</query>
Querying/retrieving list of messages or collections
Example 1

Request to retrieve messages tagged with @User1 and #People from chat with user juliet@capulet.com between 2014-01-01 00:00:00 and 2014-05-01 00:00:00

<iq type="get" id="query2">
    <retrieve xmlns='urn:xmpp:archive'
        with='juliet@capulet.com'
        from='2014-01-01T00:00:00Z'
        end='2014-05-01T00:00:00Z'>
          <query xmlns="http://tigase.org/protocol/archive#query">
              <tag>#People</tag>
              <tag>@User1</tag>
          </query>
    </retrieve>
</iq>
Example 2:

Request to retrieve collections containing messages tagged with @User1 and #People from chat with user juliet@capulet.com between 2014-01-01 00:00:00 and 2014-05-01 00:00:00

<iq type="get" id="query2">
    <list xmlns='urn:xmpp:archive'
        with='juliet@capulet.com'
        from='2014-01-01T00:00:00Z'
        end='2014-05-01T00:00:00Z'>
          <query xmlns="http://tigase.org/protocol/archive#query">
              <tag>#People</tag>
              <tag>@User1</tag>
          </query>
    </list>
</iq>
Retrieving list of tags used by user starting with some text

To search for hashtags or user names already used following request might be used:

<iq type="set" id="query2">
    <tags xmlns="http://tigase.org/protocol/archive#query" like="#test"/>
</iq>

which will return suggested similar hashtags which where found in database for particular user if following response:

<iq type="result" id="query2">
    <tags xmlns="http://tigase.org/protocol/archive#query" like="#test">
        <tag>#test1</tag>
        <tag>#test123</tag>
        <set xmlns="http://jabber.org/protocol/rsm">
             <first index='0'>0</first>
             <last>1</last>
             <count>2</count>
        </set>
    </tags>
</iq>
Automatic archiving of MUC messages

If this feature is enabled MUC messages are stored in Message Archiving repository and are added in same way as for any other messages and jid of MUC room is used as jid of message sender, so if MUC message sent from test@muc.example.com was stored then to retrieve this messages test@muc.example.com needs to be passed as with attribute to message retrieve request. Retrieved MUC messages will be retrieved in same format as normal message with one exception - each message will contain name attribute with name of occupant in room which sent this message.

This feature is by default disabled but it is possible to enable it for particular user. Additionally it is possible to change default setting on installation level and on hosted domain level to enable this feature, disable feature or allow user to decide if user want this feature to be enabled. For more information about configuration of this feature look at Configuration of automatic archiving of MUC messages

Note
  • It is worth to mention that even if more than on user resource joined same room and each resource will receive same messages then only single message will be stored in Message Archving repository.

  • It is also important to note that MUC messages are archived to user message archive only when user is joined to MUC room (so if message was sent to room but it was not sent to particular user)

10.4.4. Database

Preparation of database

Before you will be able to use Tigase Message Archiving Component and store messages in particular database you need to initialize this 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-message-archiving-version.sql, where dbname in name of database type which this schema supports and version is version of a Message Archiving 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 Preparation section of [Tigase XMPP Server Administration Guide]

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 Preparation of database section.

Note
If you use SNAPSHOT builds then schema may change for same version as this are versions we are still working on.
Schema description

Tigase Message Archiving component uses few tables and stored procedures. To make it easier to find them on database level they are prefixed with tig_ma_.

Table tig_ma_jids

This table stores all jids related to stored messages, ie. from to and from attributes of archived stanzas.

Field Description Comments

jid_id

Database ID of a 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)

domain

Domain part of a bare JID

Stored for easier lookup of messages owned by users of a particular domain

Table tig_ma_msgs

Table stores archived messages.

Field Description Comments

msg_id

Database ID of a message

owner_id

ID of a bare JID of a message owner

References jid_id from tig_ma_jids

buddy_id

ID of a bare JID of a message recipient/sender (different than owner)

References jid_id from tig_ma_jids

buddy_res

Resource part of a message recipient/sender JID

ts

Timestamp of a message

Timestamp of archivization or delayed delivery

direction

Direction of message

0 - sent by owner

1 - received by owner

type

Message type

Value of message type attribute

body

Body of a message

msg

Serialized message

stanza_hash

Hash of message parts

It is used to make sure that message is stored only once

Table tig_ma_tags

Table stores tags of archived messages. It stores one tag for many messages using tig_ma_msgs_tags to store relation between tag and a message.

Field Description Comments

tag_id

Database ID of a tag

owner_id

ID of a bare JID of a tag owner

ID of bare JID of owner for which messages with this tag were archived

tag

Actual tag value

Table tig_ma_msgs_tags

Table stores relations between tags and archived messages with this tags.

Field Description Comments

msg_id

Database ID of a message

References msg_id from tig_ma_msgs

tag_id

Database ID of a tag

References tag_id from tig_ma_tags

10.4.5. Configuration

To enable Tigase Message Archiving Component you need to add following block to etc/config.tdsl file:

message-archive () {
}

It will enable component and configure it under name message-archive. By default it will also use database configured as default data source to store data.

Custom Database

You can specify a custom database to be used for message archiving. To do this, define the archive-repo-uri property.

'message-archive' () {
    'archive-repo-uri' = 'jdbc:mysql://localhost/messagearchivedb?user=test&password=test'
}

Here, messagearchivedb hosted on localhost is used.

XEP-0136 Support

To be able to use Message Archiving component with XEP-0136: Message Archiving protocol, you additionally need to enable message-archive-xep-0136 SessionManager processor:

sess-man {
    message-archive-xep-0136 () {
    }
}

This is required for some advanced options.

Support for MAM

If you want to use Message Archiving component with XEP-0313: Message Archive Management protocol, then you need to enable urn:xmpp:mam:1 SessionManager processor:

sess-man {
    'urn:xmpp:mam:1' () {
    }
}
Setting default value of archiving level for message on a server

Setting this property will change default archiving level for messages for every account on server for which per account default archiving level is not set. User will be able to change this value setting default modes as described in XEP-0136 section 2.4

Possible values are:

false

Messages are not archived

body

Only message body will be stored. Message without a body will not be stored with this value set

message

While message stanza will be archived (if message should be stored, see Saving Options)

stream

In this mode every stanza should be archived. (Not supported)

To set default level to message you need to set default-store-method of message-archive processor to message:

sess-man {
    message-archive {
        default-store-method = 'message'
    }
}
Setting required value of archiving level for messages on a server

Setting this property will change required archiving level for messages for every account on server. User will be able to change this to any lower value by setting default modes as described in XEP-0136 section 2.4 but user will be allowed to set higher archiving level. If this property is set to higher value then default archiving level is set then this setting will be used as default archiving level setting.

Possible values for this setting are the same as values for default archiving level setting, see Setting default value of archiving level for message on a server for list of possible values.

To set required level to body you need to set required-store-method of message-archive processor to body:

sess-man {
    message-archive {
        required-store-method = `body`
    }
}
Enabling support for tags

To enable this feature Message Archiving component needs to be configured properly. You need to add tags-support = true line to message-archiving configuration section of etc/config.tdsl file. Like in following example:

message-archive {
    tags-support = true
}

where:

  • message-archive - is name of configuration section under which Message Archiving component is configured to run

Saving Options

By default, Tigase Message Archive will only store the message body with some metadata, this can exclude messages that are lacking a body. If you decide you wish to save non-body elements within Message Archive, you can now can now configure this by setting msg-archive-paths to list of elements paths which should trigger saving to Message Archive. To additionally store messages with <subject/> element:

sess-man {
    message-archive {
        msg-archive-paths = [ '-/message/result[urn:xmpp:mam:1]' '/message/body', '/message/subject' ]
    }
}

Where above will set the archive to store messages with <body/> or <subject/> elements and for message with <result xmlns="urn:xmpp:mam:1"/> element not to be stored.

Warning
It is recommended to keep entry for not storing message with <result xmlns="urn:xmpp:mam:1"/> element as this are results of MAM query and contain messages already stored in archive!
Tip
Enabling this for elements such as iq, or presence will quickly load the archive. Configure this setting carefully!
Configuration of automatic archiving of MUC messages

As mentioned above no additional configuration options than default configuration of Message Archiving component and plugin is needed to let user decide if he wants to enable or disable this feature (but it is disabled by default). In this case user to enable this feature needs to set settings of message archiving adding muc-save attribute to <default/> element of request with value set to true (or to false to disable this feature).

To configure state of this feature on installation level, it is required to set store-muc-messages property of message-archive SessionManager processor:

sess-man {
    message-archive {
        store-muc-messages = 'value'
    }
}

where value may be one of following values:

user

allows value to be set on domain level or by user if domain level setting allows that

true

enables feature for every user in every hosted domain (cannot be overridden by on domain or user level)

false

disables feature for every user in every hosted domain (cannot be overridden by on domain or user level)

To configure state of this feature on domain level, you need to execute vhost configuration command. In list of fields to configure domain, field to set this will be available with following values:

user

allows user to stat of this feature (if allowed on installation level)

true

enables feature for users of configured domain (user will not be able to disable)

false

disables feature for users of configured domain (user will not be able to disable)

Purging Information from Message Archive

This feature allows for automatic removal of entries older than a configured number of days from the Message Archive. It is designed to clean up database and keep its size within reasonable boundaries. If it is set to 1 day and entry is older than 24 hours then it will be removed, i.e. entry from yesterday from 10:11 will be removed after 10:11 after next execution of purge.

There are 3 settings available for this feature: To enable the feature:

'message-archive' {
    'remove-expired-messages' = true
}

This setting changes the initial delay after the server is started to begin removing old entries. In other words, MA purging will not take place until the specified time after the server starts. Default setting is PT1H, or one hour.

    'remove-expired-messages-delay' = 'PT2H'

This setting sets how long MA purging will wait between passes to check for and remove old entries. Default setting is P1D which is once a day.

    'remove-expired-messages-period' = 'PT2D'

You may use all settings at once if you wish.

NOTE that these commands are also compatible with unified-archive component, just replace message with unified.

Configuration of number of days in VHost

VHost holds a setting that determines how long a message needs to be in archive for it to be considered old and removed. This can be set independently per Vhost. This setting can be modified by either using the HTTP admin, or the update item execution in adhoc command.

This configuration is done by execution of Update item configuration adhoc command of vhost-man component, where you should select domain for which messages should be removed and then in field XEP-0136 - retention type select value Number of days and in field XEP-0136 - retention period (in days) enter number of days after which events should be removed from MA.

In adhoc select domain for which messages should be removed and then in field XEP-0136 - retention type select value Number of days and in field XEP-0136 - retention period (in days) enter number of days after which events should be removed from MA.

In HTTP UI select Other, then Update Item Configuration (Vhost-man), select the domain, and from there you can set XEP-0136 retention type, and set number of days at XEP-0136 retention period (in days).

Using separate store for archived messages

It is possible to use separate store for archived messages, to do so you need to configure new DataSource in dataSource section. Here we will use message-archive-store as a name of a data source. Additionally you need to pass name of newly configured data source to dataSourceName property of default repository of Message Archiving component.

Example:

dataSource {
    message-archive-store () {
        uri = 'jdbc:postgresql://server/message-archive-database'
    }
}

message-archive {
    repositoryPool {
        default () {
            dataSourceName = 'message-archive-store'
        }
    }
}

It is also possible to configure separate store for particular domain, i.e. example.com. Here we will configure data source with name example.com and use it to store data for archive:

dataSource {
    'example.com' () {
        uri = 'jdbc:postgresql://server/example-database'
    }
}

message-archive {
    repositoryPool {
        'example.com' () {
          # we may not set dataSourceName as it matches name of domain
        }
    }
}
Note
With this configuration messages for other domains than example.com will be stored in default data source.
Setting Pool Sizes

There are a high number of prepared statements which are used to process and archive messages as they go through the server, and you may experience an increase in resource use with the archive turned on. It is recommended to decrease the repository connection pool to help balance server load from this component using the Pool Size property:

'message-archive' (class: tigase.archive.MessageArchiveComponent) {
    'archive-repo-uri' = 'jdbc:mysql://localhost/messagearchivedb?user=test&password=test'
    'pool-size' = 15
}
Message Tagging Support

Tigase now is able to support querying message archives based on tags created for the query. Currently, Tigase can support the following tags to help search through message archives: - hashtag Words prefixed by a hash (#) are stored with a prefix and used as a tag, for example #Tigase - mention Words prefixed by an at (@) are stored with a prefix and used as a tag, for example @Tigase

NOTE: Tags must be written in messages from users, they do not act as wildcards. To search for #Tigase, a message must have #Tigase in the <body> element.

This feature allows users to query and retrieve messages or collections from the archive that only contain one or more tags.

Activating Tagging

To enable this feature, the following line must be in the config.tdsl file (or may be added with Admin or Web UI)

'message-archive' (class: tigase.archive.MessageArchiveComponent) {
    'tags-support' = true
}
Usage

To execute a request, the tags must be individual children elements of the retrieve or list element like the following request:

<query xmlns="http://tigase.org/protocol/archive#query">
    <tag>#People</tag>
    <tag>@User1</tag>
</query>

You may also specify specific senders, and limit the time and date that you wish to search through to keep the resulting list smaller. That can be accomplished by adding more fields to the retrieve element such as 'with', 'from’, and ’end' . Take a look at the below example:

<iq type="get" id="query2">
    <retrieve xmlns='urn:xmpp:archive'
        with='juliet@capulet.com'
        from='2014-01-01T00:00:00Z'
        end='2014-05-01T00:00:00Z'>
          <query xmlns="http://tigase.org/protocol/archive#query">
              <tag>#People</tag>
              <tag>@User1</tag>
          </query>
    </retrieve>
</iq>

This stanza is requesting to retrieve messages tagged with @User1 and #people from chats with the user juliet@capulet.com between January 1st, 2014 at 00:00 to May 1st, 2014 at 00:00.

NOTE: All times are in Zulu or GMT on a 24h clock.

You can add as many tags as you wish, but each one is an AND statement; so the more tags you include, the smaller the results.

10.4.6. Usage

Now that we have the archive component running, how do we use it? Currently, the only way to activate and modify the component is through XMPP stanzas. Lets first begin by getting our default settings from the component:

<iq type='get' id='prefq'>
  <pref xmlns='urn:xmpp:archive'/>
</iq>

It’s a short stanza, but it will tell us what we need to know, Note that you do not need a from or a to for this stanza. The result is as follows:

<iq type='result' id='prefq' to='admin@domain.com/cpu'>
<pref xmlns='urn:xmpp:archive'>
<auto save='false'/>
<default otr='forbid' muc-save="false" save="body"/>
<method use="prefer" type="auto"/>
<method use="prefer" type="local"/>
<method use="prefer" type="manual"/>
</prefq>
</iq>

See below for what these settings mean.

XEP-0136 Field Values
<auto/>
  • Required Attributes

    • save= Boolean turning archiving on or off

  • Optional Settings

    • scope= Determines scope of archiving, default is 'stream' which turns off after stream end, or may be 'global' which keeps auto save permanent,

<default/>

Default element sets default settings for OTR and save modes, includes an option for archive expiration.

  • Required Attribures

    • otr= Specifies setting for Off The Record mode. Available settings are:

      • approve The user MUST explicitly approve OTR communication.

      • concede Communications MAY be OTR if requested by another user.

      • forbid Communications MUST NOT be OTR.

      • oppose Communications SHOULD NOT be OTR.

      • prefer Communications SHOULD be OTR.

      • require Communications MUST be OTR.

    • save= Specifies the portion of messages to archive, by default it is set to body.

      • body Archives only the items within the <body/> elements.

      • message Archive the entire XML content of each message.

      • stream Archive saves every byte of communication between server and client. (Not recommended, high resource use)

  • Optional Settings

    • expire= Specifies after how many seconds should the server delete saved messages.

<item/>

The Item element specifies settings for a particular entity. These settings will override default settings for the specified JIDS.

  • Required Attributes

    • JID= The Jabber ID of the entity that you wish to put these settings on, it may be a full JID, bare JID, or just a domain.

    • otr= Specifies setting for Off The Record mode. Available settings are:

      • approve The user MUST explicitly approve OTR communication.

      • concede Communications MAY be OTR if requested by another user.

      • forbid Communications MUST NOT be OTR.

      • oppose Communications SHOULD NOT be OTR.

      • prefer Communications SHOULD be OTR.

      • require Communications MUST be OTR.

    • save= Specifies the portion of messages to archive, by default it is set to body.

      • body Archives only the items within the <body/> elements.

      • message Archive the entire XML content of each message.

      • stream Archive saves every byte of communication between server and client. (Not recommended, high resource use)

  • Optional Settings

    • expire= Specifies after how many seconds should the server delete saved messages.

<method/>

This element specifies the user preference for available archiving methods.

  • Required Attributes

    • type= The type of archiving to set

      • auto Preferences for use of automatic archiving on the user’s server.

      • local Set to use local archiving on user’s machine or device.

      • manual Preferences for use of manual archiving to the server.

    • use= Sets level of use for the type

      • prefer The selected method should be used if it is available.

      • concede This will be used if no other methods are available.

      • forbid The associated method MUST not be used.

Now that we have established settings, lets send a stanza changing a few of them:

<iq type='set' id='pref2'>
  <pref xmlns='urn:xmpp:archive'>
    <auto save='true' scope='global'/>
    <item jid='domain.com' otr='forbid' save='body'/>
    <method type='auto' use='prefer'/>
    <method type='local' use='forbid'/>
    <method type='manual' use='concede'/>
  </pref>
</iq>

This now sets archiving by default for all users on the domain.com server, forbids OTR, and prefers auto save method for archiving.

Manual Activation

Turning on archiving requires a simple stanza which will turn on archiving for the use sending the stanza and using default settings.

<iq type='set' id='turnon'>
  <pref xmlns='urn:xmpp:archive'>
    <auto save='true'/>
  </pref>
</iq>

A sucessful result will yield this response from the server:

<iq type='result' to='user@domain.com' id='turnon'/>

Once this is turned on, incoming and outgoing messages from the user will be stored in tig_ma_msgs table in the database.

10.4.7. Limitations

  • Component groups messages in collections using date of a messages instead of id of message thread, due to fact that some clients are sending messages with no thread id (ie. Psi, Psi+).

  • Only bare JID is stored of sender or recipient.

10.5. Advanced Message Processing - AMP XEP-0079

Tigase server offers support for Advanced Message Processing, called AMP or XEP-0079.

It is enabled by default but there are several configuration options that you may tweak.

Configuration of AMP is not very complex, but as it is implemented as a component in the Tigase server it does needs a few settings to get it right.

Here is a first, brief overview of the AMP configuration and later detailed explanation of each parameter.

'sess-man' {
    amp () {
        'amp-jid' = 'amp@your-domain.tld'
    }
    message (active: false) {}
    msgoffline (active: false) {}
}
'amp-security-level' = 'STRICT'

10.5.1. First of all: plugins:

Even though the whole functionality is implemented inside the component you need a way to forward messages with AMP payload to that component. This is what the amp plugin does. The amp plugin intercepts all <message/> packets even without AMP payload, redirecting some of the to the AMP component and others processing in a standard way. Therefore you no longer need message plugin or msgoffline plugin. Those are all functions are offered by the amp plugin now. Hence you have to switch message and msgoffline plugins off (the amp plugin is loaded by default):

'sess-man' {
    amp () {}
    message (active: false) {}
    msgoffline (active: false) {}
}

The amp plugin needs to know where to forward all the AMP packets. By default plugin uses hostname of the given machine as this is true to the most installations. However, this is configured by the last line of the example configuration, which forwards all packets to the address amp@your-domain.tld:

'sess-man' {
    amp () {
        'amp-jid' = 'amp@your-domain.tld'
    }
}

10.5.2. Secondly: component:

By default Tigase loads the component with the standard name amp

10.5.3. Optional parameters:

There is also one parameter shared between the component and the plugin. Connection to the database where offline messages are stored. The AMP component has a dedicated schema for storing offline messages designed for a high traffic and high load installations. It does not use UserRepository for storing messages.

By default the same physical database as for UserRepository is used but you can change it and store messages in a completely separate location to reduce performance degradation of rest of the system. You can set a database connection string using following property:

dataSource {
    'default-amp' () {
        uri = 'jdbc:mysql://localhost/tigasedb?user=db_usr&password=db_pwd'
    }
}

The XEP-0079 specification has a Section 9. - Security Considerations. As it describes, in some cases the AMP protocol can be used to reveal user’s presence information by other users who are not authorized for presence updates. There are a few possible ways to prevent this.

Tigase’s implementation offers 3 modes to handle AMP requests to prevent revealing user’s status to non-authorized users:

'amp-security-level' = 'STRICT'

In this mode the server performs strict checking. The AMP specification is fully handled. This however involves roster loading for each offline user, hence it may impact the service performance. It may not be feasible or possible to run in this mode for services under a high load with lots of AMP messages.

In the XEP this mode is described in the following way:

Accept the relevant condition only if the sender is authorized to receive the receiver’s presence, as a result of which the server MUST reply with a <not-acceptable/> error condition if the sender is not so authorized; this is the RECOMMENDED behavior. This is also the default in Tigase.

'amp-security-level' = 'PERFORMANCE'

Dummy checking is performed efficiently by just returning an error response every time there is a chance that the default action may reveal user status without looking into the user’s roster. This does not affect performance but it does impact the AMP compliance.

In the XEP this mode is described in the following way:

Accept the relevant condition only if the action is "drop", as a result of which the server MUST reply with a <not-acceptable/> error condition if the action is "alert", "error", or "notify"; this is slightly less restrictive but still unnecessarily restricts the functionality of the system, so is NOT RECOMMENDED.

It does not do any checking. It acts like all users are authorized to receive notifications, even if it may reveal user status to unauthorized users. It does not impact the server performance and it offers full AMP compliance.

'amp-security-level' = 'NONE'

10.6. Tigase PubSub Component

Welcome to Tigase PubSub component guide

10.6.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.

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.

Configuration
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>
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.

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="user@example.com" 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.

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.
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' = 'events@servername.com'
    }
}
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 (if http is name of HTTP API component)

pubsub () {
    trusted = [ 'http@{clusterNode}' ];
}
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
}
Tune handling of low memory

If there is less than 10% of free heap memory available during publication of item then Tigase pubsub component will trigger Garbage Collection and it there is still very little amount of free memory will slow down delivery of notifications for published items (waiting about 1 second before continuing).

If you have assigned a lot of memory to Tigase XMPP Server or in your case this delay is not acceptable you can adjust it by pubsub component properties:

  • setting pubsub-high-memory-usage-level to percentage of heap memory accepted as near OOM state

  • setting pubsub-low-memory-delay to number of milliseconds to wait to throttle delivery of notifications

pubsub () {
    pubsub-high-memory-usage-level = 95
    pubsub-low-memory-delay = 100
}
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
}
Database
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.

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.
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 service_id from tig_pubsub_service_jids

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 jid_id from tig_pubsub_jids

creation_date

Timestamp of creation time

configuration

Serialized configuration of PubSub node

collection_id

Points collection (parent node)

References node_id from tig_pubsub_nodes

Table tig_pubsub_affiliations

Table stores affiliations between PubSub nodes and jids.

Field Description Comments

node_id

ID of a node

References node_id from tig_pubsub_nodes

jid_id

ID of a user JID

References jid_id from tig_pubsub_jids

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 node_id from tig_pubsub_nodes

jid_id

ID of a user JID

References jid_id from tig_pubsub_jids

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 node_id from tig_pubsub_nodes

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 jid_id from tig_pubsub_jids

update_date

Timestamp of last item modification

data

Item payload

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 and pubsub-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.

Features
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.

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
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
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
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
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("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();
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='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.

Log out from PubSub Node

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.

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='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>
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='sess-man@coffeebean.local' 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 = 'sess-man@coffeebean.local'
    }
}
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='bard@shakespeare.lit' 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='bard@shakespeare.lit' subscription='none'/>
    </subscriptions>
  </pubsub>
</iq>
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 to application/json.

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 create

  • owner - 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>admin@example.com</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" : "admin@example.com",
  "pubsub#node_type" : "leaf"
}
Response in JSON
{
  "Note": "Operation successful"
}
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"
}
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 to

  • jids - 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>test1@example.com</value>
    <value>test2@example.com</value>
  </jids>
</data>
Response in XML
<result>
  <Note type="fixed">
    <value>Operation successful</value>
  </Note>
</result>
Using JSON
Request in JSON
{
  "node" : "example",
  "jids" : [
    "test1@example.com",
    "test2@example.com"
  ]
}
Response in JSON
{
  "Note" : "Operation successful"
}
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 from

  • jids - 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>test@example.com</value>
    <value>test2@example.com</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" : [
    "test@example.com",
    "test2@example.com"
  ]
}
Response in JSON
{
  "Note" : "Operation successful"
}
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 to

  • item-id - field may contain id of entry to publish

  • expire-at - field may contain timestamp (in XEP-0082 format) after which item should not be delivered to user

  • entry - 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>{ &quot;key-1&quot; : 2, &quot;key-2&quot; : &quot;value-2&quot; }</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>{ &quot;key-1&quot; : 2, &quot;key-2&quot; : &quot;value-2&quot; }</payload>
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 to

  • item-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"
}
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.

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.

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 list

  • item-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>"
  ]
}
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 subscriptions

  • node-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>test@example.com</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" : "test@example.com",
  "node-pattern" : "test-.*"
}
Response in JSON
{
  "nodes" : [
    "test-123",
    "test-342"
  ]
}
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.

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
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
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
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
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("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();
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='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.

Log out from PubSub Node

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.

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='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

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>
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='sess-man@coffeebean.local' 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 = 'sess-man@coffeebean.local'
    }
}
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='bard@shakespeare.lit' 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='bard@shakespeare.lit' subscription='none'/>
    </subscriptions>
  </pubsub>
</iq>
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 to application/json.

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 create

  • owner - 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>admin@example.com</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" : "admin@example.com",
  "pubsub#node_type" : "leaf"
}
Response in JSON
{
  "Note": "Operation successful"
}
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"
}
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 to

  • jids - 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>test1@example.com</value>
    <value>test2@example.com</value>
  </jids>
</data>
Response in XML
<result>
  <Note type="fixed">
    <value>Operation successful</value>
  </Note>
</result>
Using JSON
Request in JSON
{
  "node" : "example",
  "jids" : [
    "test1@example.com",
    "test2@example.com"
  ]
}
Response in JSON
{
  "Note" : "Operation successful"
}
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 from

  • jids - 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>test@example.com</value>
    <value>test2@example.com</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" : [
    "test@example.com",
    "test2@example.com"
  ]
}
Response in JSON
{
  "Note" : "Operation successful"
}
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 to

  • item-id - field may contain id of entry to publish

  • expire-at - field may contain timestamp (in XEP-0082 format) after which item should not be delivered to user

  • entry - 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>{ &quot;key-1&quot; : 2, &quot;key-2&quot; : &quot;value-2&quot; }</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>{ &quot;key-1&quot; : 2, &quot;key-2&quot; : &quot;value-2&quot; }</payload>
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 to

  • item-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"
}
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.

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.

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 list

  • item-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>"
  ]
}
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 subscriptions

  • node-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>test@example.com</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" : "test@example.com",
  "node-pattern" : "test-.*"
}
Response in JSON
{
  "nodes" : [
    "test-123",
    "test-342"
  ]
}

10.6.2. Limitations

Addressing

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>

10.7. Server Monitoring

All the documentation and resources related to the Tigase server monitoring.

10.7.1. Setting Up Remote Monitoring in the Server

Tigase server can be remotely monitored over following protocols: JMX/RMI, SNMP and HTTP. Even though JMX offers the biggest control and visibility to the server states, all of the monitoring services give the same basic set of the server statistics:

  • Number of network connections for s2s, c2s and Bosh

  • Last second, last minute and last hour load for all main components: SM, MR, c2s, s2s, Bosh, MUC and PubSub

  • System statistics - memory usage (heap and non heap) and the server uptime in milliseconds and human readable text.

  • Users statistics - number of registered users and number of online user session.

JMX/RMI and SNMP servers offer basic security and can restrict access while the HTTP server doesn’t offer any access restriction mechanisms. Therefore HTTP monitoring is recommended to operate behind a firewall.

The monitoring itself causes very low overhead in terms of the resources and CPU consumption on top of the normal Tigase processing requirements so it can be left on without worrying about performance degradation.

Note. This works with the Tigase server from version 4.2.0 or SVN revision 1418.

What You Need

Statistics binaries are built-in dist-max and no extra files are needed. If you have downloaded -dist file, you will need tigase-extras.

To ensure, one files is necessary to run monitoring:

File should be in the /jars directory.

Activation

You can either run the Tigase installer and use the configuration wizard to activate the monitoring or edit etc/config.tdsl file and add following lines:

monitoring() {
  jmx() {
    port = 9050
  }
  http() {
    port = 9080
  }
  snmp() {
    port = 9060
  }
}

As you see there is a separate block for each monitoring server you want to activate. Each server is responsible for activation of a different protocol and takes a single parameter - port number. There are following protocols supported right now:

  • jmx - activating monitoring via JMX/RMI

  • http - activating monitoring over HTTP protocol

  • snmp - activating monitoring over SNMP protocol

You can have all protocols active at the same time or any combination of them or none.

Security

Both JMX and SNMP offer security protection to limit access to monitoring data. The security configuration is a bit different for both.

JMX

After the server installation or in the SVN repository you can find 2 files in the etc/ directory: jmx.access and jmx.password.

  • jmx.access is a user permission file. You can use it to specify whether the user can access the monitoring data for reading only readonly or with read-write readwrite access. There are example entries in the file already and the content may simply look like: `

monitor readonly
admin readwrite
  • jmx.password is a user password file. You can set user passwords here and the format again is very simple and the same as for jmx.access. There are example entries already provided for you convenience. Content of the file may look like the example below:

    admin admin_pass
    monitor monitor_pass

Using above to files you can control who and how can access the JMX monitoring services.

SNMP

Access to SNMP monitoring is controlled using ACL (access control lists) which can be configured in the file snmp.acl located in etc/ directory. It contains lots of detailed instructions how to setup ACL and restrict access per user, host and what kind access is allowed. The simplest possible configuration may look like this:

acl = {
  {
    communities = public, private
    access = read-only
    managers = public.host.com, private.host.com
  }
  {
    communities = admin
    access = read-write
    managers = localhost, admin.host.com
  }
}

You might also need Tigase MIB definition: TIGASE-MANAGEMENT-MIB.mib for the server specific statistics. The MIB contains definition for all the server statistics exposed via SNMP.

HTTP

Access the server at example.com:9080 and you will be presented with an Agent View.

10.7.2. Retrieving statistics from the server

By default we can retrieve server statistics using XMPP, no additional setup is necessary.

Retrieving statistics using XMPP

Accessing statistics over XMPP protocol requires any XMPP client capable of executing XEP-0050: Ad-Hoc Commands. It’s essential to remember, that only administrator (a user whose JID is configured as administrative) can access the statistics.

Psi XMPP Client

For the purpose of this guide Psi client will be used. After successfully configuring and connecting to account with administrative privileges we need to access Service Discovery, either from application menu or from context menu of the particular account account:

roster-discovery

In the Service Discovery window we need to find Server Statistics component:

discovery-stats

We can either access statistics for all components or select particular component after expanding the tree. To execute ad-hoc command simply double click on the particular node which will open window with statistics:

server-stats

In this window, in addition to see the statistics, we can adjust Stats level by selecting desired level from the list and confirm by clicking Finish.

Retrieving statistics using JMX

In order to access statistics over JMX we need to enable support for it in Tigase - Monitoring Activation. Afterwards we can use a number of tools to get to the statistics, for example the following:

JConsole

After opening JConsole we either select local process or provide details of the remote process, including IP, port and credentials from etc/jmx.* files:

jconsole

Afterwards we navigate to the MBeans tab from where we can access the tigase.stats MBean. It offers similar options to XMPP - either accessing statistics for all components or only for particular component as well as adjusting level for which we want to obtain statistics:

jconsole

StatsDumper.groovy

In order to collect statistics over period of time following groovy script can be used: StatsDumper.groovy. It’s a Simple JMX client that connects to Tigase and periodically saves all statistics to files.

It takes following parameters:

$ groovy StatsDumper.groovy [hostname] [username] [password] [dir] [port] [delay(ms)] [interval(ms)] [loadhistory(bool)]
  • hostname - address of the instance

  • username - JMX username

  • password - JMX username

  • dir - directory to which save the files with statistics

  • port - port on which to make the connection

  • delay(ms) - initial delay in milliseconds after which statistics should be saved

  • interval(ms) - interval between each retrieval/saving of statistics

  • loadhistory(bool) - indicates whether or not load statistics history from server (if such is enabled in Tigase)

10.7.3. Eventbus

Tigase includes an eventbus component to help with monitoring has been implemented. This allows you to set thresholds for certain predefined tasks and you or other JIDs can be sent a message when those thresholds are passed. You can even configure a mailer extension to have an E-mail sent to system administrators to let them know an event has occurred! Lets begin with setup and requirements.

Eventbus is based on a limited PubSub specification. Events are delivered to subscribers as a normal PubSub notification.

Each component or client may subscribe for specific types of events. Only components on cluster nodes are allowed to publish events.

Setup

Eventbus is enabled by default on v7.1.0 b4001 and later, so no setup needed!

How it Works

Events in Eventbus are identified by two elements: name of event and its namespace:

<EventName xmlns="tigase:demo">
  <sample_value>1</sample_value>
</EventName>

Where event name is EventName and namespace is tigase:demo.

Listeners may subscribe for a specific event or for all events with specific a namespace. Because in pubsub, only one node name exists, so we have to add a way to convert the event name and namespace to a node name:

nodename = eventname + "|" + namespace

So for example, to subscribe to <EventName xmlns="tigase:demo">, node must be: EventName|tigase:demo. If you wish to subscribe to all events with a specific namespace, use an asterisk (*) instead of the event name: *|tigase:demo.

Note

If client is subscribed to *|tigase:demo node, then events will not be sent from node *|tigase:demo, but from the real node (in this case: EventName|tigase:demo).

Available Tasks

Eventbus monitoring has several pre-defined tasks that can be monitored and set to trigger. What follows is the list of tasks with the options attributed to each task.

  • disk-task - Used to check disk usage.
    Available Options

    1. enabled - Enable or disable task, Boolean value.

    2. period - Period of running check, Integer value.

    3. threshold - Percentage of used space on disk, Float value.

  • cpu-temp-task - Used to check CPU temperature.
    Available Options

    1. enabled - Enable or disable task, Boolean value.

    2. period - Period of running check, Integer value.

    3. cpuTempThreshold - Temperature threshold of CPU in °C.

  • load-checker-task - Used to check system load.
    Available Options

    1. enabled - Enable or disable task, Boolean value.

    2. period - Period of running check, Integer value.

    3. averageLoadThreshold - Average percent load threshold, Long value.

  • memory-checker-task - Used to check memory usage.
    Available Options

    1. enabled - Enable or disable task, Boolean value.

    2. period - Period of running check, Integer value.

    3. maxHeapMemUsagePercentThreshold - Alarm when percent of used Heap memory is larger than, Integer value.

    4. maxNonHeapMemUsagePercentThreshold - Alarm when percent of used Non Heap memory is larger than, Integer value.

  • logger-task - Used to transmit log entries depending on level entered.

    1. enabled - Enable or disable task, Boolean value.

    2. levelThreshold - Minimal log level that will be the threshold. Possible values are SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, and ALL.

  • connections-task - Used to check users disconnections.
    NOTE: The event will be generated only if both thresholds (amount and percentage) will be fulfilled.

    1. enabled - Enable or disable task, Boolean value.

    2. period - Period of running check in ms, Integer value.

    3. thresholdMinimal - Minimal amount of disconnected users required to generate alarm.

    4. threshold - Minimal percent of disconnected users required to generate alarm.

Configuration

Configuration of the eventbus monitor can be done one of two ways; either by lines in config.tdsl file, or by sending XMPP stanzas to the server. You may also send XMPP stanzas VIA HTTP REST. XMPP stanza configurations will override ones in config.tdsl, but they will only last until the server restarts.

config.tdsl

Tasks can be configured in the config.tdsl file. See available tasks for the tasks that can be setup.

To enable a specific monitor task, use the following line:

monitor {
    '$TASKNAME' {
        setting = value
    }
}

Where monitor is the component name for MonitorComponent, and $TASKNAME is one of the available task names.

This format will be the same for other settings for tasks, and it’s best to group settings under one heading. For example:

monitor {
    'connections-task' {
        enabled = true
        period = 1000
    }
}

sets the check period to 1000 milliseconds and enables connections-task.

NOTE Once triggers have been activated, they will become dormant. Think of these as one-shot settings.

Subscription Limitations

To define list of JIDs allowed to subscribe for events:

eventbus {
    affiliations {
        allowedSubscribers = 'francisco@denmark.lit,bernardo@denmark.lit'
    }
}

If this is not specified, all users can subscribe.

Configuration via XMPP

We can also configure the eventbus monitor component using XMPP stanzas. This allows us to set and change configurations during server runtime. This is done using a series of iq stanzas send to the monitor component.

We can query each component for its current settings using the following stanza.

<iq type="set" to="monitor@$DOMAIN/disk-task" id="aad0a">
<command xmlns="http://jabber.org/protocol/commands" node="x-config"/>
</iq>

The server will return the component current settings which will make things easier if you wish to edit them. In this case, the server has returned the following to us

<iq from="monitor@$DOMAIN/disk-task" type="result" id="aad0a" to="alice@coffeebean.local/Psi+">
<command xmlns="http://jabber.org/protocol/commands" status="executing" node="x-config" sessionid="0dad3436-a029-4082-b0e0-04d838c6c0da">
<x xmlns="jabber:x:data" type="">
<title>Task Configuration</title>
<instructions/>
<field type="boolean" label="Enabled" var="x-task#enabled">
<value>0</value>
</field>
<field type="text-single" label="Period [ms]" var="x-task#period">
<value>60000</value>
</field>
<field type="text-single" label="Disk usage ratio threshold" var="threshold">
<value>0.8</value>
</field>
</x>
</command>
</iq>

This tells us that the disk-task setting is not active, has a period of 60000ms, and will trigger when disk usage is over 80%.

To send new settings to the monitor component, we can send a similar stanza back to the monitor component.

<iq type="set" to="monitor@$DOMAIN/disk-task" id="aad1a">
<command xmlns="http://jabber.org/protocol/commands" node="x-config" sessionid="0dad3436-a029-4082-b0e0-04d838c6c0da">
<x xmlns="jabber:x:data" type="submit">
<field type="boolean" var="x-task#enabled">
<value>0</value>
</field>
<field type="text-single" var="x-task#period">
<value>60000</value>
</field>
<field type="text-single" var="threshold">
<value>0.8</value>
</field>
</x>
</command>
</iq>

To which a successful update will give you an XMPP success stanza to let you know everything is set correctly.

Alternatively, you can update specific settings by editing a single field without adding anything else. For example, if we just wanted to turn the disk-task on we could send the following stanza:

<iq type="set" to="monitor@$HOSTNAME/disk-task" id="ab53a">
<command xmlns="http://jabber.org/protocol/commands" node="x-config">
<x xmlns="jabber:x:data" type="submit">
<field type="boolean" var="x-task#enabled">
<value>1</value>
</field>
</x>
</command>
</iq>

To set any other values, do not forget that certain parts may need to be changed, specifically the <field type="boolean" var=x-task#enabled"> fields.
- Your field type will be defined by the type of variable specified in the Available Tasks section.
- var=x task# will be followed by the property value taken directly from the Available Tasks section.

Getting the Message

Without a place to send messages to, eventbus will just trigger and shut down. There are two different methods that eventbus can deliver alarm messages and relevant data; XMPP messages and using the mailer extension.

XMPP notification

In order to retrieve notifications, a subscription to the eventbus@tigase.org user must be made. Keep in mind that subscriptions are not persistent across server restarts, or triggers.
The eventbus schema is very similar to most XMPP subscription requests but with a few tweaks to differentiate it if you wanted to subscribe to a certain task or all of them. Each task is considered a node, and each node has the following pattern: eventName|eventXMLNS. Since each monitoring task has the tigase:monitor:event event XMLNS, we just need to pick the event name from the list of tasks. So like the above example, our event node for the disk task will be disk-task|tigase:monitor:event. Applied to an XMPP stanza, it will look something like this:

<iq type='set'
    to='eventbus@tigase.org'
    id='sub1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <subscribe node='disk-taskEvent|tigase:monitor:event' jid='$USER_JID'/>
  </pubsub>
</iq>

Don’t forget to replace $USER_JID with the bare JID of the user you want to receive those messages. You can even have them sent to a MUC or any component with a JID. Available events are as follows: - disk-taskEvent for disk-task - LoggerMonitorEvent for logger-task - HeapMemoryMonitorEvent for memory-checker-task - LoadAverageMonitorEvent for load-checker-task - CPUTempMonitorEvent for cpu-temp-task - UsersDisconnected for connections-task

Alternatively, you can also subscribe to all events within the eventbus by using a wildcard * in place of the event XMLNS like this example:

<iq type='set'
    to='eventbus@tigase.org'
    id='sub1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <subscribe node='*|tigase:monitor:event' jid='$USER_JID'/>
  </pubsub>
</iq>
Sample notification from Eventbus
<message from='eventbus.shakespeare.lit' to='francisco@denmark.lit' id='foo'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='EventName|tigase:demo'>
      <item>
        <EventName xmlns="tigase:demo" eventSource="samplecomponent.shakespeare.lit'" eventTimestamp="1444216850">
          <sample_value>1</sample_value>
        </EventName>
      </item>
    </items>
  </event>
</message>
Mailer Extension

Tigase Server Monitor Mailer Extension (TSMME) can send messages from the monitor component to a specified E-mail address so system administrators who are not logged into the XMPP server.

For v7.1.0 versions and later, TSMME is already included in your distribution package and no extra installation is needed.

For versions older than 7.1.0 TSMME requires two files to operate:

  • A compiled build of tigase mailer from its repository. Place the compiled .jar file into /jars directory.

  • javax.mail.jar file which may be downloaded from this link. Also place this file in the /jars directory.

Configuration

Tigase Mailer Extension may be configured via the config.tdsl file in the following manner:

monitor {
    'mailer-from-address' = 'sender@tigase.org'
    'mailer-smtp-host' = 'mail.tigase.org'
    'mailer-smtp-password' = '********'
    'mailer-smtp-port' = '587'
    'mailer-smtp-username' = 'sender'
    'mailer-to-addresses' = 'receiver@tigase.org,admin@tigase.org'
}

Here is an explanation of those variables.

  • mailer-smtp-host - SMTP Server hostname.

  • mailer-smtp-port - SMTP Server port.

  • mailer-smtp-usernam - name of sender account.

  • mailer-smtp-password - password of sender account.

  • mailer-from-address - sender email address. It will be set in field from in email.

  • mailer-to-addresses - comma separated notification receivers email addresses.

It is recommended to create a specific e-mail address in your mail server for this purpose only, as the account settings are stored in plaintext without encryption.

10.7.4. Configuration of statistics loggers

It is possible to enable and configure automatic storage of statistics information. To do that you need to configure any of following statistics loggers as a StatisticsCollector component sub-beans:

tigase.stats.CounterDataArchivizer

every execution put current basic server metrics (CPU usage, memory usage, number of user connections, uptime) into database (overwrites previous entry).

tigase.stats.CounterDataLogger

every execution insert new row with new set of number of server statistics (CPU usage, memory usage, number of user connections per connector, number of processed packets of different types, uptime, etc) into the database.

tigase.stats.CounterDataFileLogger

every execution store all server statistics into separate file.

As an example to configure tigase.stats.CounterDataFileLogger to archive statistics data with level FINE every 60 seconds to file prefixed with stat and located in logs/server_statistics following entry is needed:

stats() {
    'stats-file-logger' (class: tigase.stats.CounterDataFileLogger) {
        'stats-directory' = 'logs/server_statistics'
        'stats-filename' = 'stat'
        'stats-unixtime' = false
        'stats-datetime' = true
        'stats-datetime-format' = 'HH:mm:ss'
        'stats-level' = 'FINEST'
    }
}

10.8. Server to Server Protocol Settings

Tigase s2s communication component allows you to tweak it’s configuration to get a better performance in your installation.

S2S (or server to server) protocol is enabled by default with optimal settings chosen. There are however, a set of configuration parameters you can adjust the server behavior to achieve optimal performance on your installation.

This documents describes following elements of the Tigase server configuration:

  1. Number of concurrent connections to external servers

  2. The connection throughput parameters

  3. Maximum waiting time for packets addressed to external servers and the connection inactivity time

  4. Custom plugins selecting connection to the remote server

10.8.1. Number of Concurrent Connections

Normally only one connection to the remote server is required to send XMPP stanza to that server. In some cases however, under a high load, you can get much better throughput and performance if you open multiple connections to the remote server.

This is especially true when the remote server works in a cluster mode. Ideally you want to open a connection to each of the cluster nodes on the remote server. This way you can spread the traffic evenly among cluster nodes and improve the performance for s2s connections.

Tigase server offers 2 different parameters to tweak the number of concurrent, s2s connections:

  • max-out-total-conns - this property specifies the maximum outgoing connections the Tigase server opens to any remote XMPP server. This is a per domain limit, which means that this limit applies to each of the remote domains Tigase connects to. If it is set to 4 then Tigase opens a maximum of 4 connections to jabber.org plus maximum 4 connections to muc.jabber.org even if this is the same physical server behind the same IP address.

    To adjust the limit you have to add following to the config.tdsl file:

    s2s {
        'max-out-total-conns' = 2
    }
  • max-out-per-ip-conns - this property specifies the maximum outgoing connections Tigase server opens to any remote XMPP server to its single IP address. This too, is per domain limit, which means that this limit applies to each of the remote domains Tigase connects to. If it is set to 1, and the above limit is set to 4, and the remote server is visible behind 1 IP address, then Tigase opens a maximum of 1 connection to jabber.org plus a maximum of 1 connection to muc.jabber.org and other subdomains.

    To adjust the limit you have to add following line to the config.tdsl file:

    s2s {
        'max-out-per-ip-conns' = 2
    }

10.8.2. Connection Throughput

Of course everybody wants his server to run with maximum throughput. This comes with a cost on resources, usually increased memory usage. This is especially important if you have large number of s2s connections on your installations. High throughput means lots of memory for network buffers for every single s2s connection. You may soon run out of all available memory.

There is one configuration property which allows you to adjust the network buffers for s2s connections to lower your memory usage or increase data throughput for s2s communication.

More details about are available in the net-buff-high-throughput or net-buff-Standard property descriptions.

10.8.3. Maximum Packet Waiting Time and Connection Inactivity Time

There are 2 timeouts you can set for the component controlling s2s communication.

  • max-packet-waiting-time - this sets the maximum time for the packets waiting for sending to some remote server. Sometimes, due to networking problems or DNS problems it might be impossible to send message to remote server right away. Establishing a new connection may take time or there might be communication problems between servers or perhaps the remote server is restarted. Tigase will try a few times to connect to the remote server before giving up. This parameter specifies how long the packet is waiting for sending before it is returned to the sender with an error. The timeout is specified in seconds:

    s2s {
        'max-packet-waiting-time' = 420L
    }
  • max-inactivity-time - this parameters specifies the maximum s2s connection inactivity time before it is closed. If a connection is not in use for a long time, it doesn’t make sense to keep it open and tie resources up. Tigase closes s2s connection after specified period of time and reconnects when it is necessary. The timeout is specified in seconds:

    s2s {
        'max-inactivity-time' = 900L
    }

10.8.4. Custom Plugin: Selecting s2s Connection

Sometimes for very large installations you may want to set larger number of s2s connections to remote servers, especially if they work in cluster of several nodes. In such a case you can also have a control over XMPP packets distribution among s2s connections to a single remote server.

This piece of code is pluggable and you can write your own connection selector. It is enough to implement S2SConnectionSelector interface and set your class name in the configuration using following parameter in config.tdsl file:

s2s {
    's2s-conn-selector' = 'YourSelectorImplementation'
}

The default selector picks connections randomly.

10.8.5. skip-tls-hostnames

The s2s-skip-tls-hostnames property disables TLS handshaking for s2s connections to selected remote domains. Unfortunately some servers (certain versions of Openfire - [1] or [2]) have problems with TLS handshaking over s2s which prevents establishing a usable connection. This completely blocks any communication to these servers. As a workaround you can disable TLS for these domains to get communication back. Enabling this can be done on any vhost, but must be configured under the s2s component.

s2s {
    'skip-tls-hostnames' = [ 'domain1', 'domain2' ]
}

10.8.6. ejabberd-bug-workaround

This property activates a workaround for a bug in EJabberd in it’s s2s implementation. EJabberd does not send dialback in stream features after TLS handshaking even if the dialback is expected/needed. This results in unusable connection as EJabberd does not accept any packets on this connection either. The workaround is enabled by default right now until the EJabberd version without the bug is popular enough. A disadvantage of the workaround is that dialback is always performed even if the SSL certificate is fully trusted and in theory this dialback could be avoided. By default, this is not enabled.

s2s {
    dialback () {
        'ejabbered-bug-workaround' = true
        }
}

This replaces the old --s2s-ejabberd-bug-workaround-active property.

10.9. Tigase MUC Component

Tigase MUC component is included in all Tigase distributions, it is enabled by default, but you may customize the name of the component by calling it in the config.tdsl file.

muc {}

10.9.1. Configuration Options

  • room-log-directory
    Directory to store chat logs

muc {
    'room-log-directory' = ' /var/log/muc/'
}
  • message-filter-enabled
    Filter that controls subelements in <message/> set, by default is set to on and will send only <message/> element:

muc {
    'message-filter-enabled' = false
}

For example, this allows users to send XHTML stanzas through MUC chatrooms on your server.

  • presence-filter-enabled
    To disable filter and allow MUC transfer all subelements in <presence/> set:

muc {
    'presence-filter-enabled' = false
}
  • search-ghosts-every-minute
    This enables pinging of occupants once every minute:

muc {
    'search-ghosts-every-minute' = true
}
  • ghostbuster-enabled
    To disable active searching of ghosts in MUC Rooms. Default is enabled.:

muc {
    'ghostbuster-enabled' = false
}
  • muc-allow-chat-states
    Allows transfer of chat-states in MUC messages:

muc {
    'muc-allow-chat-states' = true
}
  • muc-lock-new-room
    To turn off default locking newly created rooms:

muc {
    'muc-lock-new-room' = false
}

By default new room will be locked until owner submits a new room configuration.

  • muc-multi-item-allowed To disable joining from multiple resources to a single nickname:

muc {
    'muc-multi-item-allowed' = false
}
History Providers Parameters
  • history-db
    Database type. By default the same what is used as User Repository in Server, setting both database type and uri you can have a separate MUC database. Provided types: derby, mysql, memory, pgsql, sqlserver, none.

muc {
    'history-db' = 'pgsql'
}
  • history-db-uri
    URI for database, if should be used if you want a separate MUC database:

muc {
    'history-db-uri' = 'jdbc:derby:/database/tigasedbmuc'
}
Public log
  • muc-logger-class
    Used to set a custom class for MUC logger:

muc {
    'muc-logger-class' = 'com.example.CustomLogger'
}

Class must implement interface tigase.muc.logger.MucLogger.

Modules

Each module can be configured to use a custom implementation by including it in the config.tdsl, the defaults are as follows:

muc {
    modules {
        admin = 'tigase.muc.modules.ModeratorModule'
        commands = 'tigase.component.modules.impl.AdHocCommandModule'
        disco = 'tigase.muc.modules.DiscoveryModule'
        groupchat = 'tigase.muc.modules.GroupchatMessageModule'
        invitations = 'tigase.muc.modules.MediatedInvitationModule'
        iqforwarder = 'tigase.muc.modules.IqStanzaForwarderModule'
        jabber = 'iq:version[S]=tigase.component.modules.impl.JabberVersionModule'
        owner = 'tigase.muc.modules.RoomConfigurationModule'
        presences = 'tigase.muc.modules.PresenceModuleImpl'
        privatemessages = 'tigase.muc.modules.PrivateMessageModule'
        unique = 'tigase.muc.modules.UniqueRoomNameModule'
        urn = 'xmpp:ping[S]=tigase.component.modules.impl.XmppPingModule'
    }
}
Room Configuration options

In addition to the default Room configuration options defined in the MUC specification Tigase offers following as well:

Tigase MUC Options
  • tigase#presence_delivery_logic - allows configuring logic determining which presence should be used by occupant in the room while using multiple-resource connections under one nickname, following options are available:

    • PREFERE_PRIORITY

    • PREFERE_LAST

  • tigase#presence_filtering - (boolean) when enabled broadcasts presence only to selected affiliation groups

  • tigase#presence_filtered_affiliations - when enabled tigase#presence_filtering is enabled one can select affiliation which should receive presences, following are possible to select from:

    • owner

    • admin

    • member

    • none

    • outcast

  • muc#roomconfig_maxusers - Allows configuring of maximum users of room.

Configuring default room configuration in config.tdsl
muc {
    'default_room_config' {
        'Option' = 'value'
    }
}

for example:

muc {
    default_room_config {
        'tigase#presence_delivery_logic' = 'PREFERE_LAST'
    }
}
Configuration per-room

Per room configuration is done using IQ stanzas defined in the specification, for example:

<iq type="set" to="roomname@muc.domain" id="config1">
    <query xmlns="http://jabber.org/protocol/muc#owner">
        <x xmlns="jabber:x:data" type="submit">
            <field type="boolean" var="tigase#presence_filtering">
                <value>1</value>
            </field>
            <field type="list-multi" var="tigase#presence_filtered_affiliations">
                <value>owner</value>
            </field>
        </x>
    </query>
</iq>

10.10. Tigase Load Balancing

Tigase includes load balancing functionality allowing users to be redirected to the most suitable cluster node. Functionality relies on a see-other-host XMPP stream error message. The basic principle behind the mechanism is that user will get redirect if the host returned by the implementation differ from the host to which user currently tries to connect. It is required that the user JID to be known for the redirection to work correctly.

10.10.1. Available Implementations

Tigase implementation is, as usual, extensible and allows for different, pluggable redirection strategies that implement the SeeOtherHostIfc interface.

Currently there are three strategies available:

  • SeeOtherHost - most basic implementation returning either single host configured in config.tdsl file or name of the current host;

  • SeeOtherHostHashed (default) - default implementation for cluster environment of SeeOtherHostIfc returning redirect host based on the hash value of the user’s JID; list of the available nodes from which a selection would be made is by default composed and reflects all connected nodes, alternatively hosts list can be configured in the config.tdsl;

  • SeeOtherHostDB - extended implementation of SeeOtherHost using redirect information from database in the form of pairs user_id and node_id to which given user should be redirected.

10.10.2. Configuration Options

The most basic configuration is related to the choice of actual redirection implementation by declaring class for each connector:

bosh {
    seeOtherHost (class: <value>) {}
}
c2s {
    seeOtherHost (class: <value>) {}
}
ws2s {
    seeOtherHost (class: <value>) {}
}

Possible values are:

  • tigase.server.xmppclient.SeeOtherHost

  • tigase.server.xmppclient.SeeOtherHostHashed

  • tigase.server.xmppclient.SeeOtherHostDB

  • tigase.server.xmppclient.SeeOtherHostDualIP

  • none - disables redirection

All options are configured on a per-connection-manager basis, thus all options need to be prefixed with the corresponding connection manager ID, i.e. c2s, bosh or ws; we will use c2s in the examples:

c2s {
    'cm-see-other-host' {
        'default-host' = 'host1;host2;host3'
        'phases' = [ 'OPEN', 'LOGIN' ]
    }
}
  • 'default-host' = 'host1;host2;host3' - a semicolon separated list of hosts to be used for redirection.

  • 'phases' = - a semicolon separated list of phases in which redirection should be active, currently possible values are:

    • OPEN which enables redirection during opening of the XMPP stream;

    • LOGIN which enables redirection upon authenticating user session;

By default redirection is currently enabled only in the OPEN phase.

SeeOtherHostDB

For SeeOtherHostDB implementation there are additional options:

c2s {
    'cm-see-other-host' {
        'db-url' = 'jdbc:mysqk://localhost/username?,password?'
        'get-all-query-timeout' = '10'
    }
}
  • db-url - a JDBC connection URI which should be used to query redirect information; if not configured the default dataSource will be used;

  • get-host-query - a SQL query which should return redirection hostname;

  • get-all-data-query - a SQL helper query which should return all redirection data from database;

  • get-all-query-timeout - allows to set timeout for executed queries.

SeeOtherHostDualIP

This mechanisms matches internal Tigase cluster nodes with against the lookup table to provide matching and relevant redirection hostname/IP. By default internal Tigase tig_cluster_nodes table will be used (and appropriate repository implementation will be used).

To enable this redirection mechanism following configuration / class should be used. Note that for global use, all connection managers must have the same class defined. You can define each connection manager individually.

bosh {
    seeOtherHost (class: tigase.server.xmppclient.SeeOtherHostDualIP) {}
}
c2s {
    seeOtherHost (class: tigase.server.xmppclient.SeeOtherHostDualIP) {}
}
ws2s {
    seeOtherHost (class: tigase.server.xmppclient.SeeOtherHostDualIP) {}
}

It offers following configuration options:

  • data-source - configuration of the source of redirection information - by default internal Tigase tig_cluster_nodes table will be used (and appropriate repository implementation will be used); alternatively it’s possible to use eventbus source;

  • db-url - a JDBC connection URI which should be used to query redirect information; if not configured user-db-uri will be used;

  • get-all-data-query - a SQL helper query which should return all redirection data from database;

  • get-all-query-timeout - allows to set timeout for executed queries;

  • fallback-redirection-host - if there is no redirection information present (i.e. secondary hostname is not configured for the particular node) redirection won’t be generated; with this it’s possible to configure fallback redirection address.

All options are configured or on per-component basis:

<connector> {
    'cm-see-other-host' {
        'data-source' = '<class implementing tigase.server.xmppclient.SeeOtherHostDualIP.DualIPRepository>'
        'db-url' = 'jdbc:<database>://<uri>'
        'fallback-redirection-host' = '<hostname>'
        'get-all-data-query' = 'select * from tig_cluster_nodes'
        'get-all-query-timeout' = 10
    }
}
EventBus as a source of information

It’s possible to utilize EventBus and internal Tigase events as a source of redirection data. In order to do that eventbus should be used as a value of data-source configuration option. In addition, EventBus events needs to be enabled in ClusterConnectionManager or on per-component basis:

<connector> {
    seeOtherHost (class: {data-source=eventbus}) {}
    }
}
'cl-comp' {
    'eventbus-repository-notifications' = true
}

10.10.3. Auxiliary setup options

Enforcing redirection

It’s possible to enforce redirection of connections on the particular port of connection manager with force-redirect-to set to Integer with the following general setting option:

<connection_manager> {
    connections {
        <listening_port> {
            'force-redirect-to' = <destination_port>
        }
    }
}

for example, enable additional port 5322 for c2s connection manager and enforce all connections to be redirected to port 5222 (it will utilize hostname retrieved from SeeOtherHost implementation and will be only used when such value is returned):

c2s {
    connections {
        ports = [ 5222, 5322 ]
        5322 {
            'force-redirect-to' = 5222
            socket = 'plain'
            type = 'accept'
        }
    }
}
Configuring hostnames

To fully utilize SeeOtherHostDualIP setup in automated fashion it’s now possible to provide both primary (internal) and secondary (external) hostname/IP (they need to be correct, InetAddress.getByName( property ); will be used to verify correctness). It can be done via JVM properties tigase-primary-address and tigase-secondary-address. You can also utilize different implementation of DNS resolver by providing class implementing tigase.util.DNSResolverIfc interface as value to resolver-class property. Those properties can be set via etc/tigase.conf (uncommenting following lines, or manually exposing in environment):

DNS_RESOLVER=" -Dresolver-class=tigase.util.DNSResolverDefault "

INTERNAL_IP=" -Dtigase-primary-address=hostname.local "
EXTERNAL_IP=" -Dtigase-secondary-address=hostname "

or in the etc/config.tdsl (they will be converted to JVM properties):

'dns-resolver' {
    'tigase-primary-address' = 'hostname.local'
    'tigase-resolver-class' = 'tigase.util.DNSResolverDefault'
    'tigase-secondary-address' = 'hostname'
}

10.11. External Component Configuration

Tigase can connect to external components, this guide will show you how this can be accomplished.

Configuration follows the same standards as all other components. It is also much more powerful as a single Tigase instance can control many TCP/IP ports and many external components on each port and even allows for multiple connections for the same component. It supports both XEP-0114 and XEP-0225 with protocol auto-detection mechanisms. Protocols are pluggable so more protocols can be supported or custom extensions to existing protocols can be added.

The implementation also supports a scripting API and new domains with passwords can be added at run-time using ad-hoc commands. New scripts can be loaded to even further control all connected external components.

Pages in this guide describe in details all the administration aspects of setting up and managing external components.

10.11.1. External Component Configuration

As for all Tigase components you can load and configure external components via the config.tdsl file described in details in the DSL configuration section. This document describes how to load the component and set the initial configuration to accept or initiate connections for an external component.

First thing to do is to specify the component class and the component name which must be unique within the Tigase installation. The most commonly name used is ext and the class is tigase.server.ext.ComponentProtocol which does not need to be specified.

The following line in the config.tdsl will load the component during the server startup time:

ext (class: tigase.server.ext.ComponentProtocol) {}

While this would load the component, there are no additional configurations provided to the component would be practically useless. It is possible to add necessary parameters (external domains, passwords) during run-time via ad-hoc commands. It is generally a good practice to provide some initial parameters in the configuration file too.

You may additionally configure this with the bind-ext-hostnames property.

Simple Case

The most common scenario is to connect an external component which works for a specific given domain to the main server. The component authenticates with a defined password and the external component connects to a TCP/IP port the server listens on.

For example let’s say our server works for a virtual domain: devel.tigase.org. We want it to listen on port 5270 for incoming connections from an external component working for a domain: muc.devel.tigase.org. The authentication password for the domain is muc-secret.

For such a scenario we need the following configured:

ext (class: tigase.server.ext.ComponentProtocol) {
    repository {
        items = [ 'muc.devel.tigase.org:muc-secret:listen:5270' ]
    }
}
More External Components/Domains

Suppose you want to connect more than one external component. Let’s say you want to connect PubSub and MSN components to Tigase server as well.

In that case you don’t have to open another port on the server, all the components can connect to the same port. Of course each of the components connect for a different domain and probably should use a different password.

Let’s say then that we want Tigase server accept two more domains with corresponding passwords: (pubsub.devel.tigase.org:pubsub_pass) and (msn.devel.tigase.org:msn_pass). Your configuration properties should look like this:

ext (class: tigase.server.ext.ComponentProtocol) {
    repository {
        items = [ 'muc.devel.tigase.org:muc-secret:listen:5270', 'pubsub.devel.tigase.org:pubsub_pass', 'msn.devel.tigase.org:msn_pass' ]
    }
}

Please note, each configuration item property should be written in a single line.

More TCP/IP Ports

You can make Tigase listen on more than one TCP/IP port for incoming external component connections. Please be aware that there is no way, currently to bind an external component to a particular port. If Tigase listens on two or more ports it accepts any external component on any of the ports. Therefore there is no practical reason for opening more than one port.

However, if for some reason you need Tigase to listen on more ports then this is an example configuration:

ext (class: tigase.server.ext.ComponentProtocol) {
    repository {
        items = [ 'muc.devel.tigase.org:muc-secret:listen:5270', 'pubsub.devel.tigase.org:pubsub_pass:listen?:5271', 'msn.devel.tigase.org:msn_pass:listen:5272' ]
    }
}

Please note, each configuration item property should be written in a single line.

These settings set three TCP/IP ports to listen on: 5270, 5271 and 5272. They also specify 3 different external domains with passwords which are accepted by Tigase. Even though each port is specified with conjunction with a domain they are not bound together in any way. Any of specified domains can connect through any of specified ports.

Outgoing Connections

Tigase server can not only accept connections from external components, it can also open connections to external components.

To make Tigase connect to an external component you have to change listen parameter to connect and of course you have to tell where to connect - the address of the external component:

ext (class: tigase.server.ext.ComponentProtocol) {
    repository {
        items = [ 'devel.tigase.org:muc-secret:connect:5270:muc.devel.tigase.org' ]
    }
}

Assuming the MUC component listens on the port '5270' at the DNS address: 'muc.devel.tigase.org' Tigase will connect to the component.

You can of course set as many as you need external components to which you want Tigase to connect to:

ext (class: tigase.server.ext.ComponentProtocol) {
    repository {
        items = [ 'devel.tigase.org:mucsecret:connect:5270:muc.devel.tigase.org', 'devel.tigase.org:pubsub_pass:connect:5271:pubsub.devel.tigase.org', 'devel.tigase.org:msn_pass:connect:5272:msn.devel.tigase.org' ]
    }
}

If external components run on a separate machines you can use the same port number for each of them.

Specifying Protocol

One of the last parameters you can set for the external component/domain is a protocol which should be used for the connection. At the moment the Tigase server supports two protocols defined in XEP-0114 and XEP-0225 and possibly further protocols.

You don’t have to specify a protocol if you setup a connection in listen mode as the server automatically detects a protocol which is used in incoming connections.

You can specify the protocol which is used for outgoing connections but you have to add one more parameters to the connection string.

There are two possibilities:

  1. accept which is an identifier for protocol defined in XEP-0114 (and is default if you do not specify anything).

  2. client which is identifier for protocol defined in XEP-0225 and is based on the client-to-server protocol.

An example configuration with protocol specified:

ext (class: tigase.server.ext.ComponentProtocol) {
    repository {
        items = [ 'devel.tigase.org:mucsecret:connect:5270:muc.devel.tigase.org:accept', 'devel.tigase.org:pubsub_pass:connect:5270:pubsub.devel.tigase.org:client' ]
    }
}

It defines two outgoing connections to external protocols, the first uses the XEP-0114 protocol and the second uses the XEP-0225 protocol.

Load Balancer Plugin

With the penultimate option you can set for external component connections is load balancer class.

The load balancer plugin is used if you have multiple connections for the same component (external domain name) and you want to spread the load over all connections. Perhaps you have an installation with huge number of MUC rooms and you want to spread the load over all MUC instances.

An example configuration with load balancer plugin specified:

ext (class: tigase.server.ext.ComponentProtocol) {
    repository {
        items = [ 'muc.devel.tigase.org:mucsecret:listen:5270:devel.tigase.org:accept:ReceiverBareJidLB', 'pubsub.devel.tigase.org:pubsub_pass:listen:5270:devel.tigase.org:accept:SenderBareJidLB' ]
    }
}

It defines two listeners for external component with different load balancer plugins. The first load-balance traffic by a packet destination BareJID, which makes sense for MUC component. This way each MUC instance handles a different set of rooms which allows for a good load distribution.

For the PubSub component we use a different load balancer plugin which distributes load by the sender BareJID instead. This is because for the PubSub destination BareJID is always the same so we cannot use it to distribute the load.

Either the ReceiverBareJidLB or SenderBareJidLB are class names from package: tigase.server.ext.lb however, you can use any class name as a plugin, you just have to provide a full class name and the class name must implement LoadBalancerIfc interface.

Encrypting connection

With the last option you can set type of the socket connection.

Following options are available: . plain - will create a plain socket (accepting unencrypted or TLS connections) . tls - will create a plain type socket, which enforces performing StartTLS . ssl - will create an SSL socket (only accepting SSL connections)

An example configuration with socket type specified:

ext (class: tigase.server.ext.ComponentProtocol) {
    repository {
        items = [ 'muc.devel.tigase.org:mucsecret:listen:5270:devel.tigase.org:accept:ReceiverBareJidLB:plain', 'pubsub.devel.tigase.org:pubsub_pass:listen:5270:devel.tigase.org:accept:SenderBareJidLB:ssl' ]
    }

for the MUC component it will be possible to establish plain socket connection (with possibility to perform StartTLS) and for the PubSub component an encrypted, SSL connection will be required.

10.11.2. Tigase as an External Component

There are cases when you want to deploy one or more Tigase components separately from the main server, or perhaps you want to run some Tigase components connecting to a different XMPP server, or perhaps you work on a component and you do not want to restart the main server every time you make a change.

There is a way to run the Tigase server in "external component mode". In fact you can run any of Tigase’s components as an external component and connect them to the main XMPP server either via XEP-0114 or XEP-0225 connection.

Let’s look at the examples…​

A Simple Case - MUC as an External Component

A few assumptions:

  1. We want to run a MUC component for a domain: muc.devel.tigase.org and password muc-pass

  2. The main server works at an address: devel.tigase.org and for the same virtual domain

  3. We want to connect to the server using XEP-0114 protocol and port 5270.

There is a special configuration type for this case which simplifies setting needed to run Tigase as an external component:

'config-type' = 'component'

This generates a configuration for Tigase with only one component loaded by default - the component used for external component connection. If you use this configuration type, your config.tdsl file may look like this:

admins = [ 'admin@devel.tigase.org' ]
'config-type' = 'component'
debug = [ 'server' ]
'virtual-hosts' = [ 'devel.tigase.org' ]
dataSource {
    default () {
        uri = 'jdbc:derby:/tigasedb'
    }
}
userRepository {
    default () {}
}
authRepository {
    default () {}
}
muc (class: tigase.muc.MUCComponent) {}
ext () {
    items = [ 'muc.devel.tigase.org:muc-pass:connect:5270:devel.tigase.org:accept' ]
}
More Components

Suppose you want to run more than one component as an external components within one Tigase instance. Let’s add another - PubSub component to the configuration above and see how to set it up.

The most straightforward way is just to add another component and another connection to the main server for the component domain:

admins = [ 'admin@devel.tigase.org' ]
'config-type' = 'component'
debug = [ 'server' ]
'virtual-hosts' = [ 'devel.tigase.org' ]
dataSource {
    default () {
        uri = 'jdbc:derby:/tigasedb'
    }
}
userRepository {
    default () {}
}
authRepository {
    default () {}
}
muc (class: tigase.muc.MUCComponent) {}
pubsub (class: tigase.pubsub.PubSubComponent) {}
ext () {
    items = [ 'muc.devel.tigase.org:muc-pass:connect:5270:devel.tigase.org:accept', 'pubsub.devel.tigase.org:pubsub-pass:connect:5270:devel.tigase.org:accept' ]
}

Please note however that we are opening two connections to the same server. This can waste resources and over-complicate the system. For example, what if we want to run even more components? Opening a separate connection for each component is a tad overkill.

In fact there is a way to reuse the same connection for all component domains running as an external component. The property bind-ext-hostnames contains a comma separated list of all hostnames (external domains) which should reuse the existing connection.

There is one catch however. Since you are reusing connections (hostname binding is defined in XEP-0225 only), you must use this protocol for the functionality.

Here is an example configuration with a single connection over the XEP-0225 protocol used by both external domains:

admins = [ 'admin@devel.tigase.org' ]
'bind-ext-hostnames' = [ 'pubsub.devel.tigase.org' ]
'config-type' = 'component'
debug = [ 'server' ]
'virtual-hosts' = [ 'devel.tigase.org' ]
dataSource {
    default () {
        uri = 'jdbc:derby:/tigasedb'
    }
}
ext () {
    items = [ 'muc.devel.tigase.org:muc-pass:connect:5270:devel.tigase.org:client' ]
}
userRepository {
    default () {}
}
authRepository {
    default () {}
}
muc (class: tigase.muc.MUCComponent) {}
pubsub (class: tigase.pubsub.PubSubComponent) {}

10.12. Load Balancing External Components in Cluster Mode

This document describes how to load balance any external components using Tigase XMPP Server and how to make Tigase’s components work as external components in a cluster mode.

Please note, all configuration options described here apply to Tigase XMPP Server version 5.1.0 or later.

These are actually 2 separate topics:

  1. One is to distribute load over many instances of a single component to handle larger traffic, or perhaps for high availability.

  2. The second is to make Tigase’s components work as an external component and make it work in a cluster mode, even if the component itself does not support cluster mode.

Here are step by step instructions and configuration examples teaching how to achieve both goals.

10.12.1. Load Balancing External Component

The first, and most simple scenario is to connect multiple instances of an external component to a single Tigase XMPP Server to distribute load.

There are at least 2 reasons why this would be an optimal solution: one would be to spread load over more instances/machines and the second is to improve reliability in case one component fails the other one can take over the work.

So here is a simple picture showing the use case.

ExternalCompClustering002

We have a single machine running Tigase XMPP Server and 2 instances of the MUC component connecting to Tigase.

The server configuration

admins = [ 'admin@devel.tigase.org' ]
'config-type' = 'default'
'virtual-hosts' = [ 'devel.tigase.org' ]
dataSource {
    default () {
        uri = 'jdbc:mysql://localhost/db?user=tigase&password=tigase'
    }
}
userRepository {
    default () {}
}
authRepository {
    default () {}
}
ext (class: tigase.server.ext.ComponentProtocol) {
    repository {
        items = [ 'muc.devel.tigase.org:muc-secret:listen:5270:devel.tigase.org:accept:ReceiverBareJidLB' ]
    }
}
'sess-man' () {}

And configuration for both instances of the MUC component (identical for both of them):

admins = [ 'admin@devel.tigase.org' ]
'config-type' = 'component'
'virtual-hosts' = [ 'devel.tigase.org' ]
dataSource {
    default () {
        uri = 'jdbc:mysql://localhost/db?user=tigase&password=tigase'
    }
}
userRepository {
    default () {}
}
authRepository {
    default () {}
}
muc (class: tigase.muc.MUCComponent) {}

For those familiar with Tigase’s configuration, this should be pretty basic. The difference is one small element in the server configuration. At the end of the component connection we have ReceiverBareJidLB.

This is the load balancing plugin class. Load balancing plugin decides how the traffic is distributed among different component connections that is different component instances. For the MUC component it makes sense to distribute the traffic based on the receiver bare JID because this is the MUC room address. This way we just distribute MUC rooms and traffic over different MUC component instances.

This distribution strategy does not always work for all possible components however. For transports for example this would not work at all. A better way to spread load for transports would be based on the source bare JID. And it is possible if you use plugin with class name: SenderBareJidLB.

This are two basic load distribution strategies available now. For some use cases none of them is good enough. If you have PubSub, then you probably want to distribute load based on the PubSub node. There is no plugin for that yet but it is easy enough to write one and put the class name in configuration.

10.12.2. External Component and Cluster

If you want to use Tigase’s component in a cluster mode which does not have clustering implemented yet there is a way to make it kind of cluster-able. In the previous section we connected many MUC components to a single Tigase server. Now we want to connect a single MUC component to many Tigase servers (or many Tigase cluster nodes).

Let’s say we have Tigase XMPP Server working for domain: xmpp-test.org and the server is installed on three cluster nodes: red.xmpp-test.org, green.xmpp-test.org and blue.xmpp-test.org.

ExternalCompClustering003_0

We want to make it possible to connect the MUC component to all nodes, so here is configuration for the server (for each node is the same):

admins = [ 'admin@xmpp-test.org' ]
'cluster-mode' = true
'cluster-nodes' = [ 'red.xmpp-test.org', 'green.xmpp-test.org', 'blue.xmpp-test.org' ]
'config-type' = 'default'
'virtual-hosts' = [ 'xmpp-test.org' ]
dataSource {
    default () {
        uri = 'jdbc:mysql://localhost/db?user=tigase&password=tigase'
    }
}
userRepository {
    default () {}
}
authRepository {
    default () {
        cls = 'tigase.db.jdbc.TigaseAuth'
    }
}
ext (class: tigase.server.ext.ComponentProtocol) {
    repository {
        items = [ 'muc.xmpp-test.org:muc-secret:listen:5270:xmpp-test.org:accept:ReceiverBareJidLB' ]
    }
}
'sess-man' () {}

As you can see there is nothing special here. The most interesting part comes on the MUC side.

admins = [ 'admin@xmpp-test.orgg' ]
'config-type' = 'component'
'virtual-hosts' = [ 'xmpp-test.org' ]
dataSource {
    default () {
        uri = 'jdbc:mysql://localhost/db?user=tigase&password=tigase'
    }
}
userRepository {
    default () {}
}
authRepository {
    default () {}
}
ext (class: tigase.server.ext.ComponentProtocol) {
    repository {
        items = [ 'muc.xmpp-test.org:muc-secret:connect:5270:xmpp-test.org', 'blue.xmpp-test.org', 'green.xmpp-test.org', 'red.xmpp-test.org:accept' ]
    }
}
muc (class: tigase.muc.MUCComponent) {}

As you can see remote host name is not a simple domain but a character string with a few comma separated parts. The first part is our remote domain and the rest are addresses of the host to connect to. This can be a list of domain names or IP addresses.

Of course it is possible to connect multiple external component to all cluster nodes, this way the whole installation would be really working in the cluster and also load balanced.

10.13. Client to Server Communication

Client to server communication is an integral part of XMPP communication. C2S handles all client communication to the server, and is responsible for filtering and handling remote communications. C2S CAN be disabled, however doing so will only allow communication of internal components, and S2S communications.

10.13.1. Configuration

To disable C2S, use the following line in config.tdsl folder.

c2s (active: false) {}

Otherwise, C2S component is activated by default.

10.13.2. Connections

The connections container houses all configuration related to connections with the component. Each port may be configured individually.

c2s {
    connections {
        5222 {
            <configuration>
        }
        5080 {
            <configuration>
        }
    }
}
new-connections-throttling

The property allows you to limit how many new users' connection per second the server accepts on a particular port. Connections established within the limit are processed normally, all others are simply disconnected. This allows you to avoid server overload in case there is a huge number of users trying to connect at the same time. Mostly this happens after a server restart.

c2s {
    connections {
        5222 {
            'new-connections-throttling' = 150L
        }
    }
}

Here, this limits the number to 150 connections per second before connection attempts are dropped.

This replaces the old --new-connections-throttling property.

10.13.3. Resumption timeout

It is now possible to set a default stream resumption timeout that the server uses. This allows control of how long a server will wait for a reconnection from a client. This can be particularly helpful to manage mobile clients connecting to your server as they may not have complete coverage, and you do not want to close the stream right away. By default, Tigase sets this value to 60 seconds.

c2s {
    'urn:xmpp:sm:3' {
        'resumption-timeout' = 90
    }
}

This sets the default timeout to 90 seconds. You may, if you choose, specify a maximum timeout time, which will allow the server to wait between the default and maximum before a connection is closed.

c2s {
    'urn:xmpp:sm:3' {
        'max-resumption-timeout' = 900
    }
}
Note
If the max-resumption-timeout is not set, it will always equal the resumption-timeout number, or default is none is set.

Available since v7.1.0

10.13.4. Packet Redelivery

Normally packets are handled by C2S and are typically processed in the first run, however if that fails to send, a retry of sending that packet will occur after 60 seconds. If that second try fails, the delay will increase by a factor of 1.5. This means that the next retry will occur at 90, 135, and so on until the retry count is reached. By default this count is 15, however it can be changed by using the following setting:

c2s {
    'packet-deliver-retry-count' = '20'
}

This setting prevents packet redelivery attempts from continuing into infinity (or when the host machine runs out of memory).

10.14. Tigase Socks5 Proxy

Welcome to Tigase Socks5 Proxy guide

Tigase SOCKS5 component allows for file transfers to be made over a SOCKS5 proxy in accordance with XEP-0065 SOCKS5 Bytestreams. This allows for some useful features such as: - transfer limits per user, domain, or global - recording transfers between users - quotas and credits system implementation

10.14.1. Overview

Tigase Socks5 Proxy is implementation of Socks5 proxy described in XEP-0065: SOCKS5 Bytestreams, in section 6. Mediated Connection which provides support for Socks5 proxy for file transfers between XMPP client behind NATs to Tigase XMPP Server.

Installation

Tigase SOCKS5 component comes built into the dist-max archives for Tigase XMPP server, and requires the component to be listed in config.tdsl file:

proxy {}

You will also need to decide if you wish to use database-based features or not. If you wish to simply run the socks5 proxy without features such as quotas, limits add the following line:

proxy {
    'verifier-class' = 'tigase.socks5.verifiers.DummyVerifier'
}

This will enable the SOCKS5 Proxy without any advanced features. If you wish to use those features, see the configuration section below.

Database Preparation

In order to use the more advanced features of the SOCKS5 Proxy Component, your database needs to be prepared with the proper schema prior to running the server.

You may either edit an existing database, or create a new database for specific use with the Proxy.

Edit Existing Database

You can add the proper schema to your existing database using the DBSchemaLoader utility included with Tigase. The database folder contains the schema file for your type of database.

First, backup your database before performing any actions and shut down Tigase XMPP Server.

Then from the Tigase installation directory run the following command:

java -cp "jars/*" tigase.db.util.DBSchemaLoader -dbType {derby,mysql,postgresql,sqlserver} - dbHostname {db address} -dbName {dbname} -rootUser root -rootPass root -file database/{dbtype}-socks5-schema.sql

You should see the following dialogue

LogLevel: CONFIG
tigase.db.util.DBSchemaLoader     	 <init>          	 CONFIG     Properties: [{dbHostname=localhost, logLevel=CONFIG, dbType=derby, file=database/derby-socks5-schema.sql, rootUser=root, dbPass=tigase_pass, dbName=tigasedb, schemaVersion=7-1, rootPass=root, dbUser=tigase_user}]
tigase.db.util.DBSchemaLoader     	 validateDBConnection 	 INFO       Validating DBConnection, URI: jdbc:derby:tigasedb;create=true
tigase.db.util.DBSchemaLoader     	 validateDBConnection 	 CONFIG     DriverManager (available drivers): [[jTDS 1.3.1, org.apache.derby.jdbc.AutoloadedDriver@34a245ab, com.mysql.jdbc.Driver@3941a79c, org.postgresql.Driver@6e2c634b]]
tigase.db.util.DBSchemaLoader     	 validateDBConnection 	 INFO       Connection OK
tigase.db.util.DBSchemaLoader     	 validateDBExists 	 INFO       Validating whether DB Exists, URI: jdbc:derby:tigasedb;create=true
tigase.db.util.DBSchemaLoader     	 validateDBExists 	 INFO       Exists OK
tigase.db.util.DBSchemaLoader     	 loadSchemaFile  	 INFO       Loading schema from file: database/derby-socks5-schema.sql, URI: jdbc:derby:tigasedb;create=true
tigase.db.util.DBSchemaLoader     	 loadSchemaFile  	 INFO        completed OK
tigase.db.util.DBSchemaLoader     	 shutdownDerby   	 INFO       Validating DBConnection, URI: jdbc:derby:tigasedb;create=true
tigase.db.util.DBSchemaLoader     	 shutdownDerby   	 WARNING    Database 'tigasedb' shutdown.
tigase.db.util.DBSchemaLoader     	 printInfo       	 INFO

One this process is complete, you may begin using SOCKS5 proxy component.

Create New Database

If you want to create a new database for the proxy component and use it as a separate socks5 database, create the database using the appropriate schema file in the database folder. Once this is created, add the following line to your config.tdsl folder.

proxy {}

For example, a mysql database will have this type of URL: jdbc:mysql://localhost/SOCKS?user=root&password=root to replace database URL. For more options, check the database section of this documentation.

10.14.2. Configuration

Enabling proxy

To enable Tigase Socks5 Proxy component for Tigase XMPP Server, you need to activate socks5 component in Tigase XMPP Server configuration file (etc/config.tdsl). In simples solution it will work without ability to enforce any limits but will also work without a need of database to store informations about used bandwidth.

Simple configuration
socks5 () {
    repository {
            default () {
                cls = 'dummy'
            }
    }
}
remote-addresses
proxy {
    'remote-addresses' = '192.168.1.205,20.255.13.190'
}

Comma seperated list of IP addresses that will be accessible VIA the Socks5 Proxy. This can be useful if you want to specify a specific router address to allow external traffic to transfer files using the proxy to users on an internal network.

Port settings

If socks5 is being used as a proxy, you may configure a specific ports for the proxy using the following line in config.tdsl:

proxy {
    'connections' {
        'ports' = [ 1080 ]
      }
}
Enabling limits

To enable limits you need to import schema files proper for your database and related to Tigase Socks5 Proxy component from database directory. To do this, refer to the previous section.

With that setup, it is possible to enable limits verifier by replacing entries related to Tigase Socks5 Proxy component configuration with following entries. This will use default database configured to use with Tigase XMPP Server.

DummyVerifier
  • Class Name: tigase.socks5.verifiers.DummyVerifier

This accepts file transfers VIA SOCKS5 proxy from any user and does not check limitations against the database.

socks5 () {
    verifier (class: tigase.socks5.verifiers.DummyVerifier) {
    }
}
LimitsVerifier
  • Class Name: tigase.socks5.verifiers.LimitsVerifier

Uses the database to store limits and record the amount of data transferred VIA the proxy.

Configuring limits

Following properties are possible to be set for LimitsVerifier:

proxy {
    'verifier-class' = 'tigase.socks5.verifiers.LimitsVerifier'
    tigase.socks5.verifiers.LimitsVerifier {
        'transfer-update-quantization' = '1000'
        'instance-limit' = '3000'
    }
}

Parameters for LimitsVerifier which will override the defaults. All of these limits are on a per calendar month basis. For example, a user is limited to 10MB for all transfers. If he transfers 8MB between the 1st and the 22nd, he only has 2MB left in his limit. On the 1st of the following month, his limit is reset to 10MB.

Available parameters:

  • transfer-update-quantization which value is used to quantitize value to check if value of transferred bytes should be updated in database or not. By default it is 1MB. (Low value can slow down file transfer while high value can allow to exceed quota)

  • global-limit - Transfer limit for all domains in MB per month.

  • instance-limit - Transfer limit for server instance in MB per month.

  • default-domain-limit - The Default transfer limit per domain in MB per month.

  • default-user-limit - The default transfer limit per user in MB per month.

  • default-file-limit - The default transfer limit per file in MB per month.

Note
Low values can slow down file transfers, while high values can allow for users to exceed quotas.
Individual Limits

Using the default database schema in table tig_socks5_users limits can be specified for individual users.

Value of the field user_id denotes the scope of the limitation:

  • domain_name defines limits for users which JIDs are within that domain;

  • JID of the user defines limit for this exact user.

Value of the limit bigger than 0 defines an exact value. If value is equal 0 limit is not override and more global limit is used. If value equals -1 proxy will forbid any transfer for this user. It there is no value for user in this table new row will be created during first transfer and limits for domain or global limits will be used.

Socks5 database is setup in this manner:

Table 5. tig_socks5_users
uid user_id sha1_user_id domain sha1_domain filesize_limit transfer_limit_per_user transfer_limit_per_domain

1

user@domain.com

c35f2956d804e01ef2dec392ef3adae36289123f

domain.com

e1000db219f3268b0f02735342fe8005fd5a257a

0

3000

0

2

domain.com

e1000db219f3268b0f02735342fe8005fd5a257a

domain.com

e1000db219f3268b0f02735342fe8005fd5a257a

500

0

0

This example table shows that user@domain.com is limited to 3000MB per transfer whereas all users of domain.com are limited to a max file size of 500MB. This table will populate as users transfer files using the SOCKS5 proxy, once it begins population, you may edit it as necessary. A second database is setup tig_socks5_connections that records the connections and transmissions being made, however it does not need to be edited.

Using a separate database

To use separate database with Tigase Socks5 Proxy component you need to configure new DataSource in dataSource section. Here we will use socks5-store as name of newly configured data source. Additionally you need to pass name of newly configured data source to dataSourceName property of default repository of Tigase Socks5 Proxy component.

dataSource {
    socks5-store () {
        uri = 'jdbc:db_server_type://server/socks5-database'
    }
}

socks5 () {
    repository {
        default () {
            dataSourceName = 'socks5-store'
        }
    }
    ....
}

10.14.3. Performance

Tigase Socks5 Proxy component was tested with 100 concurrent transfers. Maximal traffic processed by component was 21,45MB/s on loopback interface. All XMPP clients and Tigase XMPP Server used in test were running on the single machine.

10.15. Tigase External Service Discovery

Welcome to the Tigase External Service Discovery component user guide. Component provides support for XEP-0215: External Service Discovery which allows discovery of external services which are not accessible using XMPP protocol.

10.15.1. Setup & Configuration

Component (which is implemented in class tigase.server.extdisco.ExternalServiceDiscoveryComponent) is by default registered under name ext-disco and disabled. To enable it you need to enable it in configuration. Example:

  • in DSL format:

ext-disco () { }

Additionally you need to activate urn:xmpp:extdisco:2 XMPP processor in SessionManager by:

  • in DSL - enable subbean of @sess-man@:

sess-man {
    'urn:xmpp:extdisco:2'() {}
}

List of external services returned by server is configurable in configuration file or using adhoc commands provided for this component. AdHoc commands are accessible only for server administrator using XMPP client with support for AdHoc commands or using Tigase Admin UI. Usage of AdHoc commands provides easiest and flexible way to add, modify or remove entries for services which will be returned by discovery.

Example

Example of custom configuration with 2 services being registered in configuration file. Each service entry consists of internal id followed by : separated list of properties, in form name=value. Allowed properties are listed with description in XEP-0215: External Service Discovery - Section 2. Protocol in Table 1: Attributes :

  • in DSL:

sess-man {
    'urn:xmpp:extdisco:2'() {}
}

ext-disco () {
    externalServiceDiscoveryRepository {
        items = [
            "TURN server (TCP):host=turn.example.com:type=turn:name=TURN Server:transport=tcp",
            "FTP server:host=ftp.example.com:port=21:type=ftp:name=FTP Server:transport=tcp"
        ]
    }
}

10.16. Tigase Push Component

Welcome to Tigase Push component guide

10.16.1. Tigase Push Component

Tigase Push component is a Push notifications component implementing XEP-0357: Push Notifications. It is a gateway between Push Notification services and XMPP servers. It is configured by default to run under name of push.

Note
Tigase Push component requires at the minimum version 8.0.0 of Tigase XMPP Server.

Push notifications enable messages and pertinent information for clients, even if they are offline as long as they are registered with the push service. Tigase Messenger for iOS and Tigase Messenger for Android both have support for this feature.

Workflow

The workflow for enabling and using push notifications works as follows:

Enabling notifications

In order to receieve notifications, clients will require registration with a push service. Although this process is mainly invisible to the user, the steps in registration are listed here:

  • The client registers and bootstraps too it’s assicoated push service. This is done automatically.

  • The client registers itself with the push service server which then will dedicate a node for the device.

  • Node information is passed back to the client and is shared with necessary components.

Receiving notifications

Notifications sent from the server are recieved the following (simplified) way:

  • A message is published on the XMPP node which is then sent to the push service on the same server.

  • The push service will then inform the user agent (an application on the device running in the background) that a push notification has been sent.

  • The user agent will then publish the notification to the client for a user to see, waking up or turning on the client if is not running or suspended.

10.16.2. Configuration

Enabling component

Push notifications may be sent by Tigase XMPP Server with or without use of Push component. Push Component is only required if you have your own application for mobile devices for which you want to send push notifications.

This component is not loaded and enabled by default as it requires implementations of Push notifications providers and additional configuration (including credentials required to authorize to push services). Following entries will activate component:

push () {
}
Note
You need to enable and configure push providers implementations before it will be possible to send push notifications. For more details about this process, please check documentations of push service provider projects.
Enabling push notifications for offline messages

Push notifications may be sent by Tigase XMPP Server with or without use of Push component. Push Component is only required if you have your own application for mobile devices for which you want to send push notifications.

If you are using existing application, then its maker have to provide you with push server (push component) which will send notification in format understandable by its application.

However, on Tigase XMPP Server side you need to enable processor which will generate notifications about offline messages sent to accounts on this server. To do so, you need to add following lines withing sess-man configuration block to enable urn:xmpp:push:0 processor:

'sess-man' () {
    'urn:xmpp:push:0' () {}
}
Enabling push notifications for messages received when all resources are AWAY/XA/DND

Push notifications may also be sent by Tigase XMPP Server when new message is received and all resources of recipient are in AWAY/XA/DND state. To enable this notifications you need to enable urn:xmpp:push:0:ext processor instead of default Push processor.

'sess-man' () {
    'urn:xmpp:push:0:ext' () {}
}
Warning
This is an extended version of default processor, so be sure not to enable both of them as you may received duplicated push notifications.

As this behaviour may not be expected by users and users need a compatible XMPP client to properly handle this notifications (XMPP client needs to retrieve message history to get actual message), even with this processor enable XMPP clients need to enable push notifications and in enable element need to have away attribute with value of true as in following example"

Enabling Push notifications for away/xa/dnd account
<iq type='set' id='x43'>
  <enable xmlns='urn:xmpp:push:0' away='true' jid='push-5.client.example' node='yxs32uqsflafdk3iuqo'>
    <x xmlns='jabber:x:data' type='submit'>
        ....
    </x>
  </enable>
</iq>

If later on, user decides to disable notification for account in away/xa/dnd state, it may disable push notifications or once again send stanza to enable push notification but without away attribute being set:

<iq type='set' id='x43'>
  <enable xmlns='urn:xmpp:push:0' away='true' jid='push-5.client.example' node='yxs32uqsflafdk3iuqo'>
    <x xmlns='jabber:x:data' type='submit'>
        ....
    </x>
  </enable>
</iq>

10.16.3. Usage

Sending notifications

When you will register a device for a Push Notifications, you will receive name of the PubSub node where you should publish items. Publishing items to this node, as specified in XEP-0357: Push Notifications will result in push notifications being delivered to the registered device.

Registering device

To register a device you need to execute the adhoc command register-device available at Push Notification component. This command will return a form which needs to be filled.

Form consists of following fields:

provider

ID of a provider for which you want to register a device. It contains a list of available providers and you need to select a proper one.

device-token

Unique token which your application retrieved from a device or client library and which should be used to identify device you want to register for push notifications.

When you submit this form, it will be processed and will respond with a result type form. Within this form you will find a node field which will contain a PubSub node name created by the Push Notifications component, to which you should publish notification items. This returned node with jid of the Push Notifications Component should be passed to your XMPP server as the address of the XMPP Push Service.

Unregistering device

To unregister a device, you need to execute the adhoc command unregister-device available within the Push Notification component. This command will return a form which needs to be filled out.

This form consists of the following fields:

provider

ID of a provider for which your devices was registered.

device-token

Unique token which your application retrieved from a device or client library and was registered at this push notifications component.

When you submit this form, it will be processed and will respond with a result form to notify you that device was successfully unregistered from the push notifications component.

10.16.4. Providers

Providers availability depends on the deployed binaries, by default Tigase includes following providers:

Tigase Push Component - APNs provider

Tigase Team <team@tigase.net> :toc: :numbered: :website: http://tigase.net :Date: 2017-05-17 Welcome to Tigase Push component guide

Overview

Tigase Push Component - APNs provider is an implementation of APNs provider for Tigase Push Component. It allows Tigase Push Component to connect to Apple Push Notification service and send notifications using this service.

Configuration
Enabling provider

To enable this provider, you need to enable apns-binary-api bean within push component configuration scope.

Example
push () {
    'apns-binary-api' () {
        # APNs configuration here
    }
}
Note
You need to pass APNs configuration parameters to make it work, see below.
Setting APNs credentials

APNs binary API provider will not work properly without certificate file required for authorization by APNs and password to decrypt this certificate file. You need to get certificate using Apple Developer Account.

When you have this certificate, you need to pass path to certificate file as cert-file property and password as cert-password

Example for /etc/apns-cert.p12 and Pa$$word
push () {
    'apns-binary-api' () {
        'cert-file' = '/etc/apns-cert.p12'
        'cert-password' = 'Pa$$w0rd'
    }
}
Connection pool

By default this provider uses many connection to APNs for sending notifications which equals to number of available CPU cores. If in your use case it is to small or too big number, you can adjust it by setting value of pool-size configuration property. Setting it to 5 will make sure to use only five connections to APNs.

Example
push () {
    'apns-binary-api' () {
        'pool-size' = 5
    }
}
Tigase Push Component - FCM provider

Tigase Team <team@tigase.net> :toc: :numbered: :website: http://tigase.net :Date: 2017-05-17 Welcome to Tigase Push component guide

Overview

Tigase Push Component - FCM provider is an implementation of FCM provider for Tigase Push Component. It allows Tigase Push Component to connect to Firebase Cloud Messaging and send notifications using this service.

Configuration
Enabling provider

To enable this provider, you need to enable fcm-xmpp-api bean within push component configuration scope.

Example
push () {
    'fcm-xmpp-api' () {
        # FCM configuration here
    }
}
Note
You need to pass FCM configuration parameters to make it work, see below.
Setting FCM credentials

FCM XMPP API provider will not work properly without API key and project id as this values are required for authorization by FCM. You need to get information from FCM account.

When you have this data, you need to pass sender id as sender-id property and server key as server-key property.

Example
push () {
    'fcm-xmpp-api' () {
        'sender-id' = 'your-sender-id'
        'server-key' = 'your-server-key'
    }
}
Connection pool

By default this provider uses single client to server connection to FCM for sending notifications. If in your use case it is to small (as you need better performance), you should adjust value of pool-size configuration property. Setting it to 5 will open five connections to FCM for better performance.

Example
push () {
    'fcm-xmpp-api' () {
        'pool-size' = 5
    }
}

10.17. Tigase STUN Component

Tigase Team <team@tigase.net> :toc: :numbered: :website: http://tigase.net

Welcome to Tigase STUN component guide

10.17.1. Tigase STUN Component

Tigase STUN Component allows for the use of a STUN server to handle XMPP and related communications to allow for smoother server operations behind a NAT.

What is STUN?

STUN stands for Simple Traversal of UDP[User Datagram Protocol] Through NAT[Network Address Translators]. It allows for computers behind a NAT router to host and provide UDP information without having to create rule exceptions on the router, or provide specific information to the NAT service. When specified within Tigase, XMPP and UDP communications can be directed to a specific STUN server which will then handle incoming requests to your network. You may use a public, or your own STUN server with Tigase.

Requirements

The only requirement (aside from configuration) is that you are operating on a network that is not a Symmetric NAT as STUN by itself will not function correctly.

10.17.2. Configuration

Below is an example configuration for STUN component. Note that the 2 stun-primary and 2 stun-secondary settings are required, where external settings are not.

stun (class: tigase.stun.StunComponent) {
    'stun-primary-ip' = '10.0.0.1'
    'stun-primary-port' = 3478
    'stun-secondary-ip' = '10.0.0.2'
    'stun-secondary-port' = 7001
    'stun-primary-external-ip' = '172.16.0.22'
    'stun-primary-external-port' = 3479
    'stun-secondary-external-ip' = '172.16.0.23'
    'stun-secondary-external-port' = 7002
}
Note
Primary port should be set to 3478 as it is default port for STUN servers.
Setting descriptions
  1. stun-primary-ip - primary IP address of STUN server used for binding (and sending to client if stun-primary-external-ip)

  2. stun-primary-port - primary port of STUN server used for binding (and sending to client if stun-primary-external-port)

  3. stun-secondary-ip - secondary IP address of STUN server used for binding (and sending to client if stun-secondary-external-ip)

  4. stun-secondary-ip - secondary port of STUN server used for binding (and sending to client if stun-secondary-external-port)

If you wish to have a secondary STUN server as a backup, or to provide multiple addresses for STUN services, the following may be used.

  1. stun-primary-external-ip - primary external IP address of STUN server used for sending to client if set

  2. stun-primary-external-port - primary external port of STUN server used for sending to client if set

  3. stun-secondary-external-ip - secondary external IP address of STUN server used for sending to client if set

  4. stun-secondary-external-port - secondary external port of STUN server used for sending to client if set

Logback configuration

You man want to use logback for STUN server to append normal server logs. To do this, specify the logback xml file within java options in the tigase.conf file.

JAVA_OPTIONS="-Dlogback.configurationFile=etc/logback.xml"

You may configure the logback by editing the xml included with distributions at logback.xml.

What is included is a basic logback configuration that just adds the stun logging.

<configuration  scan="true">

  <appender name="STDOUT"
    class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>
        %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
     </pattern>
    </encoder>
  </appender>

  <logger name="de.javawi.jstun.header.MessageHeader" level="INFO" />

  <root level="DEBUG">
    <appender-ref ref="STDOUT" />
  </root>

</configuration>

10.18. Tigase SPAM Filter

Tigase Team <team@tigase.net> :toc: :toclevels: 3 :numbered: :website: http://tigase.net :Date: 2017-04-09

Welcome to Tigase SPAM Filter guide.

10.18.1. Overview

This Tigase SPAM Filter project contains additional features provided for Tigase XMPP Server to reduce number of sent/received SPAM messages.

10.18.2. Configuration

To enable default set of SPAM filters with default settings you need to enable SessionManager processor spam-filter:

Enabling default SPAM filters
'sess-man () {
    'spam-filter' () {}
}
Changing active SPAM filters

You can configure active SPAM filters by setting enabling and disabling SPAM filters (subbeans of spam-filter processor bean).

Enabling message-same-long-body filter
'sess-man' () {
    'spam-filter' () {
        'message-same-long-body' () {}
    }
}
Sending error when packet is dropped

By default, due to nature of SPAM, you do not want to send error packet when SPAM packet is dropped as sending error back will:

  • increase traffic on a server (which in rare cases may lead to overload of a XMPP server)

  • notify spammer that it was not possible to delivery message

It is possible to configure spam-filter to send error back, by setting true to spam-filter return-error property:

Allow sending error
'sess-man () {
    'spam-filter' () {
        return-error = true
    }
}
Enabling logging of dropped messages

It is possible to enable logging of dropped messages by adding spam to comma separate list of values for --debug property.

--debug=spam

10.18.3. Filters

In this section there is a list of available filters and detailed description of each filtering algorithm.

Same long message body

When there is a SPAM being sent using XMPP server in most cases number of messages with longer body size increases and in most cases every SPAM message contains same body part. This filter is identified by following id message-same-long-body.

Detection is based on:

  • message body being longer that particular value

  • multiple messages being sent with same long body

Below is list of possible settings which may be modified to adjust this filter behaviour.

Message body length

SPAM messages are usually longer messages (over 100 chars). To reduce overhead of filtering and memory required for filtering we check length of message body and process it further only if message exceeds declared message body length (default: 100 chars).

You can also check messages with smaller body (ie. only 50 chars) by setting body-size property to 50.

Setting filter to check message with body bigger that 50 chars
'sess-man' () {
    'spam-filter' () {
        'message-same-long-body' () {
            'body-size' = 50
        }
    }
}
Number of allowed message with same body

In most cases message with same body is sent to multiple users. Filter will count messages with same body (which is bigger that declared message body length) and if it exceeds message number lim