Tigase Administration Guide

Tigase Team <team@tigase.com> v8.1.0-SNAPSHOT, 2019-07-17 :toc: :toclevels: 2 :numbered: :website: http://tigase.net

1. Tigase XMPP Server 8.0.0 announcement

Tigase XMPP Server 8.1.0-SNAPSHOT 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 XMPP Server 8.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. default-virtual-host property changes

Default virtual hosts property is now able to be configured only as a domain name instead of the list of virtual host domains with options. Additional virtual host domains and their options need to be configured using ad-hoc commands or web AdminUI. 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. IzPack installer (files tigase-server-<version>-b<build>.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 and 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 distribution package, and has a number 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-305 Quickstart now supported

It’s now possible to establish connection faster due to implementation of XEP-0305: XMPP Quickstart (#1936). Feature is only available for c2s Connection Manager (i.e. connections on port 5222) and needs to be enabled in config.tdsl

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.1.29. Protection against brute-force attacks

Version 8.0.0 improves security by preventing brute-force attacks. Feature needs to be explicitly enabled and configured (on per VHost basis). Detailed configuration is described in Brute-force attack prevention (#8160)

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.

  • #2341 allow specifying SubscriptionType when adding buddy to avoid calling separately .setBuddySubscription() thus eliminating saving roster twice to database if not needed

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.

  • #7495 fix issue with not all logs being obfuscated, added testcase, documentation

  • #8305 fix issue with SeeOtherHostDualIP when using MongoDB

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. Tigase User Guide

Tigase Team <team@tigase.com> v8.1.0-SNAPSHOT, 2019-07-17

2.1. Jabber/XMPP introduction

2.1.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 WhatsApp Messenger, Facebook Messenger, Signal, Telegram, WeChat, QQ and other. 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. How to Use Tigase Service

2.2.1. This Article Describes How to use tigase.im Service for Instant Communications

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

There are multiple domains available: tigase.im, sure.im, xmpp.cloud (and you can host your own domain as well)

Short instructions:

Usually you just need to enter the user name of the form: user@tigase.im. 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.im server yet just tick the option to register new account. That’s it!

Long Instructions:

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 servers. What this means is that you can have a few Jabber accounts on different Jabber 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:

  • Beagle.im - macOS desktop client developed by Tigase team supporting all the latest and greatest features

  • Tigase Messenger for iOS - lightweight, powerful XMPP client developed by Tigase, Inc. It provides an easy way to start using the XMPP Protocol (formerly known as Jabber) if you’ve never used it before. Veterans of the protocol will find many features here they are familiar with along with enhancements to reduce data use and extend battery life.

  • Tigase Messenger for Android - mobile chat client to use with XMPP services and servers. The totally revamped v3.0 now has new features, a better design, and Google integration. Application supports any XMPP server, from free services like sure.im or Tigase.im, to a server you may host on your own.

  • tigase.im[Tigase.im] - web-based client allowing to easily chat with friends independently of platform.

  • Psi Pure Jabber client. Although it supports only Jabber network 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 Jabber client of your choice and set up for a Tigase account:

2.3. Configuration instructions for Psi

2.3.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 Jabber servers at the same time so we have to identify each connection somehow. 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 Jabber/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 the password of your choice 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 may happen that somebody earlier registered an account with the same name you’ve selected for yourself. If so, you will receive error message. You 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 After Registration

    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.

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

    PSI Connected

    Now you are connected!

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.3.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.

3.6. XMPP Supported Extensions

3.6.1. Core Compliance Suite

Table 1. Core Compliance Suite

Support

Specification

Name

Comment

RFC6120

Extensible Messaging and Presence Protocol (XMPP): Core

RFC7622

Extensible Messaging and Presence Protocol (XMPP): Address Format

We support previous version of the specification: RFC6122

RFC7590

Use of Transport Layer Security (TLS) in the Extensible Messaging and Presence Protocol (XMPP)

XEP-0368

SRV records for XMPP over TLS

Requires adding DNS entries pointing to port 5223

XEP-0030

Service Discovery

XEP-0115

Entity Capabilities

XEP-0114

Jabber Component Protocol

XEP-0163

Personal Eventing Protocol

3.6.2. Web Compliance Suite

Table 2. Web Compliance Suite

Support

Specification

Name

Comment

RFC7395

An Extensible Messaging and Presence Protocol (XMPP) Subprotocol for WebSocket

XEP-0206

XMPP Over BOSH

XEP-0124

Bidirectional-streams Over Synchronous HTTP (BOSH)

3.6.3. IM Compliance Suite

Table 3. Web Compliance Suite

Support

Specification

Name

Comment

RFC6120

Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence

XEP-0084

User Avatar

XEP-0153

vCard-Based Avatars

XEP-0054

vcard-temp

XEP-0280

Message Carbons

XEP-0191

Blocking Command

XEP-0045

Multi-User Chat

XEP-0249

Direct MUC Invitations

XEP-0048

Bookmarks

XEP-0223

Persistent Storage of Private Data via PubSub

XEP-0049

Private XML Storage

XEP-0198

Stream Management

Both Session Resumption and Stanza Acknowledgements

XEP-0313

Message Archive Management

3.6.4. Mobile Compliance Suite

Table 4. Web Compliance Suite

Support

Specification

Name

Comment

RFC7395

An Extensible Messaging and Presence Protocol (XMPP) Subprotocol for WebSocket

XEP-0198

Stream Management

Both Session Resumption and Stanza Acknowledgements

XEP-0352

Client State Indication

XEP-0357

Push Notifications

3.6.5. Non-Compliance Suite Extensions

Table 5. Core Compliance Suite

Support

Specification

Name

Comment

XEP-0004

Data Forms

XEP-0008

IQ-Based Avatars

XEP-0012

Last Activity

XEP-0013

Flexible Offline Message Retrieval

XEP-0016

Privacy Lists

XEP-0020

Feature Negotiation

XEP-0022

Message Events

XEP-0047

In-Band Bytestreams

XEP-0050

Ad-Hoc Commands

XEP-0059

Result Set Management

XEP-0060

Publish-Subscribe

XEP-0065

SOCKS5 Bytestreams

XEP-0066

Out of Band Data

XEP-0068

Field Standardization for Data Forms

XEP-0071

XHTML-IM

XEP-0072

SOAP Over XMPP

XEP-0077

In-Band Registration

XEP-0078

Non-SASL Authentication

XEP-0079

Advanced Message Processing

XEP-0080

User Location

XEP-0082

XMPP Date and Time Profiles

XEP-0083

Nested Roster Groups

XEP-0085

Chat State Notifications

XEP-0086

Error Condition Mappings

XEP-0091

Legacy Delayed Delivery

XEP-0092

Software Version

XEP-0096

File Transfer

XEP-0100

Gateway Interaction

XEP-0106

JID Escaping

XEP-0107

User Mood

Server support via Personal Eventing Protocol (XEP-0163)

XEP-0108

User Activity

Server support via Personal Eventing Protocol (XEP-0163)

XEP-0118

User Tune

Server support via Personal Eventing Protocol (XEP-0163)

XEP-0127

Common Alerting Protocol (CAP) Over XMPP

XEP-0128

Service Discovery Extensions

XEP-0131

Stanza Headers and Internet Metadata (SHIM)

XEP-0133

Service Administration

XEP-0136

Message Archiving

XEP-0141

Data Forms Layout

XEP-0142

Workgroup Queues

XEP-0144

Roster Item Exchange

XEP-0145

Annotations

XEP-0146

Remote Controlling Clients

XEP-0152

Reachability Addresses

XEP-0155

Stanza Session Negotiation

XEP-0156

Discovering Alternative XMPP Connection Methods

Uses DNS records, so will work with Tigase XMPP Server

XEP-0157

Contact Addresses for XMPP Services

XEP-0160

Best Practices for Handling Offline Messages

XEP-0166

Jingle

XEP-0167

Jingle RTP Sessions

XEP-0170

Recommended Order of Stream Feature Negotiation

XEP-0171

Language Translation

XEP-0172

User Nickname

XEP-0174

Serverless Messaging

XEP-0175

Best Practices for Use of SASL ANONYMOUS

XEP-0176

Jingle ICE-UDP Transport Method

XEP-0177

Jingle Raw UDP Transport Method

XEP-0178

Best Practices for Use of SASL EXTERNAL with Certificates

XEP-0179

Jingle IAX Transport Method

XEP-0180

Jingle Video via RTP

XEP-0181

Jingle DTMF

XEP-0184

Message Receipts

XEP-0185

Dialback Key Generation and Validation

XEP-0190

Best Practice for Closing Idle Streams

XEP-0199

XMPP Ping

XEP-0201

Best Practices for Message Threads

XEP-0202

Entity Time

XEP-0203

Delayed Delivery

XEP-0205

Best Practices to Discourage Denial of Service Attacks

XEP-0209

Metacontacts

XEP-0220

Server Dialback

XEP-0224

Attention

XEP-0225

Component Connections

XEP-0226

Message Stanza Profiles

XEP-0231

Bits of Binary

XEP-0234

Jingle File Transfer

XEP-0245

The /me Command

XEP-0246

End-to-End XML Streams

XEP-0247

Jingle XML Streams

XEP-0250

C2C Authentication Using TLS

XEP-0251

Jingle Session Transfer

XEP-0260

Jingle SOCKS5 Bytestreams Transport Method

XEP-0261

Jingle In-Band Bytestreams Transport

XEP-0262

Use of ZRTP in Jingle RTP Sessions

XEP-0277

Microblogging over XMPP

XEP-0292

vCard4 Over XMPP

XEP-0301

In-Band Real Time Text

XEP-0305

XMPP Quickstart

XEP-0323

Internet of Things - Sensor Data

XEP-0324

Internet of Things - Provisioning

XEP-0325

Internet of Things - Control

XEP-0326

Internet of Things - Concentrators

XEP-0333

Chat Markers

XEP-0363

HTTP File Upload

XEP-0387

XMPP Compliance Suites 2018

3.6.6. Full, ordered list of supported RFCs and XEPs:

Support

Specification

Name

Comment

RFC6120

Extensible Messaging and Presence Protocol (XMPP): Core

RFC6120

Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence

RFC7622

Extensible Messaging and Presence Protocol (XMPP): Address Format

We support previous version of the specification: RFC6122

RFC7395

An Extensible Messaging and Presence Protocol (XMPP) Subprotocol for WebSocket

RFC7395

An Extensible Messaging and Presence Protocol (XMPP) Subprotocol for WebSocket

RFC7590

Use of Transport Layer Security (TLS) in the Extensible Messaging and Presence Protocol (XMPP)

XEP-0004

Data Forms

XEP-0008

IQ-Based Avatars

XEP-0012

Last Activity

XEP-0013

Flexible Offline Message Retrieval

XEP-0016

Privacy Lists

XEP-0020

Feature Negotiation

XEP-0022

Message Events

XEP-0030

Service Discovery

XEP-0045

Multi-User Chat

XEP-0047

In-Band Bytestreams

XEP-0048

Bookmarks

XEP-0049

Private XML Storage

XEP-0050

Ad-Hoc Commands

XEP-0054

vcard-temp

XEP-0059

Result Set Management

XEP-0060

Publish-Subscribe

XEP-0065

SOCKS5 Bytestreams

XEP-0066

Out of Band Data

XEP-0068

Field Standardization for Data Forms

XEP-0071

XHTML-IM

XEP-0072

SOAP Over XMPP

XEP-0077

In-Band Registration

XEP-0078

Non-SASL Authentication

XEP-0079

Advanced Message Processing

XEP-0080

User Location

XEP-0082

XMPP Date and Time Profiles

XEP-0083

Nested Roster Groups

XEP-0084

User Avatar

XEP-0085

Chat State Notifications

XEP-0086

Error Condition Mappings

XEP-0091

Legacy Delayed Delivery

XEP-0092

Software Version

XEP-0096

File Transfer

XEP-0100

Gateway Interaction

XEP-0106

JID Escaping

XEP-0107

User Mood

Server support via Personal Eventing Protocol (XEP-0163)

XEP-0108

User Activity

Server support via Personal Eventing Protocol (XEP-0163)

XEP-0114

Jabber Component Protocol

XEP-0115

Entity Capabilities

XEP-0118

User Tune

Server support via Personal Eventing Protocol (XEP-0163)

XEP-0124

Bidirectional-streams Over Synchronous HTTP (BOSH)

XEP-0128

Service Discovery Extensions

XEP-0127

Common Alerting Protocol (CAP) Over XMPP

XEP-0131

Stanza Headers and Internet Metadata (SHIM)

XEP-0133

Service Administration

XEP-0136

Message Archiving

XEP-0141

Data Forms Layout

XEP-0142

Workgroup Queues

XEP-0144

Roster Item Exchange

XEP-0145

Annotations

XEP-0146

Remote Controlling Clients

XEP-0152

Reachability Addresses

XEP-0153

vCard-Based Avatars

XEP-0155

Stanza Session Negotiation

XEP-0156

Discovering Alternative XMPP Connection Methods

Uses DNS records, so will work with Tigase XMPP Server

XEP-0157

Contact Addresses for XMPP Services

XEP-0160

Best Practices for Handling Offline Messages

XEP-0163

Personal Eventing Protocol

XEP-0166

Jingle

XEP-0167

Jingle RTP Sessions

XEP-0170

Recommended Order of Stream Feature Negotiation

XEP-0171

Language Translation

XEP-0172

User Nickname

XEP-0174

Serverless Messaging

XEP-0175

Best Practices for Use of SASL ANONYMOUS

XEP-0176

Jingle ICE-UDP Transport Method

XEP-0177

Jingle Raw UDP Transport Method

XEP-0178

Best Practices for Use of SASL EXTERNAL with Certificates

XEP-0179

Jingle IAX Transport Method

XEP-0180

Jingle Video via RTP

XEP-0181

Jingle DTMF

XEP-0184

Message Receipts

XEP-0185

Dialback Key Generation and Validation

XEP-0190

Best Practice for Closing Idle Streams

XEP-0191

Blocking Command

XEP-0198

Stream Management

Both Session Resumption and Stanza Acknowledgements

XEP-0199

XMPP Ping

XEP-0201

Best Practices for Message Threads

XEP-0202

Entity Time

XEP-0203

Delayed Delivery

XEP-0205

Best Practices to Discourage Denial of Service Attacks

XEP-0206

XMPP Over BOSH

XEP-0209

Metacontacts

XEP-0220

Server Dialback

XEP-0223

Persistent Storage of Private Data via PubSub

XEP-0224

Attention

XEP-0225

Component Connections

XEP-0226

Message Stanza Profiles

XEP-0231

Bits of Binary

XEP-0234

Jingle File Transfer

XEP-0245

The /me Command

XEP-0246

End-to-End XML Streams

XEP-0247

Jingle XML Streams

XEP-0249

Direct MUC Invitations

XEP-0250

C2C Authentication Using TLS

XEP-0251

Jingle Session Transfer

XEP-0260

Jingle SOCKS5 Bytestreams Transport Method

XEP-0261

Jingle In-Band Bytestreams Transport

XEP-0262

Use of ZRTP in Jingle RTP Sessions

XEP-0277

Microblogging over XMPP

XEP-0280

Message Carbons

XEP-0292

vCard4 Over XMPP

XEP-0301

In-Band Real Time Text

XEP-0305

XMPP Quickstart

XEP-0313

Message Archive Management

XEP-0323

Internet of Things - Sensor Data

XEP-0324

Internet of Things - Provisioning

XEP-0325

Internet of Things - Control

XEP-0326

Internet of Things - Concentrators

XEP-0333

Chat Markers

XEP-0352

Client State Indication

XEP-0357

Push Notifications

XEP-0363

HTTP File Upload

XEP-0368

SRV records for XMPP over TLS

Requires adding DNS entries pointing to port 5223

XEP-0387

XMPP Compliance Suites 2018

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-<version>-SNAPSHOT-b<build>-<type> where <version> is in the form of major.minor.bugfix

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 (<type>):

  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.

6. Quick Start Guide

6.1. Minimum Requirements

Before you begin installing Tigase server onto your system, please make sure the minimum requirements are met first:

  • Java Development Kit v11 or later - We recommend OpenJDK

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

Note
It may be possible to run Tigase XMPP Server with JDK v8 but it is not recommended as not all features will be available and you may encounter startup issues.

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. Once you have the distribution binary extract it and navigate to the directory:

$ tar -xf tigase-server-<version>-dist-max.tar.gz
$ cd tigase-server-<version>
Tip
Do not run as root user!

6.3.2. Start the Server

Note
Please make sure JAVA_HOME is set and points to your JVM installation
scripts/tigase.sh start etc/tigase.conf

6.3.3. Verify Tigase is ready to start installation

Tigase should start listening on port 8080 - you can check it using lsof command:

$ lsof -i -P
COMMAND   PID   USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
java    18387 tigase  141u  IPv6 22185825      0t0  TCP *:8080 (LISTEN)

You can also check console log under logs/tigase-console.log, which should point you directly to the installer.

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. You can also use the domain name, or IP address.

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. 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.8. 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 distribution 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 tigase.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-<version>-b<build>-<type>.<archive>, where <version> is in the form of major.minor.bugfix, <type> can be either dist (basic package) or dist-max (extended set of components) and archive type can be eitehr tar.gz or zip.

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 host

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

'default-virtual-host' = '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:

'default-virtual-host' = '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 proper DNS service record (SRV) configuration that point to the following DNS address: tigase.me.

We highly encourage using SRV records. If you want to register: your-domain.tld on our XMPP service make sure that it resolves correctly:

$ 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.
$ host -t SRV _xmpps-client._tcp.your-domain.tld
_xmpp-client._tcp.your-domain.tld has SRV record 10 0 5222 tigase.me.

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.

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.

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.

Providing certificate

It’s also encouraged to provide dedicated SSL certificate - there are various ways to do it and they are described in Installing/Loading Certificate To the Tigase Server. You may want to take advantage of free Let’s Encrypt certificates and automate whole upload and renewal process as described in Installing LetsEncrypt Certificates in Your Linux System

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 (cluster connection)

  • 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 6. init.d chart
Operating system init.d file path Types of Operating Systems

Systemd

tigase-server/scripts/systemd/*

Systemd-based distributions

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)

Note
If your operating system is a systemd-based linux distribution, we recommend to use systemd service scripts. It may be possible to use (in this case legacy) init.d startup files as before, but usage of systemd startup scripts will allow better control of the startup process and will even allow for automatic restart of the Tigase XMPP Server in the case of JVM crash.

6.7.1. Configuration: For Linux Distributions using systemd

To set up Tigase XMPP Server as a system service it is required to copy tigase-server.service file to /etc/systemd/system/ directory

sudo cp $SCRIPT_FILE_PATH/tigase-server.service /etc/systemd/system/

This file contains following parameters which may need to be adjusted:

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

  • WorkingDirectory - Specifies installation directory (default: /home/tigase/tigase-server)

  • ExecStart - Specifies startup command (default: runs scripts/tigase.sh start etc/tigase.conf in the Tigase installation directory)

  • ExecStop - Specifies shutdown command (default: runs scripts/tigase.sh stop etc/tigase.conf in the Tigase installation directory)

  • PIDFile - Specifies location of the PID file (default: logs/tigase.pid file in the Tigase installation directory)

It is also required to copy options file tigase-server to /etc/default/ directory

sudo cp $SCRIPT_FILE_PATH/tigase-server /etc/default/

With those files in place you need to reload systemctl daemon

sudo systemctl daemon-reload
Note
If you are upgrading from the previous version of the Tigase XMPP Server which was not running as the systemd system service it is required to uninstall old service and remove old service files.

6.7.2. 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.3. 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.

For systemd-based linux distributions

Once installation is complete you may start Tigase as a typical systemd service using following command:

sudo systemctl start tigase-server

To stop it, you may run following command:

sudo systemctl stop tigase-server

It is also possible to enable service, to make it start during startup of the operating system:

sudo systemctl enable tigase-server
For other linux distributions

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 XMPP Server 8.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 XMPP Server 8.0.0

After downloading Tigase XMPP Server 8.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

When everything is ready it will printout following information

=============================================================================
  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

6.9.7. Upgrade/Restore with a script [experimental!]

To make upgrade process easier it’s possible to utilize tigase-upgrade.sh *nix shell script. It permits upgrading to new version (supports downloading version from provided URL).

It’s usage is as follows:

./tigase-upgrade.sh {upgrade|rollback} install_package install_directory [tar|dir]

Where: * {upgrade|rollback} - defines whether to perform upgrade or rollback to previous version * install_package - package to which perform upgrade (can be URL) in case of upgrade or backed-up installation (from which we want to restore) in case of rollback * install_directory - destination directory (both in upgrade and rollback); can be symlink in which case it will be preserved with upgraded/restored path as target * [tar|dir] - (optional) type of backup (either simply copy directory or also archive it using tar command); by default dir is used.

To upgrade installation to version tigase-server-8.0.0-SNAPSHOT-b5285-dist-max.tar.gz execute the script as follows:

$ ./tigase-upgrade.sh upgrade tigase-server-8.0.0-SNAPSHOT-b5285-dist-max.tar.gz tigase-server

To rollback from tigase-server-8.0.0-SNAPSHOT-b5264_backup-18-11-05_1712 backup execute script as follows:

bash -x ./tigase-upgrade.sh rollback tigase-server-8.0.0-SNAPSHOT-b5264_backup-18-11-05_1712/ tigase-server

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'.
Period / Duration values

Some configuration options allow control of execution of tasks with particular period or within certain duration. DSL file format accepts strings denoting particular amount of time, which follows Java’s native structures (see: Period and Duration for detailed explanation).

  • Duration formats accepted are based on the ISO-8601 duration format PnDTnHnMn.nS with days considered to be exactly 24 hours, for example:

    • PT20.345S - 20.345 seconds

    • PT15M - 15 minutes (where a minute is 60 seconds)

    • PT10H - 10 hours (where an hour is 3600 seconds)

    • P2D - 2 days (where a day is 24 hours or 86400 seconds)

    • P2DT3H4M - 2 days, 3 hours and 4 minutes

  • Period format is based on the ISO-8601 period formats PnYnMnD and PnW, for example, the following are valid inputs:

    • P2Y - 2 years

    • P3M - 3 months

    • P4W - 4 weeks

    • P5D - 5 days

    • P1Y2M3D - 1 year, 2 months, 3 days

    • P1Y2M3W4D - 1 year, 2 months, 3 weeks, 4 days

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 www.gnugk.org/ some keepalive settings should be changed to improve reliability - it will enable keep alive functionality (checking if the connection is established and valid) and, by decreasing times and interval - will make detection of broken connections faster.

# 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.

Memory consideration - total usage

The HEAP size is not the only thing that affects JVM memory usage. When trying to size accordingly for your usage and machine specification you have to consider other factors that count towards total: loaded classes, threads' stack, JIT code cache, garbage collector and others. In principle consider following equation:

Maximum memory usage = [-Xmx] + [-XX:MaxMetaspaceSize] + number_of_threads * [-Xss] + [-XX:MaxDirectMemorySize]
                       (heap)   (classes)                (threads' stack)             (direct memory)
Note
before Java8 memory dedicated to loaded classes was configured with -XX:PermSize and -XX:MaxPermSize instead of, respectively, -XX:MetaspaceSize and -XX:MaxMetaspaceSize

In case of Tigase XMPP Server, apart from heap we limit remaining factors:

  • direct memory to 128 MB

  • loaded classes to 128 MB

  • single thread’s stack size to 228 KB (number of threads depends on number of CPU cores and may vary from 500 to couple of thousands)

In principle, in addition to HEAP’s maximum size defined by -Xmx you should add roughly 512 MB

If you are interested in detailed tracking of memory take a look at [Memory footprint of the JVM](https://spring.io/blog/2019/03/11/memory-footprint-of-the-jvm/), [Native Memory Tracking in JVM](https://www.baeldung.com/native-memory-tracking-in-jvm) or [Why does my Java process consume more memory than Xmx?](https://plumbr.io/blog/memory-leaks/why-does-my-java-process-consume-more-memory-than-xmx)

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.

logic = 'tigase.xmpp.impl.MobileV1'
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.

logic = 'tigase.xmpp.impl.MobileV2'
MobileV3

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

logic = 'tigase.xmpp.impl.MobileV3'
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 by enabling Mobile_V1 (){} bean to Session Manager: sess-man () {} bean.

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 'default-virtual-host' property allows to define name of the single vhost domain which will be considered a default vhost domain for this installation. It allows you just to configure the domain name. Any additional configuration needs to be configured using ad-hoc commands.

Virtual hosts should be managed using ad-hoc commands or admin ui, visit Add and Manage Domains for description of vhosts management process or visit Specification for ad-hoc Commands Used to Manage Virtual Domains for more information about ad-hoc commands.

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.

Tip
If you have a Tigase XMPP Server running in the cluster mode hidden behind some load balancer, or if internal IP or hostname of cluster nodes differ from the DNS name under which it is available from the internet, we would suggest setting a property installation-dns-address of vhost-man component to the DNS name which allows you to connect to all cluster nodes (ie. to the DNS name of the load balancer). This will allow Tigase XMPP Server to do proper DNS lookups to verify that DNS domain name of the virtual host which you will try to add or update points to your XMPP installation.

7.6.1. Default VHost configuration

It’s possible to specify initial default configuration for all Virtual Host in TDSL configuration file (i.e. etc/config.tdsl) for selected parameters. To do so you should specify each configuration option within defaults bean belonging to vhost-man bean:

'vhost-man' () {
    'defaults' () {
        'domain-filter-policy' = null
        'hardened-mode' = false
        's2s-secret' = null
        trusted = null
        'vhost-disable-dns-check' = false
        'vhost-max-users' = 0L
        'vhost-message-forward-jid' = null
        'vhost-presence-forward-jid' = null
        'vhost-register-enabled' = true
        'vhost-tls-required' = false
    }
}

After initial definition of default configuration or after first startup of Tigase XMPP Server it is possible to configure Virtual Host defaults using ad-hoc commands by modifying values for default using ad-hoc as described in Specification for ad-hoc Commands Used to Manage Virtual Domains.

Alternatively, you may edit default Virtual Host configuration (configuration for domain default) using Admin UI which by default is available at http://localhost:8080/admin/.

7.6.2. 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 <not-authorized /> 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.3. 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
    'packet-debug-full' = true
    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.

  • packet-debug-full - controls whether log entries should be obfuscated (all CData of all elements will be replaced by CData size: <length in bytes of the replaced string>) or not; default: false.

  • 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.

Abuse Contacts

Tigase has support for XEP-0128: Service Discovery Extensions for providing additional information to the server and component discovery information. One of the important usages for this feature is XEP-0157: Contact Addresses for XMPP Services which describes usage of this feature for providing contact information to server administrators or abuse response team.

To set abuse contact details you should set disco-extensions in property in etc/config.tdsl file with subproperty abuse-addresses set to your abuse address URI (for email you need to prefix it with mailto: and for XMPP address you need to prefix it with xmpp):

'disco-extensions' = {
    'abuse-addresses' = [ 'mailto:abuse@localhost', 'xmpp:abuse@localhost' ]
}

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: Blocking Command

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 config.tdsl 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. Brute-force attack prevention

Brute-force Prevention is designed to protect Tigase Server against user password guessing. It counts invalid login tries and when it is above limit, it locks login ability for specific time (soft ban). When invalid login counter reaches second level, account will be disabled permanently.

8.3.1. Configuration

Brute-force Prevention is configured by VHost. There is following lis of configuration parameters:

brute-force-lock-enabled

boolean

Brute Force Prevention Enabled

brute-force-lock-after-fails

long

Number of allowed invalid login

brute-force-period-time

long

Time [sec] in what failed login tries are counted

brute-force-disable-after-fails

long

Threshold beyond which account will be permanently disabled

brute-force-lock-time

long

Time [sec] of soft ban (first threshold)

brute-force-mode

string

Working mode (see Working modes)

Detailed statistics

By default, in order not to pollute statistics, Brute-Force locker will only provide details about number of locker IPs and JIDs (and total number of locked attempts). In order to have detailed information about IPs and JIDs that has been locked in statistics you should use following configuration:

'sess-man' () {
    'brute-force-locker' () {
        detailedStatistics = false
    }
}
Working modes

There are three working modes:

  • Ip - it counts invalid login tries from IP, and locks login ability (soft ban) for IP what reach the threshold

  • IpJid - it counts tries from IP to specific user account. Soft ban locks ability of login to specific JID from specific IP.

  • Jid- similar to IpJid but checks only JID. Soft ban locks ability of login to specific JID from all IPs.

Note
Only in modes Jid and IpJid account may be permanently disabled.
Permanent ban

In modes Jid and IpJid, when invalid login counter reach threshold brute-force-disable-after-fails, account status will be set o disabled. To enable it again you should use Re-Enable User Ad-hoc Command.

8.4. Server Certificates

8.4.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.

It’s also possible to use: * Admin ad-hoc command via XMPP client - you should navigate to Service Discovery of your server and in the list of commands for VHost Manager component select Add SSL Certificate and then follow instructions * Admin WebUI - open http://<host>/admin, navigate to Other category and in it select Add SSL Certificate and then follow instructions * REST API - make a POST request to http://localhost:8080/rest/adhoc/vhost-man@domain.com with payload containing your certificate; to get the required form fields make GET request to the same endpoint

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:

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.4.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.

Please refer to official [certbot User Guide](https://certbot.eff.org/docs/using.html) for details how to install and operate the tool, choosing desired method of domain authentication (DNS or webserver). After successful execution the certificate with all related files will be stored under /etc/letsencrypt/live/$domain

$ sudo ls  /etc/letsencrypt/live/$domain
cert.pem  chain.pem  fullchain.pem  privkey.pem  README

In that directory, you will find four files: - privkey.pem - private key for the certificate - cert.pem - contains the server certificate by itself - chain.pem - contains the additional intermediate certificate or certificates - fullchain.pem - all certificates, including server certificate (aka leaf certificate or end-entity certificate). The server certificate is the first one in this file, followed by any intermediates.

For Tigase XMPP Server, we are only concerned with privkey.pem and fullchain.pem.

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, certificate, and combine them with the contents of isrgrootx1.pem and letsencryptauthorityx3.pem into a single pem certificate. You need to name the file after your domain such as mydomain.com.pem and place it under certs/ subdirectory of Tigase XMPP Server installation

If you moved all certs to a single directory, you may combine them using the following command under *nix operating systems:.

cat ./cert.pem ./privkey.pem ./letsencryptauthorityx3.pem ./isrgrootx1.pem > mydomain.com.pem
Note
If you are using isrgrootx1 root make sure you use cert.pem file instead of fullchain.pem, which uses different intermediate certificate ( Let’s Encrypt Authority X3 (IdenTrust cross-signed) ) and you will have to use DST Root CA X3 certificate!

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-----
Warning
LetsEncrypt certificates expire 90 days from issue and need to be renewed in order for them to remain valid!

You can check your certificate with utility class:

java -cp <path_to_tigase-server_installation>/jars/tigase-utils.jar tigase.cert.CertificateUtil -lc mydomain.com.pem -simple
Let’s encrypt and DNS verification

The only way to obtain wildcard (*.domain.com) certificate is via DNS verification. Certbot support a number of DNS operators - you can check if your DNS provider is listed by executing $ certbot plugins

AWS Route53

If you want to use it with Amazon Cloud you should install plugin for AWS:

pip install certbot-dns-route53
Note
If you are using certbot under macOS and you installed it via brew then you should use: $( brew --prefix certbot )/libexec/bin/pip install certbot-dns-route53

You should store your credentials in ~/.aws/credentials (you may want to create dedicated policy for updating DNS as described in plugin’s documentation:

[default]
aws_access_key_id = <key_id>
aws_secret_access_key = <key>

And afterward you should execute certbot with --dns-route53 parameter

Certbot update hook and Tigase API

For greater automation it’s possible to automate updating certificate obtained with certbot in Tigase XMPP Server. You should use following deploy hook - either add it to /etc/letsencrypt/renewal-hooks/deploy/ or use it directly in certboot commandline with --deploy-hook parameter (in the latter case, it will be added to particular domain configuration so it’s not necessary to specify UPDATE_DOMAINS).

Note
Please adjust account credentials used for deployment (USER, PASS, DOMAIN) as well as paths to Let’s Encrypt certificates (ISRG Root X1 named isrgrootx1.pem and Let’s Encrypt Authority X3 named letsencryptauthorityx3.pem)
#!/bin/bash

set -e

## Configuration START

USER="admin_username"
PASS="admin_password"
DOMAIN="my_domain.tld"
HOST=${DOMAIN}
#UPDATE_DOMAINS=(${DOMAIN})
# PORT=":8080"
# APIKEY="?api-key=mySecretKey"
LE_CERTS_PATH="/path/to/letsencrypt/CA/certificates/"

## Configuration END

fail_count=0

for domain in ${RENEWED_DOMAINS[@]}; do
        if [[ $domain == "*."* ]]; then
                CERT_DOMAIN=${domain#*\*.}
        else
                CERT_DOMAIN=${domain}
        fi

    if [[ ! -z "${UPDATE_DOMAINS}" ]] ; then
        match=0
        for dn in "${UPDATE_DOMAINS[@]}"; do
            if [[ $dn = "$CERT_DOMAIN" ]]; then
                match=1
                break
            fi
        done
        if [[ $match = 0 ]]; then
            echo "Skipping updating ${domain} because it's not in the list of supported domains: ${UPDATE_DOMAINS[@]}"
            continue
        fi
    fi

    CERT=`cat "$RENEWED_LINEAGE/cert.pem" "$RENEWED_LINEAGE/privkey.pem" ${LE_CERTS_PATH}/isrgrootx1.pem ${LE_CERTS_PATH}/letsencryptauthorityx3.pem`

        REQUEST="
        <command>
          <node>ssl-certificate-add</node>
          <fields>
                <item>
                  <var>Certificate in PEM format</var>
                  <value>${CERT}</value>
                </item>
                <item>
                  <var>command-marker</var>
                  <value>command-marker</value>
                </item>
                <item>
                  <var>VHost</var>
                  <value>${CERT_DOMAIN}</value>
                </item>
                <item>
                  <var>Save to disk</var>
                  <value>true</value>
                </item>
          </fields>
        </command>"

        response=`curl -s -L -H "Content-Type: text/xml" -X POST  http://${USER}%40${DOMAIN}:${PASS}@${HOST}${PORT}/rest/adhoc/vhost-man@${DOMAIN}${APIKEY} -d "${REQUEST}"`

    if [[ ! ${response} = *"loaded successfully"* ]] ; then
        echo -e "Server returned error while updating   ${domain}   certificate:\n ${response}"
        fail_count=$((${fail_count}+1))
    else
        echo "Correctly updated ${domain} certificate"
    fi
done

exit ${fail_count}
Note
If you are not using wildcard certificate when you have to provide certificate for main domain as well as certificates for subdomains that mach all components that you want to expose (muc, pubsub, push, etc…)

8.5. 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.

  • 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.

  • tigase-auth (DEPRECATED) - 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.

As always the simplest way to configure the server is through the config.tdsl 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.db.jdbc.TigaseCustomAuth'
    }
}

The different cls or classes are:

  • Drupal - tigase.db.jdbc.DrupalWPAuth

  • MySQL, Derby, PostgreSQL, MS SQL Server - tigase.db.jdbc.JDBCRepository

You can normally skip configuring connectors for the default Tigase database format: mysql, pgsql and derby, sqlserver 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.5.1. Tigase Auth Connector (DEPRECATED)

Warning
Tigase Auth connector is DEPRECATED as of version 8.0.0 and will be removed in future releases

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 repository for the schema definition files.

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.5.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.5.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.5.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.5.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.6. SASL Mechanisms

XMPP protocol supports many authentication methods, but most of them are used as SASL mechanisms. Tigase XMPP Server provides many SASL-based authentication mechanisms such as:

  • PLAIN (enabled)

  • ANONYMOUS

  • EXTERNAL

  • SCRAM-SHA-1 (enabled)

  • SCRAM-SHA-256 (enabled)

  • SCRAM-SHA-512

Most of them are enabled by default on default Tigase XMPP Server installation.

8.6.1. Enabling and disabling SASL mechanisms (credentials encoder/decoder)

If you want to enable or disable one of password-based authentication mechanism such as SCRAM-SHA-1, SCRAM-SHA-256 or SCRAM-SHA-512 you can do that by enabling or disabling 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 (and in most cases will) impact which SASL mechanisms may be allowed to use on your installation.

Note
In most cases you should enable or disable both (credentials encoder and decoder) of the same type at the same time. The only exception of this rule is when you are changing those on already working installation. In this case you should only enable encoder of the type which you want to enable and request users to change their passwords. Then, after users will change their passwords, you should reconfigure server to enable decoder of the particular type. (in other case user may loose a way to log in to your installation as system will reject their credentials as it may not have matching credentials for particular SASL mechanism).
Enabling SCRAM-SHA-512 encoder
authRepository () {
    default () {
        credentialEncoders () {
            'SCRAM-SHA-512' () {}
        }
    }
}
Disabling SCRAM-SHA-1 decoder
authRepository () {
    default () {
        credentialDecoders () {
            '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.

8.7. 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.7.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.8. 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 config.tdsl file under admins = [] (please see admins for details).

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.

  • example.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 config.tdsl 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.

Note
see Period / Duration values for format details

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] (required)

  • -D, --dbName= - name of the database that will be created (by default it is tigasedb). (required)

  • -H, --dbHostname= - address of the database instance (by default it is localhost). (required)

  • -U, --dbUser= - name of the user that will be created specifically to access Tigase XMPP Server database (default is tigase_user). (required)

  • -P, --dbPass= - password of the user that will be created specifically to access Tigase XMPP Server database (default is tigase_pass). (required)

  • -R, --rootUser= - database root account username used to create user and database (default is root). (required)

  • -A, --rootPass= - database root account password used to create user and database (default is root). (required)

  • -S, --useSSL - enable SSL support for database connection (if the database supports it) (default is false).

  • -F, --file= - 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, --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.4.2. Prepare the MySQL Database for the Tigase Server

This guide describes how to prepare MySQL database for connecting Tigase server.

The MySQL database can be prepared in many ways. Most Linux distributions contain tools which allow you to go through all steps from the shell command line. To make sure it works on all platforms in the same way, we will first show how to do it under MySQL command line client.

Configuring from MySQL command line tool

Run the MySQL command line client in either Linux or MS Windows environment and enter following instructions from the Tigase installation directory:

mysql -u root -p

Once logged in, create the database for the Tigase server:

mysql> create database tigasedb;

Add the tigase_user user and grant him access to the tigasedb database. Depending on how you plan to connect to the database (locally or over the network) use one of following commands or all if you are not sure:

  • Grant access to tigase_user connecting from any network address.

    mysql> GRANT ALL ON tigasedb.* TO tigase_user@'%'
                IDENTIFIED BY 'tigase_passwd';
  • Grant access to tigase_user connecting from localhost.

    mysql> GRANT ALL ON tigasedb.* TO tigase_user@'localhost'
                IDENTIFIED BY 'tigase_passwd';
  • Grant access to tigase_user connecting from local machine only.

    mysql> GRANT ALL ON tigasedb.* TO tigase_user
                IDENTIFIED BY 'tigase_passwd';

And now you can update user permission changes in the database:

mysql> FLUSH PRIVILEGES;
Important

It’s essential to enable log_bin_trust_function_creators option in MySQL server, for example by running:

mysql> SET GLOBAL log_bin_trust_function_creators = 1;
Installing Schemas

Starting with v8.0.0 the Schemas are no longer linked, and will need to manually be installed in the following order.

Switch to the database you have created:

mysql> use tigasedb;
Note
We are assuming you run the mysql client in Linux from the Tigase installation directory, so all file links will be relative.

Next install the schema files:

mysql> source database/mysql-common-0.0.1.sql;

You will need to repeat this process for the following files:

mysql-common-0.0.1.sql
mysql-common-0.0.2.sql
mysql-server-7.0.0.sql
mysql-server-7.1.0.sql
mysql-server-8.0.0.sql
mysql-muc-3.0.0.sql
mysql-pubsub-3.1.0.sql
mysql-pubsub-3.2.0.sql
mysql-pubsub-4.0.0.sql
mysql-http-api-2.0.0.sql

Other components may require installation such as:

mysql-socks5-2.0.0.sql
mysql-push-1.0.0.sql
mysql-message-archiving-2.0.0.sql
mysql-unified-archive-2.0.0.sql
Windows instructions:

On Windows you have probably to enter the full path, assuming Tigase is installed in C:\Program Files\Tigase:

mysql> source c:/Program Files/Tigase/database/mysql-common-0.0.1.sql;
mysql> source c:/Program Files/Tigase/database/mysql-common-0.0.2.sql;
mysql> source c:/Program Files/Tigase/database/mysql-server-7.0.0.sql;
and so on...
Configuring From the Linux Shell Command Line

Follow steps below to prepare the MySQL database:

Create the database space for the Tigase server:

mysqladmin -p create tigasedb

Add the tigase_user user and grant access to the tigasedb database. Depending on how you plan to connect to the database (locally or over the network) use one of following commands or all if you are not sure:

Selective access configuration
Grant access to tigase_user connecting from any network address.
echo "GRANT ALL ON tigasedb.* TO tigase_user@'%' \
            IDENTIFIED BY 'tigase_passwd'; \
            FLUSH PRIVILEGES;" | mysql -u root -pdbpass mysql
Grant access to tigase_user connecting from localhost.
echo "GRANT ALL ON tigasedb.* TO tigase_user@'localhost' \
            IDENTIFIED BY 'tigase_passwd'; \
            FLUSH PRIVILEGES;" | mysql -u root -pdbpass mysql
Grant access to tigase_user connecting from local machine only.
echo "GRANT ALL ON tigasedb.* TO tigase_user \
            IDENTIFIED BY 'tigase_passwd'; \
            FLUSH PRIVILEGES;" | mysql -u root -pdbpass mysql
Schema Installation

Load the proper mysql schemas into the database.

mysql -u dbuser -p tigasedb < mysql-common-0.0.1.sql
mysql -u dbuser -p tigasedb < mysql-common-0.0.2.sql
etc..

You will need to repeat this process for the following files:

mysql-common-0.0.1.sql
mysql-common-0.0.2.sql
mysql-server-7.0.0.sql
mysql-server-7.1.0.sql
mysql-server-8.0.0.sql
mysql-muc-3.0.0.sql
mysql-pubsub-3.1.0.sql
mysql-pubsub-3.2.0.sql
mysql-pubsub-4.0.0.sql
mysql-http-api-2.0.0.sql

Other components may require installation such as:

mysql-socks5-2.0.0.sql
mysql-push-1.0.0.sql
mysql-message-archiving-2.0.0.sql
mysql-unified-archive-2.0.0.sql
Configuring MySQL for UTF-8 Support

In my.conf put following lines:

[mysql]
default-character-SET=utf8

[client]
default-character-SET=utf8

[mysqld]
init_connect='SET collation_connection = utf8_general_ci; SET NAMES utf8;'
character-set-server=utf8
default-character-SET=utf8
collation-server=utf8_general_ci
skip-character-set-client-handshake

Then connect to the database from the command line shell check settings:

SHOW VARIABLES LIKE 'character_set_database';
SHOW VARIABLES LIKE 'character_set_client';

If any of these shows something else then 'utf8' then you need to fix it using the command:

ALTER DATABASE tigasedb DEFAULT CHARACTER SET utf8;

You can now also test your database installation if it accepts UTF-8 data. The easiest way to ensure this is to just to create an account with UTF-8 characters:

call TigAddUserPlainPw('żółw@some.domain.com', 'żółw');

And then check that the account has been created:

SELECT * FROM tig_users WHERE user_id = 'żółw@some.domain.com';

If the last command gives you no results it means there is still something wrong with your settings. You might also want to check your shell settings to make sure your command line shell supports UTF-8 characters and passes them correctly to MySQL:

export LANG=en_US.UTF-8
export LOCALE=UTF-8
export LESSCHARSET='utf-8'

It seems that MySQL 5.0.x also needs extra parameters in the connection string: '&useUnicode=true&characterEncoding=UTF-8' while MySQL 5.1.x seems to not need it but it doesn’t hurt to have it for both versions. You have to edit etc/config.tdsl file and append this to the database connection string.

For MySQL 5.1.x, however, you need to also update code for all database stored procedures and functions used by the Tigase. They are updated for Tigase version 4.4.x and up, however if you use an older version of the Tigase server, you can reload stored procedures using the file from SVN.

Other MySQL Settings Worth Considering

There are a number of other useful options, especially for performance improvements. Please note, you will have to review them as some of them may impact data reliability and are useful for performance or load tests installations only.

# InnoDB seems to be a better choice
# so lets make it a default DB engine
default-storage-engine = innodb

Some the general MySQL settings which mainly affect performance:

key_buffer = 64M
max_allowed_packet = 32M
sort_buffer_size = 64M
net_buffer_length = 64K
read_buffer_size = 16M
read_rnd_buffer_size = 16M
thread_stack = 192K
thread_cache_size = 8
query_cache_limit = 10M
query_cache_size = 64M

InnoDB specific settings:

# Keep data in a separate file for each table
innodb_file_per_table = 1
# Allocate memory for data buffers
innodb_buffer_pool_size = 1000M
innodb_additional_mem_pool_size = 100M
# A location of the MySQL database
innodb_data_home_dir = /home/databases/mysql/
innodb_log_group_home_dir = /home/databases/mysql/
# The main thing here is the 'autoextend' property
# without it your data file may reach maximum size and
# no more records can be added to the table.
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_file_size = 10M
innodb_log_buffer_size = 32M
# Some other performance affecting settings
innodb_flush_log_at_trx_commit = 2
innodb_lock_wait_timeout = 50
innodb_thread_concurrency = 16

These settings may not be fully optimized for your system, and have been only tested on our systems. If you have found better settings for your systems, feel free to let us know.

Support for emoji and other icons

Tigase Database Schema can support emojis and other icons, however by using UTF-8 in mysqld settings will not allow this. To employ settings to support emojis and other icons, we recommend you use the following in your MySQL configuration file:

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_bin

Doing this, Tigase XMPP Server Database will still use utf8 character set, with utf8_general_ci as collation, and only fields which require support for emojis will be converted to utf8mb4.

Note
Database URI passed in Tigase XMPP Server config MUST NOT contain &characterEncoding=UTF-8 as in other case it will override utf8mb4 client charset with utf8 charset! NOTE: Tigase XMPP Server databases should be created with utf8_general_ci collation as it will work properly and is fastest from utf8 collations supported by MySQL

9.4.3. Prepare the Derby Database for the Tigase Server

This guide describes how to prepare Derby database for connecting the Tigase server.

Basic Setup

Preparation of Derby database is quite simple, but the following assumptions are made

  • DerbyDB - Derby database name

  • database/ directory contains all necessary schema files

  • jars/ and libs/ directories contains Tigase and Derby binaries

General Approach

From the main Tigase directory execute following commands (Linux and Windows accordingly)

Note
You must use these sql files on order FIRST!

Linux

java -Dij.protocol=jdbc:derby: -Dij.database="DerbyDB;create=true" -cp libs/derby.jar:libs/derbytools.jar:jars/tigase-server.jar org.apache.derby.tools.ij database/derby-common-0.0.1.sql

Windows

java -Dij.protocol=jdbc:derby: -Dij.database="DerbyDB;create=true" -cp libs\derby.jar;libs\derbytools.jar;jars\tigase-server.jar org.apache.derby.tools.ij "database\derby-common-0.0.1.sql"

This will create Derby database named DerbyDB in the main Tigase directory and load common version for common v0.1.

You will need to repeat this process again in for following order:

derby-common-0.0.1.sql
derby-common-0.0.2.sql
derby-server-7.0.0.sql
derby-server-7.1.0.sql
derby-server-8.0.0.sql
derby-muc-3.0.0.sql
derby-pubsub-3.1.0.sql
derby-pubsub-3.2.0.sql
derby-pubsub-4.0.0.sql
derby-http-api-2.0.0.sql

Other components may require installation such as:

derby-socks5-2.0.0.sql
derby-push-1.0.0.sql
derby-unified-archive-2.0.0.sql
Connecting Tigase to database

Once the database is setup, configure the config.tdsl file in Tigase and add the following configuration:

dataSource {
    default () {
        uri = 'jdbc:derby:{location of derby database};'
    }
}

9.4.4. Prepare the MS SQL Server Database for the Tigase Server

This guide describes how to prepare the MS SQL Server database for connecting the Tigase server to it.

It’s expected that a working installation of Microsoft SQL Server is present. The following guide will describe the necessary configurations required for using MS SQL Server with Tigase XMPP Server.

Preparing MS SQL Server Instance

After installation of MS SQL Server an instance needs to be configure to handle incoming JDBC connections. For that purpose it’s required to open SQL Server Configuration Manager. In the left-hand side panel navigate to SQL Server Configuration Manager, then SQL Server Network Configuration → Protocols for ${INSTANCE_NAME}. After selecting instance in the right-hand side panel select TCP/IP and open Properties, in the Protocol tab in General section select Yes for Enabled property. In the IP Addresses tab select Yes for Active and Enabled properties of all IP Addresses that you want MS SQL Server to handle. Subsequently set the TCP Port property (if missing) to the default value - 1433. A restart of the instance may be required afterwards.

Configuration using MS SQL Server Management Studio

In order to prepare the database you can use either a wizard or execute queries directly in the Query Editor. Firstly you need to establish a connection to the MS SQL Server instance. From Object Explorer select Connect and in the Connect to Server dialog enter administrator credentials.

Using Wizards
  • Create Login

    In the left-hand side panel select Security → Logins and from context menu choose New Login, in the Wizard window enter desired Login name, select SQL Server authentication and enter desired password subsequently confirming action with OK

  • Create Database

    From the Object Explorer select Databases node and from context menu select New Database; in the Wizard window enter desired Database name and enter previously created Login name into Owner field; subsequently confirming action with OK.

Using Queries

From the Object Explorer root node’s context menu select New Query. In the Query windows execute following statements adjusting details to your liking:

USE [master]
GO

CREATE DATABASE [tigasedb];
GO

CREATE LOGIN [tigase] WITH PASSWORD=N'tigase12', DEFAULT_DATABASE=[tigasedb]
GO

ALTER AUTHORIZATION ON DATABASE::tigasedb TO tigase;
GO
Import Schema

From the File menu Select Open → File (or use Ctrl+O) and then open following files:

sqlserver-common-0.0.1.sql
sqlserver-common-0.0.2.sql
sqlserver-server-7.0.0.sql
sqlserver-server-7.1.0.sql
sqlserver-server-8.0.0.sql
sqlserver-muc-3.0.0.sql
sqlserver-pubsub-3.1.0.sql
sqlserver-pubsub-3.2.0.sql
sqlserver-pubsub-4.0.0.sql
sqlserver-http-api-2.0.0.sql
Note
These files must be done sequentially! They are not linked, and so may need to be done one at a time.

Other components may require installation such as:

sqlserver-socks5-2.0.0.sql
sqlserver-push-1.0.0.sql
sqlserver-message-archiving-2.0.0.sql
sqlserver-unified-archive-2.0.0.sql

Subsequently select created database from the list of Available Databases (Ctrl+U) available on the toolbar and execute each of the opened files in the order listed above.

Configuring from command line tool

Creation of the database and import of schema can be done from command line as well. In order to do that, execute following commands from the directory where Tigase XMPP Server is installed otherwise paths to the schema need to be adjusted accordingly:

sqlcmd -S %servername% -U %root_user% -P %root_pass% -Q "CREATE DATABASE [%database%]"
sqlcmd -S %servername% -U %root_user% -P %root_pass% -Q "CREATE LOGIN [%user%] WITH PASSWORD=N'%password%', DEFAULT_DATABASE=[%database%]"
sqlcmd -S %servername% -U %root_user% -P %root_pass% -d %database% -Q "ALTER AUTHORIZATION ON DATABASE::%database% TO %user%;"
sqlcmd -S %servername% -U %root_user% -P %root_pass% -d %database% -i database\sqlserver-schema-7-1-schema.sql
sqlcmd -S %servername% -U %root_user% -P %root_pass% -d %database% -i database\sqlserver-schema-7-1-sp.sql
sqlcmd -S %servername% -U %root_user% -P %root_pass% -d %database% -i database\sqlserver-schema-7-1-props.sql
sqlcmd -S %servername% -U %root_user% -P %root_pass% -d %database% -i database\sqlserver-pubsub-schema-3.2.0.sql

Above can be automatized with provided script %tigase-server%\scripts\db-create-sqlserver.cmd (note: it needs to be executed from main Tigase XMPP Server directory due to maintain correct paths):

$ scripts\db-create-sqlserver.cmd %database_servername% %database_name% %tigase_username% %tigase_password% %root_username% %root_password%

If no parameters are provided then the following defaults are used:

%database_servername%=localhost
%database_name%=tigasedb
%tigase_username%=tigase
%tigase_password%=tigase12
%root_username%=root
%root_password%=root
Tigase configuration - config.tdsl

Configuration of the MS SQL Server follows general database convention.

dataSource {
    default () {
        uri = 'jdbc:[jtds:]sqlserver://db_hostname:port[;property=val]'
    }
}

where any number of additional parameters can (and should) consist of:

  • databaseName - name of the database

  • user - username configured to access database

  • password - password for the above username

  • schema - name of the database schema

  • lastUpdateCount - 'false' value causes all update counts to be returned, including those returned by server triggers

Example:

dataSource {
    default () {
        uri = 'jdbc:sqlserver://hostname:1433;databaseName=tigasedb;user=tigase;password=tigase12;schema=dbo;lastUpdateCount=false'
    }
}
JDBC: jTDS vs MS JDBC driver

Tigase XMPP Server supports two JDBC drivers intended to be used with Microsoft SQL Server - one created and provided by Microsoft itself and the alternative implementation - jTDS. Tigase is shipped with the latter in the distribution packages. Starting with the version 7.1.0 we recommend using jDTS driver that is shipped with Tigase as JDBC driver created by Microsoft can cause problems with some components in cluster installations. MS driver can be downloaded form the website: JDBC Drivers 4.0, 4.1 for SQL Server then unpack the archive. Copy sqljdbc_4.0/enu/sqljdbc4.jar file to ${tigase-server}/jars directory.

Depending on the driver used uri needs to be configured accordingly.

  • Microsoft driver:

    dataSource {
        default () {
            uri = 'jdbc:sqlserver://...'
        }
    }
  • jDTS driver

    dataSource {
        default () {
            uri = 'jdbc:jdts://...'
        }
    }

9.4.5. Prepare the PostgreSQL Database for the Tigase Server

This guide describes how to prepare PostgreSQL database for connecting to Tigase server.

The PostgreSQL database can be prepared in many ways. Below are presented two possible ways. The following assumptions apply to both methods:

  • admin_db_user - database user with admin rights

  • tigase_user - database user for Tigase

  • tigasedb - database for Tigase

Configuring from PostgreSQL Command Line Tool

Run the PostgreSQL command line client and enter following instructions:

Add the tigase_user:

psql=# create role tigase_user with login password 'tigase123';

Next, Create the database for the Tigase server with tigase_user as owner of database:

psql=# create database tigasedb owner tigase_user;
Schema Installation

Load database schema to initialize the Tigase server from the file that corresponds to the version of Tigase you want to use. First you need to switch to tigasedb.

psql=# \connect tigasedb

Begin by applying the basic Schema

psql=# \i database/postgresql-common-0.0.1.sql

Continue by adding the schema files listed below:

postgresql-common-0.0.1.sql
postgresql-common-0.0.2.sql
postgresql-server-7.0.0.sql
postgresql-server-7.1.0.sql
postgresql-server-8.0.0.sql
postgresql-muc-3.0.0.sql
postgresql-pubsub-3.1.0.sql
postgresql-pubsub-3.2.0.sql
postgresql-pubsub-4.0.0.sql
postgresql-http-api-2.0.0.sql

Other components may require installation such as:

postgresql-socks5-2.0.0.sql
postgresql-push-1.0.0.sql
postgresql-message-archiving-2.0.0.sql
postgresql-unified-archive-2.0.0.sql
Configuring From the Linux Shell Command Line

Follow steps below to prepare the PostgreSQL database:

First, add the tigase_user:

createuser -U admin_db_user -W -D -R -S -P tigase_user

You will be asked for credentials for admin_db_user and password for new database user.

Create the database for the Tigase server with tigase_user as owner of database:

createdb -U admin_db_user -W -O tigase_user tigasedb
Database Schema Installation

Load database schema to initialize the Tigase server

psql -q -U tigase_user -W tigasedb -f database/postgresql-common-0.0.1.sql
psql -q -U tigase_user -W tigasedb -f database/postgresql-common-0.0.2.sql
etc..

Continue by adding the schema files listed below:

postgresql-common-0.0.1.sql
postgresql-common-0.0.2.sql
postgresql-server-7.0.0.sql
postgresql-server-7.1.0.sql
postgresql-server-8.0.0.sql
postgresql-muc-3.0.0.sql
postgresql-pubsub-3.1.0.sql
postgresql-pubsub-3.2.0.sql
postgresql-pubsub-4.0.0.sql
postgresql-http-api-2.0.0.sql

Other components may require installation such as:

postgresql-socks5-2.0.0.sql
postgresql-push-1.0.0.sql
postgresql-message-archiving-2.0.0.sql
postgresql-unified-archive-2.0.0.sql
Note
The above commands should be executed from the main Tigase directory. The initialization schema file should be also available locally in database/ directory of your Tigase installation.

9.4.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.

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.

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
db.createUser( { user: "tigase",
                 pwd: "password",
                 customData: { employeeId: 12345 },
                 roles: [ "root" ]
                }
              )

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'
}
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 7. 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 8. 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 9. 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.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. 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.7. 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.8. Importing Existing Data

Information about importing user data from other databases.

9.8.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.

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.8.2. Integrating Tigase Server with Drupal

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.8.3. 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.9. Schema Updates

This is a repository for Schema updates in case you have to upgrade from older installations.

9.9.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) {}
            'SCRAM-SHA-256' (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.9.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.

Warning
You MUST update your database to be compliant with the new schema. If you do not, Tigase will not function properly.
Note
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
  • Windows:

    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} (required)

  • -schemaVersion schema version {4, 5, 5-1}

  • -dbName database name (required)

  • -dbHostname database hostname (default is localhost)

  • -dbUser tigase username

  • -dbPass tigase user password

  • -rootUser database root username (required)

  • -rootPass database root password (required)

  • -file path to sql schema file (required)

  • -query sql query to execute

  • -logLevel java logger Level

  • -adminJID comma separated list of admin JIDs

  • -adminJIDpass password (one for all entered JIDs

Note
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

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. Advanced Message Processing - AMP XEP-0079

Tigase server offers support for XEP-0079: Advanced Message Processing (often abbreviated to AMP).

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.1.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.1.2. Secondly: component

By default Tigase loads the component with the standard name amp

10.1.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.2. Server Monitoring

All the documentation and resources related to the Tigase server monitoring.

10.2.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 build 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[https://tigase.tech/projects/tigase-extras/repository] built and included 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.2.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.2.3. Monitor Component

Tigase includes an Monitor 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.

Monitor Component is based on eventbus which in turn 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

Monitor Component 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

Monitor Component 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 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, monitor will just trigger and shut down. There are two different methods that monitor 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@<VHost> user must be made. Keep in mind that subscriptions are not persistent across server restarts, or triggers.
The monitor 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@<VHost>'
    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:

  • DiskUsageMonitorEvent 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@<VHost>'
    id='sub1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <subscribe node='*|tigase:monitor:event' jid='$USER_JID'/>
  </pubsub>
</iq>
Sample notification from Monitor
<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@<VHost>'
    'mailer-smtp-host' = 'mail.tigase.org'
    'mailer-smtp-password' = '********'
    'mailer-smtp-port' = '587'
    'mailer-smtp-username' = 'sender'
    'mailer-to-addresses' = 'receiver@<VHost>,admin@<VHost>'
}

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.2.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.3. Server to Server Protocol Settings

Tigase server-to-server communication component facilitates communication with other XMPP servers (federation) and 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.3.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.3.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.3.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.3.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.3.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.3.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.4. 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.4.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.

  • SeeOtherHostDualIP - matches internal Tigase cluster nodes against the lookup table to provide relevant redirection hostname/IP (by default internal Tigase tig_cluster_nodes table will be used)

10.4.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' = [] - an array 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 against the lookup table to provide matching and relevant redirection hostname/IP. By default internal Tigase tig_cluster_nodes table is 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-repository-notifications needs to be enabled in ClusterConnectionManager:

'cl-comp' {
    'eventbus-repository-notifications' = true
}

10.4.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-resolver-class' = 'tigase.util.DNSResolverDefault'
    'tigase-primary-address' = 'hostname.local'
    'tigase-secondary-address' = 'hostname'
}

10.5. 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.5.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 enable 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 (class doesn’t have to be specified when using default name).

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, without any additional configurations provided, the component would be practically useless. It is necessary to configure the virtual host domains of the external component during run-time via ad-hoc commands to make use of this component.

You may additionally configure the bind-ext-hostnames property.

To configure external component connections using Admin UI you need to open Admin UI web page (if you are logged in the same computer on which Tigase XMPP Server is running by default it should be available at http://localhost:8080/admin/). Then you should click on Configuration on the left side of the Admin UI web page and then select Add new item on ext component or by execution corresponding ad-hoc command on ext component using ad-hoc capable XMPP client, ie. Psi.

adminui ext add item button

You will be presented with a form which you should fill to configure external component connection details:

adminui ext add item form

  • Domain name - external component domain name (muc.devel.tigase.org)

  • Domain password - password for authentication of the external component connection (muc-pass)

  • Connection type - accept to make component wait for connection or connect force component to connect to the server (connect)

  • Port number - port on which component should wait for connection or on which it try to connect (5270)

  • Remote host - host to connect to (devel.tigase.org) (may be left blank if component will only accept connections)

  • Protocol - id of protocol used for establishing connection

Additional options may be left with defaults.

Later on if you would like to modify this values, you can do that using Admin UI by clicking on Configuration and Remove an item or Update item configuration at ext component or by execution corresponding ad-hoc commands on ext component using ad-hoc capable XMPP client, ie. Psi.

10.5.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…​

Usage with shared database (since version 8.0.0)

When you are using Tigase server 8.0.0 or newer in the "external component mode" while using shared default "user repository" and you have main server also running Tigase XMPP Server 8.0.0 or newer, then you can benefit from the remote management of the component connections from the main server. To use that, you need to enable external component and external component manager on the main server by adding following line to the config file:

'ext' () {}
'ext-man' () {}

With that in place you can use Admin UI or ad-hoc commands available at ext-man component of the main server to configure connection details of the servers running in the component mode.

In Admin UI you click on Configuration section and select Add new item at the ext-man component, which will present you with a following form to fill in external component connectivity details:

adminui extman add item form

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'

Knowing that we can now create simple configuration file for Tigase XMPP Server:

admins = [ 'admin@devel.tigase.org' ]
'config-type' = 'component'
debug = [ 'server' ]
'virtual-hosts' = [ 'devel.tigase.org' ]
dataSource {
    default () {
        uri = 'master_server_default_database_url'
    }
}
userRepository {
    default () {}
}
authRepository {
    default () {}
}
muc (class: tigase.muc.MUCComponent) {}
ext () {
}

where master_server_default_database_url is the same URL as the one used on the main server for default data source.

With that in place we can use ad-hoc commands or Admin UI on the main server to configure Tigase XMPP Server to accept external component connections and to connect from the external component to the master server.

Adding external component connection settings to the manager (ext-man) using Admin UI

adminui extman add item form external muc

You need to pass:

  • Domain name - external component domain name (muc.devel.tigase.org)

  • Domain password - password for authentication of the external component connection (muc-pass)

  • Connection type - accept to make component wait for connection or connect force component to connect to the server (connect)

  • Port number - port on which component should wait for connection or on which it try to connect (5270)

  • Remote host - host to connect to (devel.tigase.org)

  • Protocol - id of protocol used for establishing connection

Additional options may be left with defaults.

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 to the server running in the component mode 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 () {}

and then to add new connection domain to the main server external component settings and to the external component manager settings. You basically do the same thing as you did while adding only MUC component as the external component.

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 () {
}
userRepository {
    default () {}
}
authRepository {
    default () {}
}
muc (class: tigase.muc.MUCComponent) {}
pubsub (class: tigase.pubsub.PubSubComponent) {}

With this configuration you do not need to configure entries in ext-man for PubSub component, only for MUC component but you need to user client as the value for protocol field.

Usage with a separate database
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 () {
}

To make this new instance connect to the Tigase XMPP Server, you need to create one more file with external connection configuration at etc/externalComponentItems which will be loaded to the local database and then removed.

muc.devel.tigase.org:muc-pass:connect:5270:devel.tigase.org:accept
Warning
While loading configuration from etc/externalComponentItems file is supported, we recommend usage of shared database if possible. In future this method may be deprecated.
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 external component connection to the main server for the component domain using Admin UI or ad-hoc command on the main server.

Then we can use following configuration on the server running in the component mode:

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 () {
}

and we need to create a file with configuration for external component connection which will be loaded to the internal database:

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 () {
}
userRepository {
    default () {}
}
authRepository {
    default () {}
}
muc (class: tigase.muc.MUCComponent) {}
pubsub (class: tigase.pubsub.PubSubComponent) {}

and example of the external connections configuration file:

muc.devel.tigase.org:muc-pass:connect:5270:devel.tigase.org:client

10.6. 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 8.0.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.6.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.

On the server side we will enable ComponentProtocol component as we need to do to enable external component without clustering support.

Then using Admin UI we will add a new external component connection settings using Add item position for ext component in Configuration section of the web page just as it is described in External Component Configuration section.

adminui ext add item form

The only change here is that we will specify value for field Load balancer class and we will use ReceiverBareJidLB as a value.

The configuration for both instances of the MUC component (identical for both of them) can be done in the same way as it is done for a single instance of the MUC component. There is nothing to change here.

The difference is one small element in the server configuration. At the value of Load balancer class field in Add item form is set to 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.6.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. To do so, we are configuring Tigase XMPP Server to run in the cluster mode and on each of cluster nodes we need to enable ComponentProtocol component.

This can be simply done by adding following line to the server configuration file:

ext () {}

After this is done we need to add a new external component connection settings using Add item position for ext component in Configuration section of the web page just as it is described in External Component Configuration section.

As you can see there is nothing special here. The most interesting part comes on the MUC side, but it is only a very small change from the configuration of the component to use with single node Tigase XMPP Server installation.

When you are adding/configuring external component settings using Admin UI (Add item or Update item configuration for ext-man component) or using separate configuration file (when you are not using shared database) then you need to pass as a value for Remote host field a semicolon separated list of all of the cluster nodes to which external component should connect.

In our case it would be:

red.xmpp-test.org;green.xmpp-test.org;blue.xmpp-test.org

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.7. 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.7.1. Configuration

To disable C2S, use the following line in config.tdsl folder.

c2s (active: false) {}

Otherwise, C2S component is activated by default.

10.7.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.7.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.7.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.8. 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.8.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 using ad-hoc 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.

11. Using Tigase

This section keeps set of documents which apply to all the Tigase server version and contain more generic or introductory information on general use and features.

11.1. Offline Messages

Tigase like any XMPP server supports storing of messages for users who are offline so that they may receive messages sent to them while they were not logged in.

By default, Tigase MessageAmp processor is responsible for storing offline messages, and will automatically store offline messages. This guide has multiple sections for setting limits globally, per user, and others.

Many of the features listed here require the use of the Advanced Message Processor Plugin which is turned on by default. To ensure AMP is turned on your system, view your config.tdsl file and be sure the following is there in your plugins line:

'sess-man' {
    amp () {}
}

Messages will be delivered to intended recipients when they first login after roster exchange.

11.1.1. Offline Message Limits

Support for limiting number of stored offline messages on a per-user basis has now been added to Tigase as of v7.1.0. By default, Tigase comes with a limit of stored offline messages which is set for every user. This limit by default is 100 offline messages for barejid-barejid pair. This value can be changed by the store-limit property. To change to 200 messages on barejid-barejid paid, add the following entries to the config.tdsl file:

amp {
    'store-limit' = 200L
}
'sess-man' {
    amp () {
        'store-limit' = 200L
    }
}

This setting applies to every user.

User Limit

Each user is able to configure the number of offline messages which should be stored for him. To enable this feature, the following lines need to be entered into the config.tdsl file:

amp {
    'user-store-limit-enable' = true
}
'sess-man' {
    amp () {
        'user-store-limit-enable' = true
    }
}

Values of user-specific limits will be stored in UserRepository under subnode of offline-msgs and key store-limit. Data storage will be stored in tig_pairs key with the value and a proper record from tig_nodes points to this record.

Handling of Offline Messages Exceeding Limits

There are two possible ways to handle offline messages that exceed the limitations: . error sending message with error type back to sender. . drop drop of message without notifications to sender.

By default, Tigase sends a message back to the original sender with an error type of service-unavailable with a proper description of error according to XEP-0160. However, it is possible to change this behavior to better suit your needs. This is done by adding the following line to your config.tdsl file.

'sess-man' {
    amp () {
        'quota-exceeded' = 'drop'
    }
}

This will force Tigase to drop packets that exceed the offline message limit.

Setting the Limits by User

Users wishing to set a custom limit of stored offline messages for barejid-barejid pairs needs to send the following XMPP stanza to the server:

<iq type="set" id="${random-id}">
  <msgoffline xmlns="msgoffline" limit="${limit}"/>
</iq>

Where: . ${random-id} is a random ID of the stanza (can be any string). . ${limit} is the integer value of the offline message limit. This can be set to false to disable offline message limits.

In response, the server will send back an iq stanza with a result type:

<iq type="result" id="${random-id}">
  <msgoffline xmlns="msgoffline" limit="${limit}"/>
</iq>
Example of Setting Limit of Stored Offline Messages to 10

XMPP client sends the following to the server:

<iq type="set" id="aabba">
  <msgoffline xmlns="msgoffline" limit="10"/>
</iq>

Server response:

<iq type="result" id="aabba">
  <msgoffline xmlns="msgoffline" limit="10"/>
</iq>
Example of Disabling Offline Message Limit

XMPP client sends the following to the server:

<iq type="set" id="aabbb">
  <msgoffline xmlns="msgoffline" limit="false"/>
</iq>

Server response:

<iq type="result" id="aabbb">
  <msgoffline xmlns="msgoffline" limit="false"/>
</iq>

11.1.2. Storing offline messages without body content

Tigase can now store offline messages without <body/> content.

See XEP-0334 for protocol details.

This can include message receipts, and messages with specific do-not-store tags.

Support has been added to set a list of paths and xmlns to trigger and place storage of offline messages using the following settings in config.tdsl:

'sess-man' {
    amp () {
        'msg-store-offline-paths' = [ '/message/received[urn:xmpp:receipts]', '/message/store-offline' ]
    }
}

This example results in two settings:

/message/received[urn:xmpp:receipts]

Results in storage of messages with a recieved subelement and with the xlmns set to urn:xmpp:receipts

/message/store-offline

Results in storing messages with a store-offline subelement without checking xmlns.

Filtering of offline storage

It is possible to set storage of other types to save:

'sess-man' {
    amp () {
        'msg-store-offline-paths' = [ '/message/store-offline', '-/message/do-not-store' ]
    }
}

The above setting in the config.tdsl file will cause that:

  • messages with <store-offline> subelement will be stored without checking for associated xmlns.

  • messages with <do-not-store> element will not be saved.

Any of these can be adjusted for your installation, remember that a '-' will stop storage of messages with the indicated property. Messages will be checked by these matchers and if any of them result in a positive they will override default settings.

For example, if you wanted to store messages with <received> element, but not ones with <plain> element, your filter will look like this:

'sess-man' {
    amp () {
        'msg-store-offline-paths' = [ '/message/received', '-/message/plain' ]
    }
}

However…​.

Note
THE ABOVE STATEMENT WILL NOT WORK As it will just store all messages with <received> subelement.

The below statement will properly filter your results.

'sess-man' {
    amp () {
        'msg-store-offline-paths' = [ '-/message/plain', '-/message/received' ]
    }
}

Filtering logic is done in order from left to right. Matches on the first statement will ignore or override matches listed afterwards.

11.1.3. Disabling Offline Messages

If you wish to disable the storing of offline messages, use the following line in your config.tdsl file. This will not disable other features of the AMP plugin.

'sess-man' {
    amp () {
        msgoffline (active: false) {}
    }
}

11.2. Last Activity

Tigase XMPP Server supports XEP-0012: Last Activity extension, which allows retrieval information when particular contact was active last time. It’s not enabled by default.

The functionality itself is split in two plugins:

  • jabber:iq:last-marker - responsible for updating information about last activity of user

  • jabber:iq:last - responsible for handling requests to retrieve last activity information (it depends on jabber:iq:last-marker plugin).

In order to enable functionality you should add both plugins to your configuration file

'sess-man' {
    'jabber:iq:last-marker' (active: true) {
            'jabber:iq:last' (active: true) {}
    }
}

11.2.1. What updates last activity

By default marker plugin will only update last activity information on presence stanza. It’s possible to control whether <presence/> and/or <message/> should update with respective options:

'sess-man' {
    'jabber:iq:last-marker' (active: true) {
        message = true
        presence = true
    }
}

Those settings will cause updating last activity information for both <message/> and <presence/> stanzas

11.2.2. Persist everything to repository

To lower impact on performance, by default last activity information is persisted to repository less frequently. This can yield slightly less accurate results on installations with multiple cluster nodes with users having multiple resources connected. To get more accurate results you should set persistAllToRepository to true, which will cause all update times to be persisted (please bear in mind that this could cause higher impact on the repository).

'sess-man' {
    'jabber:iq:last-marker' (active: true) {
        persistAllToRepository = true
    }
}

11.3. Tigase Log Guide

Tigase has multiple levels of logging available to help provide targeted and detailed information on processes, components, or traffic. In these documents we will look at where tigase generates logs, what they contain, and how we can customize them to our needs.

11.3.1. install.log

This log file is a basic list of files that are made on install of Tigase server. Although you may not need to use it, it can provide a handy list to see if any files were not written to your hard drive upon installation.

11.3.2. derby.log

If you are using the derby database installed with Tigase, this is the startup log for the database itself. Issues that might be related to the database, can be found in this file. Typically, if everything works okay, it’s a very small file with only 10 lines. It is overwritten on startup of the database.

11.3.3. etc/config-dump.properties

The config-dump.properties is dump file of all your properties listed for every option within Tigase and components. The structure of the log lines is the same as the structure of Tigase XMPP Server config file - TDSL. Lets take the value for admins, listing who is administrator for the server.

admins = [ 'admin@jabber.freehost.org', 'administrator@jabber.freehost.org', 'fJones@jabber.freehost.org' ]

The admin parameter which is an array of strings and has 3 users listed.

This file is re-written every time tigase starts.

11.3.4. logs/tigase.log.#

The tigase.log files are where the majority of logging will take place. The rules for writing to these longs can be manipulated by editing files in the int.properties file. To see how, see the Debugging Tigase section of this manual for more details about how to turn on debug logging, and how to manipulate log settings. Entries to these logs are made in the following format:

2015-08-10 13:09:41.504 [main]      Sctipr.init()         INFO: Initilized script command, id: comp-manager, lang:Groovy, ext: groovy

The format of these logs is below: <timestamp> <thread_name> <class>.<method> <log_level>: <message> <thread_name>. This can vary - for components it would be <direction>_<int>_<component name>, for plugins it will just be the plugin name.

Let’s look at another example from the log file.

2015-08-10 12:31:40.893 [in_14_muc] InMemoryMucRepository.createNewRoom()   FINE: Creating new room 'chatroom@muc.localhost.com'

The process ID may sometimes come in a different format such as [in_14-muc] which specifies the component (muc) along with the process thread identifier (14). As you can see, the format otherwise is nearly identical.

tigase.log.# files are rotated - this means that server begins writing to tigase.log.0 when it is first run, and continues to dump information until the log size limit is hit. At this point, Tigase renames tigase.log.0 as tigase.log.1. A new tigase.log.0 will be created, and Tigase will begin logging to this file. When this file is full, tigase.log.1 will be renamed tigase.log.2 and tigase.log.0 will be renamed tigase.log.1. Using this scheme, tigase.log.0 will always be your most recent log.

By default, Tigase has a limit of 10000000 bytes or 10MB with a file rotation of 10 files. You can edit these values by editing the config.tdsl file and adding the following lines.

logging {
    java.util.logging.FileHandler {
        count = '15'
        limit = '20000000'
    }
}

This code, if entered into the config.tdsl file increases the size of the files to 15, and enlarges the maximum size to 20MB. Note the larger the collective log space is, the larger number of sectors on hard disk are active. Large log blocks may impact system performance.

You may see a tigase.log.0.lck file in the directory while the server is running. This is a temporary file only and is deleted once Tigase is cleanly shut down.

11.3.5. logs/statistics.log.#

Statistics log will duplicate any information that is related to sending of statistics to Tigase if you are using an unlicensed copy of Tigase XMPP server. Mainly it will consist output of LicenceChecker. The numbering logic will be the same as tigase.log.# files.

11.3.6. logs/tigase.pid

tigase.pid is a file that just contains the Process ID or PID for the current run of Tigase. It is only valid for the current or most recent run cycle and is overwritten every time Tigase starts.

11.3.7. logs/tigase-console.log

Important
This is the most important log file containing the most essential information related to operation of the Tigase XMPP Server. Any errors or exceptions in this file indicate with high probability serious issues with server operation.

This file contains information related to Tigase’s running environment, and is a dump from the server itself on what is being loaded, when, and if any issues are encountered. It will start by loading Java classes (consequently making sure the Java environment is present and functioning). Then it will begin loading the configuration file, and adding default values to settings that have not been customized. You can then see all the components being loaded, and settings added where default values are needed. Lastly you will see a log of any plugins that are loaded, and any parameters therein. You may see tags such as INFO or WARNING in the logs. Although they may contain important information, the program will continue to operate as normal are not of too great concern.

ERROR flags are issues you will want to pay attention as they may list problems that prevent Tigase or components from properly functioning.

Note
Windows does not create this file, rather the output is shown in the command line and is not dumped to a file.

If Tigase is gracefully shut down, tigase-console.log will add statistics from the server’s operation life in the following format.

component/statistic = value

Any component that may have a statistic, whether used or not, will place a value here

This file can be handy if you are tracking issues in the server.

tigase-console.log is appended during each run session of the server.

11.3.8. Log File Location

You can also change the location of log files if you have a specific directory you wish to use. The configuration may be made by the following lines in your config.tdsl file:

logging {
    java.util.logging.FileHandler {
        pattern = '/var/log/tigase/tigase.log'
    }
}

This setting changes the log file location to /var/log/tigase/ where all log files will be made. Files in the original location will be left.

11.4. Debuging Tigase

If something goes wrong and you can’t find out why it is not working as expected, you might want more detailed debugging options switched on.

Tigase is a Java application and it uses Java logging library, this gives you the flexibility to switch logging on for selected Java packages or even for a single Java class.

Logs files are stored in logs/ directory. tigase-console.log stores basic log data, but is the main log file. tigase.log.N files keep all the detailed logging entries. So this is the place where you should look in case of problems.

11.4.1. Configuration

By default, Tigase has the old debug = ['server'] setting is turned on and does not need to be added.

However, people want to see what is going on the network level. That is what has been sent and what has been received by the server - the actual character data. The class which would print all received and sent character data is: tigase.xmpp.XMPPIOService. To enable all debugging info for this class you have to modify the debug line:

debug = [ 'xmpp.XMPPIOService' ]

You can also have debugging switched on for many packages/classes at the same time:

debug = [ 'cluster' , 'xmpp.XMPPIOService' ]

Other packages you might be interested in are:

  • io can print out what is going on a very low level network level including TLS/SSL stuff.

  • xml would print the XML parser debugging data.

  • cluster would print all the clustering related stuff.

  • xmpp.impl would print logs from all plugins loaded to Tigase server.

Non-Tigase packages

To enable logging for your own packages from those different than Tigase, you have to use another option which has been made available for this:

debug-packages = [ your.com.package ]

11.5. Basic System Checks

Previously, a configuration article is available about Linux settings for high load systems. This has a description of basic settings which are essential to successfully run XMPP service for hundreds or thousands of online users.

Of course, high load and high traffic systems require much more tuning and adjustments. If you use selinux you have to be careful as it can interfere with the service while it is under a high load. Also some firewall settings may cause problems as the system may decide it is under a DDOS attack and can start blocking incoming connections or throttle the traffic.

In any case, there are some basic checks to do every time you deploy XMPP service to make sure it will function properly. I am trying to keep the article mentioned above up to date and add all the settings and parameters I discover while working with different installations. If you have some suggestions for different values or different parameters to add, please let me know.

If you want to run a service on a few cluster nodes (5 or even 10), then manually checking every machine and adjusting these settings is time consuming and it is very easy to forget about.

To overcome this problem I started to work on a shell script which would run all the basic checks and report problems found. Ideally it should be also able to adjust some parameters for you.

Inside the Tigase server scripts/ repository find a script called machine-check.sh. It performs all the basic checks from the article and also tries to adjust them when necessary. Have a look at the code and run for yourself.

Any comments or suggestions, as usual, are very much appreciated.

11.6. Add and Manage Domains (VHosts)

Tigase XMPP Server offers an easy to use and very flexible way to add and manage domains hosted on installation (vhosts).

There are two ways of managing domains you host on your server:

  • using web-based admin management console - Admin UI

  • using XMPP ad-hoc commands by XMPP client, ie. Psi

Note
To use any of those ways, you need to be an administrator of the server, which means that you have a XMPP account created on this XMPP server and your account JID is added to the list of the administrators in the Tigase XMPP Server configuration file.

11.6.1. Using Admin UI

First, you need to open Admin UI web page. By default Admin UI is enabled and available at the port 8080 at path /admin/ on the XMPP server. Assuming that your are logged on the same machine which hosts Tigase XMPP Server, it will be available at http://localhost:8080/admin/.

When you will be prompted for username and password to login to the Admin UI please fill username with full JID of your XMPP admin account and fill password field with password for this account. When you submit correct credentials you will get access to the Admin UI and Tigase XMPP Server configuration and management web-based interface.

Adding a new domain

To add a new domain you need to open Configuration section of the Admin UI (by clicking on Configuration label and then selecting Add new item position which mentions vhost-man.

adminui vhost add item button

After doing that, you will be presented with a form which you need to fill in. This form allows you to pass Domain name to add and other options (some of the are advanced options).

adminui vhost add item form

Tip
All options with exception of Domain name may be changed later on by modifying vhost settings.

When you will be ready, please submit the form using button below the form. As a result you will be presented with a result of this operation. If it was successful it show Operation successful message and if something was not OK, it will display an error to help you fix this issue which you encountered.

Modifying domain settings

Modifying a domain settings is very similar to adding a new domain. You need to open Configuration section of the Admin UI and then select Update item configuration position which mentions vhost-man.

adminui vhost update item button

You will be presented with a list of domains hosted on this Tigase XMPP Server installation. From them you should choose the one for which you wish to modify settings.

adminui vhost update item domains list

After submitting this selection, you will be presented with a the same form as the one used during adding a new domain. It presents configuration options for this domain and currently used values.

adminui vhost update item form

Now you should adjust them as you wish and submit this form using the button below the form.

As a result you will be presented with a result of this operation. If it was successful it show Operation successful message and if something was not OK, it will display an error to help you fix this issue which you encountered.

Removing a domain

Removing a hosted domain from the Tigase XMPP Server installation is quite simple as well. You need to open Configuration section of the Admin UI and then select Remove an item position which mentions vhost-man.

adminui vhost remove item button

You will be presented with a list of domains hosted on this Tigase XMPP Server installation. From them you should select the one which should be removed.

adminui vhost remove item domains list

After submitting your selection, Tigase XMPP Server will try to remove this domain from the list of hosted domains and will present you with the result. If it was successful it show Operation successful message and if something was not OK, it will display an error to help you fix this issue which you encountered.

11.6.2. Using ad-hoc commands

For everybody interested in using our service to host their own XMPP domain we have good news! You do not have to ask an administrator to add your domain or add users for your domain anymore. You can do it on your own.

Please note, this is very new stuff. Something may go wrong or may not be polished. Please report any problems, notices or suggestions.

This is the guide to walk you through the new functions and describes how to add a new domain and new users within your domain.

You can do everything from your XMPP client or you can use our web application that allows you to connect to the service and execute admin commands. I recommend Psi because of its excellent support for parts of the XMPP protocol which are used for domains and user management. You may use other clients as well, but we can only offer support and help if you use Psi client.

Secondly, you need an account on the server. This is because all the commands and features described here are available to local users only. Therefore, if you do not have a registered domain with us yet, please go ahead and register an account on the website either the Jabber.Me or Tigase.IM.

Adding a New Domain

Once you register an account on one of the websites, connect to the XMPP server using the account on the Psi client. We will be using the following account: green@tigase.im which is this guide.

When you are ready right click on the account name in Psi roster window to bring up context menu. Select Service Discovery element.

service disco menu

A new windows pops up as in the example on the right. The service discovery window is where all the stuff installed on XMPP service should show up. Most of elements on the list are well known transports, MUC and PubSub components. The new stuff on the list, which we are interested in, are 2 elements: VHost Manager and Session Manager.

service disco window vhost

VHost Manager component in Tigase is responsible for managing and controlling virtual hosts on the installation. It provides virtual hosts information to all other parts of the system and also allows you to add new hosts and remove/update existing virtual hosts.

Session Manager component in Tigase is responsible for managing users. In most cases online users but it can also perform some actions on user repository where all user data is stored.

Select VHost Manager and double click on it. A new windows shows up (might be hidden behind the service discovery window). The window contains another menu with a few items: Add…​, Remove…​ and Update…​ . These are for adding, removing and updating VHost information. For now, just select the first element Add…​.

command menu add vhost

Click Execute and you get a new window where you can enter all of your VHost configuration details. All fields should be self explanatory. Leave a blank field for Other parameters for now. Owner is you, that is Jabber ID which controls the domain and can change the domain configuration settings or can remove the domain from the service. Administrators field can be left blank or can contain comma separated list of Jabber IDs for people who can manage users within the domain. You do not need to add your user name to the list as Owners can always manage users for the domain.

add vhost window

When you are ready click the Finish button. All done, hopefully. You can get either a window confirming everything went well or a window printing an error message if something went wrong. What can be wrong? There are some restrictions I decided to put on the service to prevent abuse. One of the restrictions is the maximum number of domains a user can register for himself which is 25 right now. Another restriction is that the domain which you add must have a valid DNS entry pointing to our service. The XMPP guide describes all the details about DNS settings. Please refer to these instructions if you need more details.

Adding a New User

Adding a new user process is quite similar, almost identical to adding a new domain. This time, however we have to select Session Manager in the service discovery window.

service disco window sm

Double click on the Session Manager and a window with SM’s commands list shows up. Right now, there is only one command available to domain administrators - Add user. I am going to make available more commands in the future and I am waiting for your suggestions.

command menu add user

If you click Execute a window presented on the left shows up. Fill all fields accordingly and press Finish.

add user window

If everything went well you have just added a new user and you should get a window confirming successful operation. If something went wrong, a window with an error message should show up. Possible errors may be you tried to add a user which is already present, or you may have tried to add a user for a domain to which you do not have permission or to non-existen domain.

11.6.3. SSL Certificate Management

SSL Certificate Management has been implemented, and certificates can be manipulated when in a .pem form. For more details, see Creating and Loading the Server Certificate in pem Files section of documentation for more information.

11.7. Presence Forwarding

Have you ever thought of displaying your users presence status on the website? Or, maybe, you wanted to integrate XMPP service with your own system and share not only users' accounts but also presence status?

Not only is it possible but also very simple. You have a new option in the domain control form.

Actually there are 2 new options:

  1. Presence forward address

  2. Message forward address - not fully implemented yet

Presence forward address can be any XMPP address. Usually you want it to be a bot address which can collect your users' presence information. Once this option is set to a valid XMPP address Tigase forwards user’s presence, every time the user changes his status. The presence is processed normally, of course, and distributed to all people from the contact list (roster), plus to this special address. It can be a component or a bot. If this is a bot connecting to a regular XMPP account, Make sure the presence forward address contains resource part and the bot is connecting with this resource. Otherwise the presence won’t be delivered to the bot.

vhost presence forward

As the screenshot shows, there are new input lines with option for presence forwarding address and message forwarding address. As you can see this option can be specified separately for each domain, so you can have a different forward address for each domain.

If you have your own Tigase installation, the forwarding address can be also set globally and can be the same for all domains. However, for this website, we offer this feature to all our users who have own domains and this can be set on per-domain basis.

Now, the big question. How this can be used? I am attaching below an example code. With just a few lines of code you can connect a command line bot to the server as a client which would collect all presences from users. Code below is a simple Groovy script which receives presence packet and displays them on the console. However, it should be easy enough to store users' presence information in a database and then load it from a web application.

The bot/client uses our JaXMPP2 library which is included in current builds of Tigase XMPP Server.

You should be able to find a few more code examples on the wiki page.

package jaxmppexample

import tigase.jaxmpp.core.client.BareJID
import tigase.jaxmpp.core.client.SessionObject
import tigase.jaxmpp.core.client.exceptions.JaxmppException
import tigase.jaxmpp.core.client.observer.Listener
import tigase.jaxmpp.core.client.xmpp.modules.presence.PresenceModule
import tigase.jaxmpp.core.client.xmpp.modules.presence.PresenceModule.PresenceEvent
import tigase.jaxmpp.j2se.Jaxmpp

final Jaxmpp jaxmpp = new Jaxmpp()
jaxmpp.getProperties().setUserProperty( SessionObject.USER_BARE_JID,
  BareJID.bareJIDInstance( "test4@test.tigase.org" ) )
jaxmpp.getProperties().setUserProperty(SessionObject.RESOURCE, "presence-collector")
jaxmpp.getProperties().setUserProperty( SessionObject.PASSWORD, "pass" )
jaxmpp.getModulesManager().getModule( PresenceModule.class ).addListener(
  PresenceModule.ContactChangedPresence,  new Listener() {
    public void handleEvent( PresenceEvent be ) {
      def msg = (be.getStatus() != null) ? be.getStatus() : "none"
      println( "Presence received:\t" + be.getJid() + " is now " + be.getShow() +
        " (" + msg + ")" )
    }
  }
)
println( "Loging in..." )
jaxmpp.login()
println( "Waiting for the presence for 10 minutes" )
Thread.sleep( 10 * 60 * 1000 )
disconnect()

11.8. Watchdog

Tigase’s Watchdog was implemented to help Tigase close connections that have become stale or inactive. Sometimes the connection is delayed, maybe dropped packets, or a service interruption. After a time, if that connection is re-established, both server and client (or server and server) will continue on as if nothing happened. However, these gaps in connection can last longer, and some installations will rely on the operating system to detect and close stale connections. Some operating systems or environments can take up to 2 hours or more to determine whether a connection is bad and wait for a response from a foreign entity and may not be configured. This can not only slow down performance, but can lead to security issues as well. To solve this problem, we have introduced Watchdog to monitor connections independent of operating system and environments to keep those broken connections from becoming a problem.

11.8.1. Setup

No extra setup is necessary, Watchdog is already included with your build of Tigase (as long as it’s 7.1.0 or newer). Follow the steps in the configuration section.

11.8.2. Watchdog Configuration

To configure watchdog, the following lines need to be present or edited in config.tdsl file:

'watchdog-timeout' = 70000
'watchdog-delay' = 60000
'watchdog-ping-type' = 'xmpp'

The three settings are as follows:

  • 'watchdog-timeout'= 70000 This setting sets the amount of time that watchdog will consider before it determines a connection may be stale. This setting sets the timeout at 70000ms or 70 seconds.

  • 'watchdog-delay' = 60000 This setting sets how often the watchdog should conduct the check, the default delay at 60000ms or 60 seconds.

  • 'watchdog-ping-type' This setting determines the type of ping sent to components when watchdog is testing for activity.

You may, if you choose, to specify individual watchdog settings for specific components by adding them to the component settings, for example if we wanted to change the Client2Server settings to include watchdog, use the following lines in config.tdsl:

c2s {
    watchdog-delay = '1500'
    watchdog-timeout = '3000'
}

If any settings are not set, the global or settings will be used. watchdog-delay default is set to 10 min watchdog-ping-type default is set to XMPP

11.8.3. Logic

Watchdog compares it’s own pings, and records the time it takes for a round trip to different components, clustered connections, and if one variable is larger than the other, watchdog will commence closing that stale connection. Here is a breakdown:

  1. A check is performed of a connection(s) on every watchdog-delay interval.

  2. During this check two things occur

    • If the last transfer time exceeds max-inactivity-time a stop service command is given to terminate and broadcast unavailable presence.

    • If the last transfer time is lower than max-inactivity-time but exceeds watchdog-timeout watchdog will try to send a ping (of watchdog-ping-type). This ping may be one of two varieties (set in config.tdsl)

      • WHITESPACE ping which will yield the time of the last data transfer in any direction.

      • XMPP ping which will yield the time of the last received xmpp stanza.

  3. If the 2nd option is true, the connection will remain open, and another check will begin after the watchdog-delay time has expired.

For example, lets draw this out and get a visual representation

-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-- (1)
     |     |     |     |     |     |     |     |     |     |     |
---+---------------------------------------------------------------- (2)
   1 2     3     4     5     6
---*-*-----*-----*-----*----------- (3)
  1. This line represents how often the check is performed. Each - (dash) is 10 seconds, so the check is done every 60 seconds ('watchdog-delay' = 60000)

  2. This line is client activity, here the client sent a message at 40 seconds (marked by +) and has gone idle.

  3. The following line represents the watchdog logic, with timeout at 120 seconds and max inactivity timeout at 180 seconds:

    'watchdog-timeout' = 120000
    c2s {
        'max-inactivity-time' = '180000'
    }
    (timeout at 120 seconds and max inactivity timeout at 180 seconds)

How the check is performed:

  1. 30 seconds - at this point last transfer or last received time is updated.

  2. 60 seconds - watchdog runs - it check the connection and says: _ok, last client transfer was 20s ago - but it’s lower than both inactivity (so don’t disconnect) and timeout (so don’t send ping).

  3. 120 seconds - 2nd check - last transfer was 100s ago - still lower than both values - do nothing.

  4. 180 seconds - 3rd check - last transfer was 160s ago - lower than inactivity but greater than delay - ping it sent.

  5. 240 seconds - 4th check - last transfer was 220s ago - client still hasn’t responded, watchdog compares idle time to max-inactivity-timeout and finds out that it is greater, connection is terminated.

  6. 300 seconds - watchdog is run again but given the connection was terminatet there is no XMPP session to check for that particular client.

Tip
It is possible that the connection is broken, and could be detected during the sending of a ping and the connection would be severed at step 4 instead of waiting for step 5. NOTE This MAY cause JVM to throw an exception.
Note

Global settings may not be ideal for every setup. Since each component has its own settings for max-inactivity-time you may find it necessary to design custom watchdog settings, or edit the inactivity times to better suit your needs. Below is a short list of components with thier default settings:

bosh {
    'max-inactivity-time' = 600L
}
c2s {
    'max-inactivity-time' = 86400L
}
'cl-comp' {
    'max-inactivity-time' = 180L
}
s2s {
    'max-inactivity-time' = 900L
}
ws2s {
    'max-inactivity-time' = 86400L
}
Important
Again remember, for Watchdog to properly work, the max-inactivity-time MUST be longer than the watchdog-timeout setting

11.8.4. Testing

The tigase.log.0 file can reveal some information about watchdog and how it is working (or how it might be fighting your settings). To do so, enter the following line into your config.tdsl file:

debug = [ 'server', 'xmpp.init' ]

This will set debug mode for your log, and enable some more information about what Tigase is doing. These logs are truncated for simplicity. Lets look at the above scenario in terms of the logs:

Stage Two
2015-10-16 08:00:00.000 [Watchdog - c2s]   ConnectionManager$Watchdog$1.check()  FINEST: Testing service: c2s@xmpp.domain.com/192.168.0.150_5222_192.168.0.201_50368, type: accept, Socket: TLS: c2s@xmpp.domain.com/192.168.0.150_5222_192.168.0.201_50368 Socket[addr=/192.168.0.201,port=50368,localport=5222], jid: user@xmpp.domain.org/mobile, sinceLastTransfer: 20,000, maxInactivityTime: 180,000, watchdogTimeout: 120,000, watchdogDelay: 60,000, watchdogPingType: XMPP
Stage Three
2015-10-16 08:01:00.000 [Watchdog - c2s]   ConnectionManager$Watchdog$1.check()  FINEST: Testing service: c2s@xmpp.domain.com/192.168.0.150_5222_192.168.0.201_50368, type: accept, Socket: TLS: c2s@xmpp.domain.com/192.168.0.150_5222_192.168.0.201_50368 Socket[addr=/192.168.0.201,port=50368,localport=5222], jid: user@xmpp.domain.org/mobile, sinceLastTransfer: 100,000, maxInactivityTime: 180,000, watchdogTimeout: 120,000, watchdogDelay: 60,000, watchdogPingType: XMPP
Stage Four
2015-10-16 08:02:00.000 [Watchdog - c2s]   ConnectionManager$Watchdog$1.check()  FINEST: Testing service: c2s@xmpp.domain.com/192.168.0.150_5222_192.168.0.201_50368, type: accept, Socket: TLS: c2s@xmpp.domain.com/192.168.0.150_5222_192.168.0.201_50368 Socket[addr=/192.168.0.201,port=50368,localport=5222], jid: user@xmpp.domain.org/mobile, sinceLastTransfer: 160,000, maxInactivityTime: 180,000, watchdogTimeout: 120,000, watchdogDelay: 60,000, watchdogPingType: XMPP
2015-10-16 08:02:00.697 [Watchdog - c2s]   ConnectionManager$Watchdog$1.check()  FINEST: c2s@xmpp.domain.com/192.168.0.150_5222_192.168.0.201_50368, type: accept, Socket: TLS: c2s@xmpp.domain.com/192.168.0.150_5222_192.168.0.201_50368 Socket[addr=/192.168.0.201,port=50368,localport=5222], jid: user@xmpp.domain.org/mobile, sending XMPP ping from=null, to=null, DATA=<iq from="xmpp.domain.com" id="tigase-ping" to="user@xmpp.domain.com/mobile" type="get"><ping xmlns="urn:xmpp:ping"/></iq>, SIZE=134, XMLNS=null, PRIORITY=NORMAL, PERMISSION=NONE, TYPE=get
Stage Five
2015-10-16 08:03:00.000 [Watchdog - c2s]   ConnectionManager$Watchdog$1.check()  FINEST: Testing service: c2s@xmpp.domain.com/192.168.0.150_5222_192.168.0.201_50368, type: accept, Socket: TLS: c2s@xmpp.domain.com/192.168.0.150_5222_192.168.0.201_50368 Socket[addr=/192.168.0.201,port=50368,localport=5222], jid: user@xmpp.domain.org/mobile, sinceLastTransfer: 100,000, maxInactivityTime: 180,000, watchdogTimeout: 120,000, watchdogDelay: 60,000, watchdogPingType: XMPP
2015-10-16 08:03:00.248 [pool-20-thread-6]  ConnectionManager.serviceStopped()  FINER:  [[c2s]] Connection stopped: c2s@xmpp./domain.com/192.168.0.150_5222_192.168.0.201_50368, type: accept, Socket: TLS: c2s@lenovo-z585/192.168.0.150_5222_192.168.0.201_50368 Socket[unconnected], jid: user@xmpp.domain.com
2015-10-16 08:03:00.248 [pool-20-thread-6]  ClientConnectionManager.xmppStreamClosed()  FINER: Stream closed: c2s@xmpp.domain.com/192.168.0.150_5222_192.168.0.201_50368

11.9. Tips and Tricks

The section contains some short tricks and tips helping in different kinds of issues related to the server administration and maintenance.

11.9.1. Tigase Tip: Checking the Runtime Environment

It has happened recently that we have tried very hard to fix a few annoying problems on one of the Tigase installations. Whatever we did, the problem still existed after uploading a new version and restarting the server. It worked fine in our development environment and it just didn’t on the target system.

It turned out that due to specific environment settings on the target system, an old version of Tigase server was always started regardless of what updates uploaded. We finally located the problem by noticing that the logs were not being generated in the proper locations. This led us to finding the issue: improper environment settings.

The best way to check all the environment settings used to start the Tigase server is to use… check command line parameter:

$ ./scripts/tigase.sh check etc/tigase.conf

Checking arguments to Tigase
TIGASE_HOME = .
TIGASE_JAR = jars/tigase-server.jar
TIGASE_PARAMS = etc/tigase.conf
TIGASE_CONFIG = etc/tigase.xml
TIGASE_RUN = tigase.server.XMPPServer -c etc/tigase.xml --property-file etc/init.properties
TIGASE_PID = ./logs/tigase.pid
TIGASE_OPTIONS = --property-file etc/init.properties
JAVA_OPTIONS = -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 \
    -Djdbc.drivers=com.mysql.jdbc.Driver:org.postgresql.Driver \
    -server -Xms100M -Xmx200M -XX:PermSize=32m -XX:MaxPermSize=256m
JAVA = /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/bin/java
JAVA_CMD =
CLASSPATH = ./jars/tigase-server.jar:./libs/jdbc-mysql.jar:./libs/jdbc-postgresql.jar:\
    ./libs/tigase-extras.jar:./libs/tigase-muc.jar:./libs/tigase-pubsub.jar:\
    ./libs/tigase-utils.jar:./libs/tigase-xmltools.jar
TIGASE_CMD = /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/bin/java \
    -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 \
    -Djdbc.drivers=com.mysql.jdbc.Driver:org.postgresql.Driver \
    -server -Xms100M -Xmx200M -XX:PermSize=32m -XX:MaxPermSize=256m \
    -cp ./jars/tigase-server.jar:./libs/jdbc-mysql.jar:./libs/jdbc-postgresql.jar:\
    ./libs/tigase-extras.jar:./libs/tigase-muc.jar:./libs/tigase-pubsub.jar:\
    ./libs/tigase-utils.jar:./libs/tigase-xmltools.jar tigase.server.XMPPServer \
    -c etc/tigase.xml --property-file etc/init.properties
TIGASE_CONSOLE_LOG = ./logs/tigase-console.log

In our case TIGASE_HOME was set to a fixed location pointing to an old version of the server files. The quick check command may be a real time saver.

Best Practices for Connecting to Tigase XMPP server From Web Browser

Currently we have 2 ways to connect to Tigase XMPP Server from web browsers:

  1. BOSH (Bidirectional-streams Over Synchronous HTTP)

  2. WebSocket (XMPP over WebSocket)

You will find more information about these ways for connecting to Tigase XMPP Server with some useful tips below.

BOSH

BOSH protocol specified in XEP-0124 is one of first protocols defined to allow to establish XMPP connection to XMPP servers from web browsers due to this protocol being widely supported and used. It is also easy to use in single server mode. It’s enabled by default in Tigase XMPP Server and available at port 5280.

In clustered mode we can deploy it with load balancer deployed with guarantees that each BOSH connection from web browser will be forwarded to same Tigase XMPP Server instance. So in clustered mode if we have two XMPP server t1 and t2 which are hosting domain example.com we would need to have load balancer which will respond for HTTP request to domain example.com and forward all requests from same IP address to same node of a cluster (i.e. all request from 192.168.122.32 should be forwarded always to node t1.

Tip #1 - BOSH in Cluster Mode Without Load Balancer

There is also a way to use BOSH without load balancer enabled. In this case the XMPP client needs to have more logic and knowledge about all available cluster nodes (with names of nodes which will identify particular cluster nodes from internet). Using this knowledge XMPP client should select one random node from list of available nodes and always establish BOSH connections to this particular node. In case if BOSH connection fails due to network connection issues, the XMPP client should randomly pick other node from list of rest of available nodes.

Solution:

Tigase XMPP Server by default provides server side solution for this issue by sending additional host attribute in body element of BOSH response. As value of this attribute Tigase XMPP Server sends domain name of server cluster node to which client connected and to which next connections of this session should be opened. It is possible to disable this custom feature by addition of of following line to etc/config.tdsl config file:

bosh {
    'send-node-hostname' = false
}

Example:

We have servers t1.example.com and t2.example.com which are nodes of a cluster hosting domain example.com. Web client retrieves list of cluster nodes from web server and then when it needs to connect to the XMPP server it picks random host from list of retrieved cluster nodes (i.e. t2.example.com) and tries to connect using BOSH protocol to host t2.example.com but it should send example.com as name of the server it tries to connect to (example.com should be value of to attribute of XMPP stream).

WebSocket

WebSocket protocol is newly standardized protocol which is supported by many of current versions of browsers. Currently there is a draft of protocol draft-ietf-xmpp-websocket-00 which describes usage of WebSocket to connect to XMPP servers. Tigase XMPP Server implementation of WebSocket protocol to connect to XMPP server is very close to this draft of this specification. By default Tigase XMPP Server has XMPP-over-WebSocket protocol enabled without encryption on port 5290. To use this protocol you need to use library which supports XMPP-over-WebSocket protocol.

Tip #1 - Encrypted WebSocket Connection

It is possible to enable encrypted WebSocket connection in Tigase XMPP Server. To do this you need to add following lines to etc/config.tdsl config file:

ws2s {
    connections {
        ports = [ 5290, 5291 ]
        5290 {
            socket = 'ssl'
            type = 'accept'
        }
        5291 {
            socket = 'plain'
            type = 'accept'
        }
    }
}

In this example we enabled WebSocket endpoint on port 5290 allowing unencrypted connections, and encrypted WebSocket endpoint on port 5291. As this is TLS/SSL connection (no STARTTLS) it uses default certificate installed in Tigase XMPP Server instance. This certificate is located in certs/default.pem.

Note
There is no default configuration for non-default ports. All ports outside 443 MUST be configured.
Tip #2 - Encrypted WebSocket Connection - Dealing With Multiple VHosts

As mentioned in Tip #1 WebSocket endpoint is plain TLS/SSL port, so it always serves default certificate for Tigase XMPP Server instance. That is ok if we are hosting single domain and if default certificate matches matches our domain. But If we host multiple domain we cannot use wss://example1.com:5291/ connection URL, if our default certificate is for domain example2.com. In this situation it is recommended to use the default certificate for the domain under which the server is accessible from the internet. This domain should identify this server, so this domain would not point to two nodes of a cluster. After we deploy separate certificate for each of cluster nodes, we should follow same tip as Tip #1 for BOSH. Our web-based XMPP client should have knowledge about each node of a cluster and when it needs to connect it should randomly select one node from list of available cluster nodes and try to connect using connection URL that would contain name of server under which it can be identified from internet.

Example:

We have servers t1.example1.com and t2.example1.com which are nodes of a cluster in hosting domain example2.com. Each of our nodes contains default SSL certificate with domain names matching the cluster node. Web client retrieves list of cluster nodes from web server and then when it needs to connect to XMPP server it picks random host from list of retrieved cluster nodes (i.e. t2.example1.com) and tries to connect using WebSocket encrypted protocol to host t2.example1.com using the following URL: wss://t2.example1.com:5291/. Upon connection the client should still send example2.com as name of server to which it tries to connect (example2.com should be value of to attribute of XMPP stream). This will allow browser to validate certificate as it will be for the same domain to which browser connects, and it will allow XMPP client to connect to domain example2.com, which is one of hosted vhosts.

11.10. Licensing

With the release of v7.1.0, users and commercial clients alike may now be able to register and request a license file from our servers on their own. This process makes it easier for everyone to obtain valid license file when needed. Users who do not wish to register will not be required to register. However, If you are using Tigase ACS or other commercial pieces of software, you will be required to register.

Warning
Tigase XMPP Server will shut down during license check if no installation-id or license is received within a given period of time.

Again, Tigase XMPP Server will still be available free under AGPLv3, and free users will not need to register.

Note
COMMERCIAL COMPONENTS REQUIRE THE USE OF A LICENSE.

11.10.1. Registering for a License

There are currently two ways for registering for a license with Tigase commercial products. The easiest and recommended method is using the built in automatic registration function. However, you may also register via a web portal if your installation has limitations on network connectivity.

Once a commercial component is activated on Tigase XMPP Server, the program will then retrieve an Installation ID from our servers, and make a file called installation-id in your etc/ directory including the Installation ID for your instance. An installation ID is generated using the complete cluster map and all machines within the same cluster should have the same Installation ID. This Installation ID will then be sent along with server details to a license server, and appropriate license files will be made in your tigasedir/etc directory. When the license is due to be expired, this mechanism will update your license file automatically.

Manual
Caution
This method should be used only in extreme cases when [AutomaticLicenceRegistration] can’t be used.

If you do not wish to use the automatic method, you may decide to generate a license file using our web portal. Offline installation may obtain Installation IDs from our web portal in a three-step process: registration, generating hash, and obtaining license file.

Generating Installation ID

For offline installations, you may obtain an Installation ID from this address: https://license.tigase.software/register.

Data Fields:

  • Customer name: Company or user name used to identify machines. Multiple clusters or servers can have the same customer name.

  • VHosts: Comma separated list of VHosts you will be using on this node. NOTE: these fields are case sensitive!

  • Legacy license hashes: Copy the digest hash generated for all legacy licenses - it’s available in the etc/tigase-console.log after startup (if such licenses are present).

  • Captcha question: Enter the basic math answer for this form to prove you are not a robot.

The next page will provide you with an installation ID like the following:

1TCICGG7K8AS2JSSEVMDA9QOLR4NVLJSR

Edit your config.tdsl file and add your installation-id

'installation-id' = '1TCICGG7K8AS2JSSEVMDA9QOLR4NVLJSR'

Note that the installation-id file will be made automatically once the license file is installed and verified by the server.

Obtaining a Server Code

Once you have the Installation ID, you will need to generate a server code. This can be done by accessing the admin UI page and navigating to the License section. Once there, click on Retrieve code for license. Select the component you wish to generate a code for and click Submit. You will see a fields with installation-id, module, VHosts filled out based on your server’s configuration. Copy the contents of the Code field and proceed to the next section.

Obtaining license file

Open a new browser and navigate to this address: https://license.tigase.software/retrieve once there, paste the generated code from the last step in the field and click submit. Afterwards you will be prompted to download a license file, place this file in your etc/ folder and restart your server, your license is now activated and installed on your server.

If you are provided a manually produced license, you will need to place it in the same etc/ directory with the name <component_name>.license (e.g.: etc/acs.license)

11.10.2. What happens if I do not use a license file or it is expired?

Tigase permits commercial products to be used without a license, but a validation process must complete otherwise the server will shutdown. Within the first hour of runtime, Tigase will check for the presence and validity of the license file. If none is found, or it is invalid or expired the server will then contact Tigase master server in order to obtain a valid one.

Communications will be made to license.tigase.software over https (port 443) to verify the license or download a new one.

11.10.3. Demo mode

If no valid license can be found, Tigase will revert to a demonstration mode. Most functions will be available and usable, but with a caveat. Statistics from that server will be sent to https://stats.tigase.software about your server and it’s usage. Details are in the next section. If this information cannot be sent, the server will assume unauthorized use and will shut down.

Statistics Sent

Statistics of your server may be sent to Tigase server’s if the all of following happens:

  • You are using commercial Tigase components.

  • You have registered an installation-id.

  • You do not have a current license to run Tigase commercial components.

If these conditions exist, statistics will be sent to our servers and a warning will be posted in your logs. The following is an example of what information will be sent.

Note
The text below has been better formatted for readability, but does not reflect the actual text being sent to Tigase.
<statistics version="1">
    <domain>xmppserver</domain>
    <timestamp>2016-06-23T17:16:24.777-0700</timestamp>
    <vhosts>
        <item>vhost1.xmppserver.com</item>
    </vhosts>
    <uptime>308833</uptime>
    <heap>
        <used>30924376</used>
        <max>1426063360</max>
    </heap>
    <cluster>
        <nodes_count>1</nodes_count>
    </cluster>
    <users>
        <online>0</online>
        <active>0</active>
        <max_today>1</max_today>
        <max_yesterday>0</max_yesterday>
    </users>
    <additional_data>
        <components>
            <cmpInfo>
                <name>amp</name>
                <title>Tigase XMPP Server</title>
                <version>7.1.0-SNAPSHOT-b4226/5e7210f6 (2016-06-01/23:15:52)</version>
                <class>tigase.cluster.AmpComponentClustered</class>
            </cmpInfo>

            <cmpInfo>
                <name>bosh</name>
                <title>Tigase XMPP Server</title>
                <version>7.1.0-SNAPSHOT-b4226/5e7210f6 (2016-06-01/23:15:52)</version>
                <class>tigase.cluster.BoshConnectionClustered</class>
            </cmpInfo>

            <cmpInfo>
                <name>c2s</name>
                <title>Tigase XMPP Server</title>
                <version>7.1.0-SNAPSHOT-b4226/5e7210f6 (2016-06-01/23:15:52)</version>
                <class>tigase.cluster.ClientConnectionClustered</class>
            </cmpInfo>

            <cmpInfo>
                <name>cl-comp</name>
                <title>Tigase XMPP Server</title>
                <version>7.1.0-SNAPSHOT-b4226/5e7210f6 (2016-06-01/23:15:52)</version>
                <class>tigase.cluster.ClusterConnectionManager</class>
            </cmpInfo>

            <cmpInfo>
                <name>eventbus</name>
                <title>Tigase XMPP Server</title>
                <version>7.1.0-SNAPSHOT-b4226/5e7210f6 (2016-06-01/23:15:52)</version>
                <class>tigase.disteventbus.component.EventBusComponent</class>
            </cmpInfo>

            <cmpInfo>
                <name>http</name>
                <title>Tigase HTTP API component: Tigase HTTP API component</title>
                <version>1.2.0-SNAPSHOT-b135/27310f9b-7.1.0-SNAPSHOT-b4226/5e7210f6 (2016-06-01/23:15:52)</version>
                <class>tigase.http.HttpMessageReceiver</class>
            </cmpInfo>

            <cmpInfo>
                <name>monitor</name>
                <title>Tigase XMPP Server</title>
                <version>7.1.0-SNAPSHOT-b4226/5e7210f6 (2016-06-01/23:15:52)</version>
                <class>tigase.monitor.MonitorComponent</class>
            </cmpInfo>

            <cmpInfo>
                <name>muc</name>
                <title>Tigase ACS - MUC Component</title>
                <version>1.2.0-SNAPSHOT-b62/74afbb91-2.4.0-SNAPSHOT-b425/d2e26014</version>
                <class>tigase.muc.cluster.MUCComponentClustered</class>
                <cmpData>
                    <MUCClusteringStrategy>class tigase.muc.cluster.ShardingStrategy</MUCClusteringStrategy>
                </cmpData>
            </cmpInfo>

            <cmpInfo>
                <name>pubsub</name>
                <title>Tigase ACS - PubSub Component</title>
                <version>1.2.0-SNAPSHOT-b65/1c802a4c-3.2.0-SNAPSHOT-b524/892f867f</version>
                <class>tigase.pubsub.cluster.PubSubComponentClustered</class>
                <cmpData>
                    <PubSubClusteringStrategy>class tigase.pubsub.cluster.PartitionedStrategy</PubSubClusteringStrategy>
                </cmpData>
            </cmpInfo>

            <cmpInfo>
                <name>s2s</name>
                <title>Tigase XMPP Server</title>
                <version>7.1.0-SNAPSHOT-b4226/5e7210f6 (2016-06-01/23:15:52)</version>
                <class>tigase.server.xmppserver.S2SConnectionManager</class>
            </cmpInfo>

            <cmpInfo>
                <name>sess-man</name>
                <title>Tigase XMPP Server</title>
                <version>7.1.0-SNAPSHOT-b4226/5e7210f6 (2016-06-01/23:15:52)</version>
                <class>tigase.cluster.SessionManagerClustered</class>
                <cmpData>
                    <ClusteringStrategy>class tigase.server.cluster.strategy.OnlineUsersCachingStrategy
                    </ClusteringStrategy>
                </cmpData>
            </cmpInfo>

            <cmpInfo>
                <name>ws2s</name>
                <title>Tigase XMPP Server</title>
                <version>7.1.0-SNAPSHOT-b4226/5e7210f6 (2016-06-01/23:15:52)</version>
                <class>tigase.cluster.WebSocketClientConnectionClustered</class>
            </cmpInfo>

            <cmpInfo>
                <name>vhost-man</name>
                <title>Tigase XMPP Server</title>
                <version>7.1.0-SNAPSHOT-b4226/5e7210f6 (2016-06-01/23:15:52)</version>
                <class>tigase.vhosts.VHostManager</class>
            </cmpInfo>

            <cmpInfo>
                <name>stats</name>
                <title>Tigase XMPP Server</title>
                <version>7.1.0-SNAPSHOT-b4226/5e7210f6 (2016-06-01/23:15:52)</version>
                <class>tigase.stats.StatisticsCollector</class>
            </cmpInfo>

            <cmpInfo>
                <name>cluster-contr</name>
                <title>Tigase XMPP Server</title>
                <version>7.1.0-SNAPSHOT-b4226/5e7210f6 (2016-06-01/23:15:52)</version>
                <class>tigase.cluster.ClusterController</class>
            </cmpInfo>
        </components>

        <unlicencedComponenents>
            <ComponentAdditionalInfo name=&quot;acs&quot;/>
        </unlicencedComponenents>
    </additional_data>
</statistics>

11.10.4. Unauthorized use

Tigase will consider itself unauthorized if the following conditions are met:

  • if Tigase XMPP Server does not have a valid license file and

  • cannot contact the licensing server to obtain installation id and attached licenses.

Then the program will then attempt to send statistics.

  • if unable to sent statistics the server after a random number of retries.

  • if these retries are not successful within 10 attempts, the server will then shutdown.

If you are experiencing this condition, please contact Tigase.

11.10.5. Manual mode

If you cannot open communication to stats.tigase.software or license.tigase.software over the required ports (https over port 443), you may request to use manual mode. Manual mode requires Tigase to create a license file to be used on your machine locally. This must be placed in the same folder as the above information, and the license check system will not seek communication unless the license is invalid or expired.

11.11. Tigase Clustering

Tigase Clustering allows the use of a number of servers to be unified in delivering, from what a client or user sees, a single unified platform. There are two typical reasons why clustering should be employed:

  • High Availability

    By using clustering, services can be provided with a high reliability and redundancy. By using a network of multiple servers, content or services can be served on any of the clustered servers maintaining a consistent uptime without relying on one machine.
  • Load Balancing

    This type of cluster helps to distribute a workload over a number of servers to reduce bottlenecking from heavy resource loads on a particular server.

With Tigase, you don’t have to choose between either/or!

Tigase Clustering offers Full Redundancy and Automatic Load Balancing allowing addition of new nodes at runtime with a simple configuration. All without a severe tax on resource consumption.

All basic components support clustering configuration, and some may be turned on or off.

11.11.1. Configuration

To enable Clustering on Tigase servers, use the following line in your config.tdsl file:

'cluster-mode' = true

That’s it!

Custom Ports

You can customize ports for the cluster component, just be sure that each clustered server also has the same settings so they can communicate.

cl-comp {
    connections {
        4250 {}
        3540 {}
    }
}

You can fine tune each port configuration, however this is not typically needed.

Custom Port Configuration

Each port has it’s own details that can be manipulated via the following ports. Again THIS IS OPTIONAL

'cl-comp' {
    connections {
        4250 {
            ifc = [ '*' ]
            'remote-host' = 'localhost'
            socket = 'plain'
            type = 'accept'
            connections {
                tls {
                    required = false
                }
            }
        }
    }
}
Multi-node configuration

Each node should have 'cluster-mode' = true enabled that you wish to connect to the cluster. They will automatically discover other nodes to connect to VIA Server to Server traffic. Nodes that are added or removed will be periodically updated.

Traffic Control

You can customize the traffic going between clustered servers with a few options.

cm-ht-traffic-throttling

This setting will control the number of bytes sent over non-user connections. Namely, Server to Server or S2S connections.

'cm-ht-traffic-throttling' = 'xmpp:25k:0:disc,bin:200m:0:disc'

The format is as follows: {traffic-type}:{maximum-traffic}:{max-lifespan-traffic}:{action}

traffic-type

Specifies the type of traffic controlled. This can either be XMPP or bin. XMPP limits the number of packets transferred, whereas bin limits the number of bytes transferred.

maximum-traffic

Specifies how many bytes or packets may be sent within one minute.

max-lifespan-traffic

Specifies how many bytes or packets may be sent within the lifetime of the connection. 0 means unlimited.

action

Specifies the action to be taken which can be disc which disconnects the connection, or drop which will drop any data exceeding the thresholds.

cm-see-other-host

This allows the specific use of a load balancing mechanism by selecting SeeOtherHostIfc implementation. For more details, see Tigase Load Balancing documentation.

11.11.2. Old configuration method

While these options are still available these settings CAN be less reliable. Use ONLY if you need specific setups that cannot be accommodated by the automatic cluster mode.

Specifying Specific nodes

You can still use the old method of specifying every node on each server. Server 3 needs the following set

'cluster-nodes' = [ 'serv1.xmpp-test.org' , 'serv2.xmpp-test.org' ]

Server 2 needs

'cluster-nodes' = [ 'serv1.xmpp-test.org' , 'serv3.xmpp-test.org' ]

and so on…​

However, we do not recommend this.

Password and Port configuration

You may specify a password and port to specific cluster servers if that is required. To do so, you will need to add {password}:{port} to the domain, like this example:

'cluster-nodes' = [ 'serv1.xmpp-test.org:domainpass:5600' ]

11.11.3. Checking Cluster Connections

After setting up clustering you may want to verify that the clusters are operational. Right now it can be done in two manners - first by checking that there are actual network connections established between cluster nodes. The other is to check internal status of the server.

Established connections

There are number of ways to check for opened connections, simplest one use command line. (Tigase uses port 5277 for cluster connections)

  • Linux

    $ lsof -iTCP:5277 -sTCP:ESTABLISHED -P -n
  • Windows

    C:\WINNT>netstat -anp tcp | find ":5277 "
Cluster nodes connected (using XMPP)

Verifying clustering connectivity over XMPP protocol requires any XMPP client capable of XEP-0030: Service Discovery. It’s essential to remember that only an administrator (a user whose JID is configured as administrative) has access.

Psi XMPP Client

For the purpose of this guide a 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 Cluster Connection Manager component. After expanding the tree node for the component a list of all cluster nodes will be presented with the current status (either connected or disconnected). Node column will contain actual hostname of the cluster node:

discovery-nodes

11.12. Anonymous Users & Authentication

To support anonymous users, you must first enable anonymous authentication on your server.

11.12.1. Anonymous Authentication

Tigase Server can support anonymous logins via SASL-ANONYMOUS in certain scenarios. This can be enabled on per-VHost basis by adjusting Anonymous enabled option as described in Add and Manage Domains (VHosts) This setting is false by default as SASL-ANONYMOUS may not be totally secure as users can connect without prior permission (username and password).

11.12.2. Anonymous User Features

To connect to your server anonymously, you must use a client that supports anonymous authentication and users. Connect to the server with the name of the server as the username, and no password. For example, to connect anonymously to xmpp.example.com use the following credentials,

Username: xmpp.example.com Password:

In this mode all login information is stored in memory, and cannot be retrieved at a later date.

Other features of Anonymous Authentication

  • Temporary Jid is assigned and destroyed the moment of login/logout.

  • Anonymous users cannot access the database

  • Anonymous users cannot communicate outside the server (use s2s connections)

  • Anonymous users have a default limit on traffic generated per user.

Reconnection on Anonymous

On products such as our JaXMPP Server, users connected using SASL-ANONYMOUS can reconnect to existing sessions using cookie management. However, reconnection can be improved and extended using Bosh Session Cache which allows for session storage in memory rather than using client-side data for reconnection.

11.13. Scripting support in Tigase

Tigase server supports scripting languages in versions 4.3.1 and higher. These pages describe this feature in details how to create new scripts, upload them to the server, and execute them. The guide also contains API description with code examples.

Note
Tigase server is known for it very low memory consumption and successfully runs with less then 10MB of RAM memory. However adding scripting support for any non-standard (default) language to Tigase server significantly increases memory requirements for the installation. You cannot expect Tigase server to run on 10MB RAM system if you enabled Python, Scala or any other non-standard language.

11.13.1. Scripting Introduction - Hello World!

This document is the first in a series describing scripting support in the Tigase server showing how to load, install, update and call a script. It contains also an introduction to the scripting API with the first Hello world! example.

Since Tigase version 4.3.1 the server supports scripting for administrator commands as well as standard commands.

In theory many different languages can be used to write scripts and the only requirement is that support JSR-223 for the language is installed. More details can be found on the Java scripting project site.

In practice some languages are better supported than others, at the moment we recommend Groovy. However the following languages are also confirmed to be working: Scala, Python and Ruby. The Tigase SVN contains a few examples for these languages.

Note
the default Tigase installation contains only libraries for Groovy. Adding support for a different language is as simple as copying a few JAR files to the Tigase libs/ directory.

All the examples presented in this guide are also available as ready to use scripts in the Tigase SVN repository in directory: src/main/groovy/tigase/admin.

The scripting utilizes only standard XMPP extensions and is by no means specific to any particular solution. We use and prefer Psi client. The whole guide and all the screen-shots are created using Psi client. You can, however, use any other client which supports these extensions as well. As the whole thing is based on the service discovery and ad-hoc commands you need a XMPP client with a good support for both features.

To follow the guide and run all the examples you need will need to have installed Tigase server version 4.3.1 or newer and you have to connect to the server as administrator.

Loading Script at Run Time

All the scripting stuff is usually based on the service discovery and ad-hoc commands in the Tigase server.

service disco

The first thing to do, therefore, is to browse service discovery on the running server. The result you receive will depend on your installation and installed components.

The most interesting things right now are all items with "http://jabber.org/protocol/admin" in their node part. You may have a few scripts loaded already but there are two commands used for scripting management. Their names are descriptive enough: New command script and Remove command script.

The first is for adding a new script or updating existing and the second is for removing script from the server.

To add a new script you have just to execute New command script. In Psi this is done by double clicking on the element in service discovery list.

hello1 new script

The screenshot above shows a couple of options to set for the loaded script:

Description

is what shows as the script name in the service discovery window. There are no special restrictions on what to put there.

Command id

is a unique ID of the script (admin command). This is what shows after the "http://jabber.org/protocol/admin" in node part. This needs to be unique or existing script is overwritten.

Language

a drop down list of all supported scripting languages for your installation. Tigase automatically detects all libraries for scripting languages and lists them here. So all you need is to select the correct language for your script.

Script text

is just your script content.

When your script is ready and all fields are correctly set, simply press "Finish" button and you should receive a message confirming that the script has been loaded successfully.

loaded ok small

In this guide we are creating a simple "Hello world" script written in Groovy. What it does is displays a window (ad-hoc command result) with a message: "Hello admin, how are you?".

It uses a basic scripting API which is described line by line below:

  1. It imports basic Tigase classes.

  2. Sets a local variable p which points to a packet variable with data received from the client.

  3. Creates a res variable which is response sent back to the client (administrator). The response to the client is of type result. Other possible types will be introduced later.

  4. We operate on ad-hoc commands here so the script uses Tigase utility class to set/retrieve command parameters. It sets the window title and a simple message displayed to the user (administrator).

  5. The last line returns new packet as a script execution result.

The first, very simple version looks like this:

import tigase.server.*
def p = (Packet)packet
def res = p.commandResult(Command.DataType.result)
Command.addTitle(res, "Hello World Script")
Command.addInstructions(res, "Hello admin, how are you?")
return res
Executing Script

Once the script is successfully loaded you will have to reload/refresh the service discovery window which now should display one more element on the list.

service disco with new hello

As you can see script name is set to what you have entered as "Description" in script loading window - "Hello world script". The command node is set to: "http://jabber.org/protocol/admin#hello" if "hello" is what is set as the script ID.

To execute the script you just have to double click on the script name (or click execute command if you use any other client).

As a result you should see a simple window similar to the screenshot below displaying our message.

hello1 result small

Interaction in Scripts

Displaying just a message is very nice but is not very useful in most cases. Normally you need to ask the user for some more data or parameters before you can perform any real processing.

Therefore in most cases the administrator script has to display a new window with input fields asking the user for some more data. In this document we present very simple examples, just an introduction so let’s ask about the administrator name before displaying a greeting.

hello2 asking for name small

To ask the user for some more information we have to extend example above with some more code:

import tigase.server.*

def p = (Packet)packet

def name = Command.getFieldValue(packet, "name")

if (name == null) {
  def res = p.commandResult(Command.DataType.form);
  Command.addTitle(res, "Hello World Script")
  Command.addInstructions(res, "Please provide some details")
  Command.addFieldValue(res, "name", name ?: "", "text-single",
    "Your name")
  return res
}

def res = p.commandResult(Command.DataType.result)
Command.addTitle(res, "Hello World Script")
Command.addInstructions(res, "Hello ${name}, how are you?")

return res

If you compare both scripts you see that they are quite similar. Before displaying greeting, however, the script tries to retrieve data from the name input field. If the name had been provided the greeting is displayed, otherwise the script asks for the user name.

hello2 result small

Please note, in this case the packet sent back to the user is of type form instead of result. The practical difference is that the type result displays only OK button which when pressed doesn’t send any data to the server. The form packet displays more buttons - Finish and Cancel. Whichever you press some data is sent back to the server.

This script demonstrates use of two new methods from the utility class "Command": getFieldValue and addFieldValue.

  • The first argument to all Command methods is the packet with ad-hoc command.

  • The second argument is usually the input field name

These two method parameters are actually enough to read the ad-hoc command data. Methods creating input fields in the ad-hoc command need a few arguments more:

  • Next arguments sets a default value displayed to the user. The way to it is set in the example above is specific to Groovy language and is quite useful what will be apparent in later examples.

  • After that we have to specify the field type. All field types are defined in the XEP-0004 article.

  • The last argument specifies the field label which is displayed to the user.

hello2 new script

There are a few other different utility methods in the Command class to set different types of input fields and they will be described in details later on.

To reload the script simply call "New command script" again, enter the script text and make sure you entered exactly the same command ID to replace the old script with the new one.

Or of course, you can enter a new command id to create a new command and make it available on your server.

When the script is loaded on the server, try to execute it. You should get a new dialog window asking for your name as in the screenshot at the beginning of this section. When you have entered your name and clicked the "Finish" button you will see another window with a greeting message along with your name.

Automatic Scripts Loading at Startup Time

The last thing described in this guide is how to automatically load your scripts when the Tigase server starts. The ability to load scripts at run time, update and remove remove them is very useful, especially in emergency cases if something wrong is going on and you want to act without affecting the service.

If you, however have a few dozens scripts you don’t want to manually load them every time the server restarts.

Tigase server automatically loads all scripts at the startup time which are located in the admin scripts directory. Unless you set it differently in the configuration it is: YourTigaseInstallationDir/scripts/admin/. All you have to do is to copy all your scripts to this directory and they will be loaded next time the server starts.

But hold on. What about the script parameters: language, description, command id? How are you supposed to set them?

Language is simple. It is detected automatically by the script file extension. So just make sure file extensions are correct and the language is sorted.

The script description and command id needs a little bit more work. You have to include in your script following lines:

AS:Description: The command description
AS:CommandId: command-id
AS:Component: comp_name

Please note, there must be at least a single space after the AS:Description: or AS:CommandId: string. Everything rest after that, until the end of the line, is treated as either the script description or command id. Put these in your script file and the loader will detect them and set correctly for your script.

11.13.2. Tigase Scripting Version 4.4.x Update for Administrators

Scripting functionality is quite useful in Tigase server for all sorts of administrator tasks. The possibility to load new scripts or replace old ones at the server runtime opens quite new area for the service maintenance.

In earlier versions of the Tigase server scripting capabilities was available only in the session manager component while it might be very useful in many other places - connection managers, MUC, PubSub, VHostManager and what even more important in completely new, custom components created for specific needs. It would be quite wasteful to reinvent the wheel every time and implementing scripting capabilities for each component separately.

Therefore the scripting capabilities has been implemented in the core of the Tigase server. It is now part of the API and is automatically available to all components without any additional coding. A detailed developer guide will be published separately.

This document describes changes from the user/administrator perspective because there are some usability changes related to the new implementation.

Please note. The description and screenshots are taken from the Psi client and most likely interface for ad-hoc commands and service discovery on other client looks different. I recommend to do some initial testing and experiments using Psi client and then switch to your preferred application for your day-to-day use.

As it always was in the Tigase you can access all the functions via XMPP service discovery on the server. However, as soon as you connect to the server you can see some changes there.

new service disco admin

There are no command on the list. They are hidden from the main service discovery list. You can see on the list only the server main components.

This had to be done for many reasons. One of them is, obviously, the cleaner access to the main server stuff. Another, probably more important, is to avoid a long list of commands for different components mixed together. Commands for different components can have the same name/description and they can even do similar things but they are executed on a different server component. To avoid any confusion and minimize opportunities for mistake the commands are now closely tight to their components. To access a list of commands for a particular component you have to double click on the component name on the list or click 'Execute command" icon on top of the window when your component is selected.

A new window should show up with drop-down list of available commands. All the commands are related to the selected component and are executed kind of "inside the component environment". You can of course add new command or delete existing one and of course execute any of the commands showing on the list.

new command list

As a reminder, in the window title you can see the component ID and you should check it before running any command to make sure you accidentally don’t break your system.

new add command

There has been also a small change made to the script adding window. As you can see on the screenshot there is one additional option added - "Save to disk". This means that once you submitted the script to the server it is written to the hard drive and will be automatically loaded at next startup time.

This option is enabled by default as this seems to be a logical choice that the administrator wants to save his new script for later reuse. This, however requires proper configuration of the server and give writing permission to the directory where all scripts are stored. Otherwise the server won’t be able to write script files on the hard drive.

As in previous version only users with administrator permissions can execute commands and access all the critical elements on the server. There has been, however, another change made, long time requested by users. In the new version all the administrator specific elements are hidden for the rest of users.

Server components don’t show up on the service discovery, the user can’t see administrator commands nor he can execute them. This hasn’t been implemented to improve the server security but to reduce confusion for general users who would otherwise see a lot of stuff which can’t be used by them anyway.

11.13.3. Tigase and Python

This article describes how to get Python working as a scripting language for ad-hoc commands in Tigase server. The first part is installation, and the second shows a few code examples with explanation of the differences between Python usage and some other languages.

Please note, we are not a Python developer, and by no means this is Python development guide. All the code examples are used only to present the API available and there are certainly better ways to do it in the proper Python style. If you have any suggestions or have a better code examples I am happy to include them in the guide.

Installation

In short, installation is extremely simple: just copy the file attached to this article to your Tigase installation, to the libs/ directory. Restart the server and you are ready to start scripting and executing Python.

In theory the Tigase offers scripting support defined in JSR-223. You can use any language for which there is such support for JVM. This includes also stand-alone python implementations and the JSR-223 plugins acts just as a bridge. This, however, does not make much sense as you are not able to interact with JVM code (Tigase API). Therefore you need a language which is executed within JVM and can easily exchange data between the main application (Tigase server) and the script.

lang list no python small

The best way to go is to use Jython implementation. It works very well within JVM and more importantly, perfectly integrates with Tigase server. Tigase server is tested with Jython-2.2.1 and is confirmed to work fine. Version Jython-2.5.1 is recommended however, and all the examples are executed with this version installed. Please note, Jython-2.5.0 does not work at all. Both supported versions can be downloaded from the Jython website.

Version 2.5.1 is a bit simpler to install. When you download and run the Jython installer, find jython.jar file in the directory where you installed Jython. Copy the file to the Tigase’s libs/ directory and all is ready to go. Please note, this is the same file as the one attached to this article for your convenience.

Version 2.2.1 needs a little bit more work. The first part is the same. It is not, however enough to copy the jython.jar file. One more file is necessary for the Jython to work with the Tigase server. You have to install JSR-223 engine separately which can be downloaded from the Java scripting project website. The binary file has to be unpacked and jython-engine.jar file needs to be copied to the Tigase libs/ directory.

The best way to check if the Jython is installed correctly and support for Python is enabled, is by trying to submit a new script to the Tigase server. Browser the server service discovery, select "Session manager" component and run "Execute command" function. A new window should show with a list of all available ad-hoc commands. Select "New command script" item and click "Execute". Ad-hoc command dialog windows should show up. One of the field is "Language" with pull down list of available scripting languages. If "python" is on the list it means everything is ok and support for Python is enabled.

lang list with python small

Writing Python Scripts

Python scripts work in a similar way to Groovy or other languages scripts, except one significant difference. You cannot call "return" from the script itself. Hence you cannot simply pass script results by calling "return" statement directly from the script.

To overcome the problem, Tigase offers another way to pass script execution results. It checks the value of a special variables on the script completion: “result” and “packet”. By assigning value to one of these variables the Python (or any other language) can pass execution results back to the Tigase server.

  • result allows to return simple text (or characters String) from the script.

  • packet allows to return Packet instance which is send back to the user.

The simplest possible Python script may look like this one:

result = "Hello world!"

For instructions how to load and execute the script, please refer to the introductory article for scripting in Tigase server. There were some minor changes in Tigase 4.4.0 and later versions, so please have a look at the article describing new elements as well.

An example of a more advanced script asks the user for providing required parameters for the actual script execution:

from java.lang import *
from tigase.server import *

num1 = Command.getFieldValue(packet, "num1")
num2 = Command.getFieldValue(packet, "num2")

if num1 is None or num2 is None:
  res = Iq.commandResultForm(packet)
  Command.addTextField(res, "Note", "This is a Python script!")
  Command.addFieldValue(res, "num1", "")
  Command.addFieldValue(res, "num2", "")
  packet = res
else:
  result = num1 + num2

Except this minor difference, the rest part of scripting in Python for the Tigase administrator commands is the same as all other languages. As all languages can return execution results via these special variables, it could be argued there is no difference at all.

In another article, I am going to present the Tigase server API available for scripting framework. My main language is Groovy as it offers the best integration with JVM and Tigase API, however I will try to include Python example code as well.

12. Appendix I - Statistics description

Statistics are divided between data sources, components and processors. You may see the same statistics collected for multiple components which are defined in common components section. Note that statistics are defined by {$component}/statistic so if you wanted Max queue size on pubsub, you would look for pubsub/Max queue size. Statistics will not be provided by components that are not enabled.

12.1. Data source statistics

Data sources used to access data storages such as JDBC (databases) or MongoDB provide statistics related to stability of connections to data storage and number of open connections.

Statistics Name Description Statistics Level Format List of Possible Statistics

Number of active data sources

Number of defined and active data sources (i.e. connection pools). This is not a number of connections to data sources as it varies and is listed separately for every defined data source.

FINE

Integer

dataSource/Number of data sources

Number of connections for {dataSourceName}

Number of connections for defined data source.

FINE

String

dataSource/{dataSourceName}/uri

Number of failed reconnections for {dataSourceName}

Number of reconnections that has failed since start to the defined data source.

FINE

Integer

dataSource/{dataSourceName}/failed reconnections

Number of reconnections for {dataSourceName}

Number of reconnections for defined data source.

FINE

Integer

dataSource/{dataSourceName}/reconnections

URI of {dataSourceName}

Returns URI of defined data source.

FINE

String

dataSource/{dataSourceName}/uri

12.2. User repository statistics of {repo}

For every {method} declared in UserRepository we gather execution statistics. This statistics are collected separately for every data source for which user repository is defined.

Statistics Name Description Statistics Level Format List of Possible Statistics

Average processing time of {method}

Average time taken by call of {method} for this data source since creation of data source (most likely from server startup). It includes time taken by calls which thrown exception, etc.

FINE

Integer

userRepository/{repo}/{method}/Average processing time

Number of exceptions of a {method}

Number of exceptions the specified method has caused

FINE

Integer

userRepository/{repo}/{method}/Exceptions during execution

Number of exceptions of a {method} in last {interval}

Number of exceptions the specified method has caused within the specified interval

FINEST

Integer

userRepository/{repo}/{method}/Executions last {interval}

Number of executions of a {method}

Number of times specified method has been executed

FINE

Integer

userRepository/{repo}/{method}/Executions

12.3. Auth repository statistics of {repo}

For every {method} declared in AuthRepository we gather execution statistics. This statistics are collected separately for every data source for which authentication repository is defined.

Statistics Name Description Statistics Level Format List of Possible Statistics

Average processing time of {method}

Average time it takes to process {method}.

FINE

Integer

authRepository/{repo}/{method}/Average processing time

Number of exceptions of {method}

Number of times {method} has caused an exception.

FINE

Integer

authRepository/{repo}/{method}/Exceptions during execution

Number of exceptions of {method} in last {interval}

Number of times {method} has caused an exception within the specified interval.

FINEST

Integer

authRepository/{repo}/{method}/Executions last {interval}

Number of executions of {method}

Number of times {method} has been executed.

FINE

Integer

authRepository/{repo}/{method}/Executions

12.4. Statistics common to custom {compname} component repositories

These statistics may be found in many components which are using repository implementations created just for them. An example of such components may be:

amp

with msgBroadcastRepository as {repo} name,

message-archive

with repositoryPool as a {repo} name,

muc

with muc-dao as a {repo} name,

pubsub

with dao as a {repo} name,

sess-man

with msgRepository as a {repo} name

For custom component repositories we gather statistics in a same way as we do for user and authorization repositories. Statistics are collected on per {method} basis separately for every data source ({dataSourceName}) for which repository is defined.

Statistics Name Description Statistics Level Format List of Possible Statistics

Average processing time of {method}

Average time it takes to process {method}.

FINE

Integer

{compname}/{repo}/{dataSourceName}/{method}/Average processing time

Number of exceptions of a {method}

Number of exceptions {method} has caused.

FINE

Integer

{compname}/{repo}/{dataSourceName}/{method}/Exceptions during execution

Number of executions of a {method}

Number of times {method} has been executed.

FINE

Integer

{compname}/{repo}/{dataSourceName}/{method}/Executions

12.5. Statistics common to components

These statistics may be found in multiple components and may be seen multiple times. For example both s2s and c2s will have Bytes received statistic, so each can be found the following way:

s2s/Bytes received
c2s/Bytes received
Statistics Name Description Statistics Level Format Available {field} List of Possible Statistics

add-script last {interval}

The number of times that add-script adhoc command has been run within the last interval.

FINEST

Integer

hour minute second
{compname}/adhoc-command/add-script last hour {compname}/adhoc-command/add-script last minute {compname}/adhoc-command/add-script last second

add-script/Average processing time

The average processing time add-script takes to complete.

FINEST

Integer

add-script/Average processing time

Average processing time on last 100 runs [ms]

The average processing time in milliseconds for all commands and scripts for this component over the last 100 times component is called. This number will populate with less than 100 runs, and will continue averaging until 100 runs happens, at that point, it’s the most recent 100 instances. This statistic will reset every time the server shuts down or restarts.

FINEST

Integer

{compname}/Average processing time on last 100 runs [ms]

Bytes received

The total number of bytes that the component has received during the current server instance. This statistic resets at server shutdown or restart.

FINE or FINEST

Integer

{compname}/Bytes received

Bytes sent

The total number of bytes that the component has sent during the current server instance. This statistic resets at server shutdown or restart.

FINE or FINEST

Integer

{compname}/Bytes sent

del-script last {interval}

The number of times that del-script adhoc command has been run within the last interval.

FINEST

Integer

hour minute second
{compname}/adhoc-command/del-script last hour {compname}/adhoc-command/del-script last minute {compname}/adhoc-command/del-script last second

del-script Average processing time

The average time in ms, returned as an integer, it takes for del-script to execute.

FINEST

Integer

{compname}/adhoc-command/del-script/Average processing time

Last {interval} packets

The number of packets that have been handled by this component in the last interval.

FINEST

Integer

hour minute second
{compname}/last hour packets {compname}/last minute packets {compname}/last second packets

List-commands last {interval}

The number of list-commands requests sent to the component in the last interval.

FINEST

Integer

hour minute second
{compname}/list-commands last hour {compname}/list-commands last minute {compname}/list-commands last second

List-commands Average processing time

The average time in ms, returned as an integer, it takes for list-commands to execute on this component.

FINEST

Integer

{compname}/list-commands/Average processing time

{IN/OUT/Total} queue overflow

The number of times the in or out queue has overflown for this component. That is there are more packets queues than the max queue size. A total statistic is also available that combines both results.

FINEST

Integer

{compname}/IN queue overflow {compname}/OUT queue overflow {compname}/Total queue overflow

{in/out} queue wait: {priority}

The number of packets with {priority} priority currently in the incoming or outgoing queue.

FINEST

Integer

SYSTEM CLUSTER HIGH NORMAL LOW PRESENCE LOWEST
{compname}/In queue wait: SYSTEM {compname}/In queue wait: CLUSTER {compname}/In queue wait: HIGH {compname}/In queue wait: NORMAL {compname}/In queue wait: LOW {compname}/In queue wait: PRESENCE {compname}/In queue wait: LOWEST {compname}/Out queue wait: SYSTEM {compname}/Out queue wait: CLUSTER {compname}/Out queue wait: HIGH {compname}/Out queue wait: NORMAL {compname}/Out queue wait: LOW {compname}/Out queue wait: PRESENCE {compname}/Out queue wait: LOWEST

{IN/OUT}_QUEUE processed {type}

The number of stanzas of different types that have been processed VIA the In or Out Queue of this component. This number will reset at the end of the server instance. Each component will have a list of the different types of stanzas it can process.

FINER

Integer

# messages presences cluster other IQ no XMLNS IQ http://jabber.org/protocol/disco#items IQ bind IQ jabber:iq:roster IQ session IQ vCard IQ command IQ jabber:iq:private IQ http://jabber.org/protocol/disco#info total IQ
{compname}/IN_QUEUE processed {compname}/IN_QUEUE processed messages {compname}/IN_QUEUE processed presences {compname}/IN_QUEUE processed cluster {compname}/IN_QUEUE processed other {compname}/IN_QUEUE processed IQ no XMLNS {compname}/IN_QUEUE processed IQ http://jabber.org/protocol/disco#items {compname}/IN_QUEUE processed IQ http://jabber.org/protocol/disco#info {compname}/IN_QUEUE processed IQ bind {compname}/IN_QUEUE processed IQ jabber:iq:roster {compname}/IN_QUEUE processed IQ jabber:iq:private {compname}/IN_QUEUE processed IQ session {compname}/IN_QUEUE processed IQ vCard {compname}/IN_QUEUE processed IQ command {compname}/IN_QUEUE processed total IQ {compname}/OUT_QUEUE processed messages {compname}/OUT_QUEUE processed presences {compname}/OUT_QUEUE processed cluster {compname}/OUT_QUEUE processed other {compname}/OUT_QUEUE processed IQ no XMLNS {compname}/OUT_QUEUE processed IQ http://jabber.org/protocol/disco#items {compname}/OUT_QUEUE processed IQ http://jabber.org/protocol/disco#info {compname}/OUT_QUEUE processed IQ bind {compname}/OUT_QUEUE processed IQ jabber:iq:roster {compname}/OUT_QUEUE processed IQ jabber:iq:private {compname}/OUT_QUEUE processed IQ session {compname}/OUT_QUEUE processed IQ vCard {compname}/OUT_QUEUE processed IQ command {compname}/OUT_QUEUE processed total IQ

NOTE: Several statistics are only available from statistics component, shutdown thread will ONLY print the following: messages, presences, cluster, other, IQ no XLMNS, total IQ.

max queue size

The maximum number of items allowed in the packet queue for this component.

FINEST

Integer

{compname}/max queue size

Open Connections

The number of open connections to the component.

INFO/FINEST

Integer

{compname}/Open connections

Packets received

The total number of packets received by the component from external sources in the current instance. This number resets at server shutdown or restart.

FINE

Integer

{compname}/Packets received

Packets sent

The total number of packets sent by the component in the current instance. This number resets at server shutdown or restart.

FINE

Integer

{compname}/Packets sent

Processed packets thread: {in/out}

How many packets have been processed in and out by each processing thread.

FINEST

Integer

{compname}/Processed packets thread: IN {compname}/Processed packets thread: OUT {compname}/Processed packets thread (outliers) IN {compname}/Processed packets thread (outliers) OUT

Statistics will provide an array for each processor, listed from 0, 1, 2, 3 etc.. Let’s say that we have 4 threads set for ws2s, a list will be seen like this:
ws2s/Processed packets thread: IN=[2, 6, 4, 2]
ws2s/Processed packets thread: OUT=[8, 0, 1, 3]
ws2s/Processed packets thread (outliers) IN=mean: 79.0, deviation: 441, outliers: [in_10-ws2s: 2359]
ws2s/Processed packets thread (outliers) OUT=mean: 16.5, deviation: 23.2058941, outliers: [out_ws2s: 80]
Note that the processor arrray will only have as many threads as the component has as defined in {compname}/Processing threads.

processing threads

The number of threads provided for the particular component.

FINER

Integer

{compname}/processing threads

stream-error-counter

The number of errors counted during the operation of the server for this component. Will only be available if stream-error-counter is enabled in config.tdsl, otherwise will be 0.

FINE

Integer

{compname}/processors/stream-error-counter

Socket overflow

The number of times that this component has experienced socket overflow and had to drop packets. This does not include the number of dropped packets.

FINEST

Integer

{compname}/Socket overflow

Total {in/out} queues wait

The number of packets in the inbound or outbound queue that are currently waiting to be sent. This includes packets of all types. This is an instant statistics, in that the number in queue is only as many in the queue the moment statistics are gathered.

FINEST

Integer

{compname}/Total in queues wait {compname}/Total out queues wait

Total queue wait

A combined total of Total in queue wait and Total out queue wait statistics for this component.

FINEST

Integer

{compname}/Total queue wait

Total queues wait

A combined total of all component queue wait statistics.

FINEST

Integer

Total queues wait

Total queues overflow

The number of times the component packet wait queue has overflown and had to drop packets. This statistic does not keep track of the number of dropped packets.

FINEST

Integer

{compname}/Total queues overflow

Total/Total queues overflow

The combined total of all queue overflow statistics for all components.

FINEST

Integer

total/Total queues overflow

Waiting to send

The number of packets in the component’s queue that are waiting to be sent. This number will usually be 0 however it will grow if a large number of packets are jamming up your system, or your queue sizes are set too low.

FINEST

Integer

{compname}/Waiting to send

Watchdog runs

The number of times watchdog has been run on this component to check for stale connections.

FINER

Integer

{compname}/Watchdog runs

Watchdog stopped

The number of times watchdog identified and closed a connection it has found to be stale according to the settings in config.tdsl or by the defaults defined in this section.

FINER

Integer

{compname}/Watchdog stopped

Watchdog tests

The number of times watchdog has found a potential stale connection and has conducted a test to determine whether or not to close the connection. This is per component in the current server instance.

FINER

Integer

{compname}/Watchdog tests

12.6. Component statistics

12.6.1. AMP

No exclusive amp specific statistics

12.6.2. bosh

Statistics Name

Description

Statistics Level

Format

Available {field}
List of Possible Statistics

Bosh sessions

The number of currently open and running BOSH sessions to the server.

FINEST

Integer

bosh/Bosh sessions

pre-bind session last {interval}

The number of times the pre-bind-session command has been executed within the last specified interval.

FINEST

Integer

hour minute second
bosh/adhoc-command/pre-bind-session last hour bosh/adhoc-command/pre-bind-session last minute bosh/adhoc-command/pre-bind-session last second

pre-bind-sessions/Average processing time

The average time in ms, returned as an integer, it takes for pre-bind-session to execute.

FINEST

Integer

bosh/adhoc-command/pre-bind-session/Average processing time

12.6.3. c2s

No exclusive c2s specific statistics.

12.6.4. cl-comp

Statistics Name

Description

Statistics Level

Format

Available {field}
List of Possible Statistics

adhoc-command/cluster-nodes-list last {interval}

The number of times per interval that the cluster-nodes-list command has been executed.

FINEST

Integer

hour minute second
cl-comp/adhoc-command/cluster-nodes-list last hour cl-comp/adhoc-command/cluster-nodes-list last minute cl-comp/adhoc-command/cluster-nodes-list last second

adhoc-command/cluster-nodes-list/Average processing time

The average time in ms, returned as an integer, it takes for cluster-nodes-list to execute.

FINEST

Integer

cl-comp/adhoc-command/cluster-nodes-list/Average processing time

adhoc-command/force-stop-service last {interval}

The number of times per interval that the force-stop-service command has been executed.

FINEST

Integer

hour minute second
cl-comp/adhoc-command/force-stop-service last hour cl-comp/adhoc-command/force-stop-service last minute cl-comp/adhoc-command/force-stop-service last second

Adhoc-command/force-stop-service/Average processing time

The average time in ms, returned as an integer, it takes for force-stop-service to execute.

FINEST

Integer

cl-comp/adhoc-command/force-stop-service/Average processing time

adhoc-command/service-keys last {interval}

The number of times per interval that the service-keys command has been executed.

FINEST

Integer

hour minute second
cl-comp/adhoc-command/service-keys last hour cl-comp/adhoc-command/service-keys last minute cl-comp/adhoc-command/service-keys last second

Adhoc-command/service-keys/Average processing time

The average time in ms, returned as an integer, it takes for service-keys to execute.

FINEST

Integer

cl-comp/adhoc-command/service-keys/Average processing time

adhoc-command/sim-serv-stopped {interval}

The number of times per interval that the sim-serv-stopped command has been executed.

FINEST

Integer

hour minute second
cl-comp/adhoc-command/sim-serv-stopped last hour cl-comp/adhoc-command/sim-serv-stopped last minute cl-comp/adhoc-command/sim-serv-stopped last second

Adhoc-command/sim-serv-stopped/Average processing time

The average time in ms, returned as an integer, it takes for sim-serv-stopped to execute.

FINEST

Integer

cl-comp/adhoc-command/sim-serv-stopped/Average processing time

Average compression ratio

The average compression ratio of data sent to other clusters during the session.

FINE

Float

cl-comp/Average compression ratio

Average decompression ratio

The average compression ratio of data received from other clusters during the session.

FINE

Float

cl-comp/Average decompression ratio

Known cluster nodes

The number of cluster nodes currently connected to the server.

INFO

Integer

cl-comp/Known cluster nodes

Last {interval} disconnects

The number of cluster disconnections within the specified interval.

FINE

Comma Separated Array

day hour
cl-comp/Last day disconnects cl-comp/Last hour disconnects

For day, each array is the number of disconnections each hour, most recent first. For hour each array is the number of disconnections each minute, most recent first.

Service connected time-outs

The number of time-outs during connection initialization of cluster nodes.

FINEST

Integer

cl-comp/Service connected time-outs

Total disconnects

The number of clusters that have disconnected during the current session.

FINEST

Integer

cl-comp/Total disconnects

12.6.5. eventbus

No exclusive eventbus specific statistics.

12.6.6. message-archive

Statistics Name

Description

Statistics Level

Format

Available {field}
List of Possible Statistics

Removal time of expired messages (avg)

The average amount of time in milliseconds it takes to remove expired messages from the repository. This includes manual and automatic removal of messages.

FINE

Integer

message-archive/Removal time of expired messages (avg)

12.6.7. message-router

Statistics Name

Description

Statistics Level

Format

Available {field}
List of Possible Statistics

CPUs no

The number of CPUs available on the host machine.

FINEST

Integer

message-router/CPUs no

CPU Usage

% of available CPU power used by Tigase Server at the moment statistics are taken.

FINE

Float/String

message-router/CPU usage [%] message-router/CPU usage

Two formats are available for CPU usage: A float integer which expresses a long decimal available from CPU Usage [%], and a string which provides a rounded number with a % sign from CPU usage.

Free Heap

The amount of heap memory that is available for use, expressed in KB.

FINE

String

message-router/Free Heap

Free NonHeap

The amount of non-heap memory that is available for use, expressed in KB.

FINE

String

message-router/Free NonHeap

HEAP usage [%]

Total percent of HEAP memory in use by Tigase.

FINE

Float

message-router/HEAP usage [%]

Local hostname

The local hostname of the physical server.

INFO

String

message-router/Local hostname

Load average

The average system load for the previous minute. The way in which the load average is calculated is operating system specific but is typically a damped time-dependent average.

FINE

Float

message-router/Load average

Max Heap mem

Maximum amount of heap memory available as defined by JAVA_OPTIONS in tigase.conf, in Kb.

INFO

String

message-router/Max Heap mem

Max NonHeap mem

Maximum amount of non-heap memory available as defined by JAVA_OPTIONS in tigase.conf, in Kb.

FINE

String

message-router/Max NonHeap mem

NONHEAP Usage [%]

Total amount of NONHEAP memory in use expressed as a percentage.

FINE

Float

message-router/NONHEAP usage [%]

Threads count

The total number of processing threads available across all components.

FINEST

Integer

message-router/Threads count

Uptime

The total amount of time the server has been online for this session.

INFO

String

message-router/Uptime

Used Heap

The amount of heap memory in use in KB.

INFO

String

message-router/Used Heap

Used NonHeap

The amount of non-heap memory in use shown in KB.

FINE

String

message-router/Used NonHeap

12.6.8. monitor

Statistics Name

Description

Statistics Level

Format

Available {field}
List of Possible Statistics

adhoc-command/load-errors last {interval}

The number of times per interval that the load-errors command has been executed.

FINEST

Integer

hour minute second
monitor/adhoc-command/load-errors last hour monitor/adhoc-command/load-errors last minute monitor/adhoc-command/load-errors last second

Adhoc-command/load-errors/Average processing time

The average time in ms, returned as an integer, it takes for load-errors to execute.

FINEST

Integer

monitor/adhoc-command/load-errors/Average processing time

12.6.9. muc

Statistics Name

Description

Statistics Level

Format

Available {field}
List of Possible Statistics

adhoc-command/remove-room last {interval}

The number of times per interval that the remove-room command has been executed.

FINEST

Integer

hour minute second
monitor/adhoc-command/remove-room last hour monitor/adhoc-command/remove-room last minute monitor/adhoc-command/remove-room last second

Adhoc-command/remove-room/Average processing time

The average time in ms, returned as an integer, it takes for remove-room to execute.

FINEST

Integer

monitor/adhoc-command/remove-room/Average processing time

adhoc-command/default-room-config last {interval}

The number of times per interval that the default-room-command command has been executed.

FINEST

Integer

hour minute second
muc/adhoc-command/default-room-config last hour muc/adhoc-command/default-room-config last minute muc/adhoc-command/default-room-config last second

Adhoc-command/default-room-config/Average processing time

The average time in ms, returned as an integer, it takes for default-room-config to execute.

FINEST

Integer

muc/adhoc-command/default-room-config/Average processing time

12.6.10. proxy

Statistics Name

Description

Statistics Level

Format

List of Possible Statistics

Average transfer size in KB

Average size of packets sent through the proxy component during the current session.

FINEST

Integer

proxy/Average transfer size in KB

KBytes transferred

Total number of Kb transferred through the proxy component.

FINEST

Integer

proxy/KBytes transferred

Open streams

Number of currently open proxy streams.

FINEST

Integer

proxy/Open streams

Transfers completed

Number of specific transfers completed through proxy component.

FINEST

Integer

proxy/Transfers completed

12.6.11. pubsub

Statistics Name

Description

Statistics Level

Format

Available {field}
List of Possible Statistics

Added new nodes

The total number of new nodes that has been added in the current server instance. This statistic is reset when the server resets.

FINEST

Integer

pubsub/Added new nodes

adhoc-command/delete-item last {interval}

The number of times per interval that the delete-item command has been executed.

FINEST

Integer

hour minute second
pubsub/adhoc-command/delete-item last hour pubsub/adhoc-command/delete-item last minute pubsub/adhoc-command/delete-item last second

adhoc-command/delete-item/Average processing time

The average time in ms, returned as an integer, it takes for delete-item to execute.

FINEST

Integer

pubsub/adhoc-command/delete-item/Average processing time

adhoc-command/delete-node last {interval}

The number of times per interval that the delete-node command has been executed.

FINEST

Integer

hour minute second
pubsub/adhoc-command/delete-node last hour pubsub/adhoc-command/delete-node last minute pubsub/adhoc-command/delete-node last second

adhoc-command/delete-node/Average processing time

The average time in ms, returned as an integer, it takes for delete-node to execute.

FINEST

Integer

pubsub/adhoc-command/delete-node/Average processing time

adhoc-command/list-items last {interval}

The number of times per interval that the list-items command has been executed.

FINEST

Integer

pubsub/adhoc-command/list-items last hour pubsub/adhoc-command/list-items last minute pubsub/adhoc-command/list-items last second

adhoc-command/list-items/Average processing time

The average time in ms, returned as an integer, it takes for list-items to execute.

FINEST

Integer

pubsub/adhoc-command/list-items/Average processing time

adhoc-command/list-nodes last {interval}

The number of times per interval that the list-nodes command has been executed.

FINEST

Integer

pubsub/adhoc-command/list-nodes last hour pubsub/adhoc-command/list-nodes last minute pubsub/adhoc-command/list-nodes last second

adhoc-command/list-nodes/Average processing time

The average time in ms, returned as an integer, it takes for list-nodes to execute.

FINEST

Integer

pubsub/adhoc-command/list-nodes/Average processing time

adhoc-command/publish-item last {interval}

The number of times per interval that the publish-item command has been executed.

FINEST

Integer

pubsub/adhoc-command/publish-item last hour pubsub/adhoc-command/publish-item last minute pubsub/adhoc-command/publish-item last second

adhoc-command/publish-item/Average processing time

The average time in ms, returned as an integer, it takes for publish-item to execute.

FINEST

Integer

pubsub/adhoc-command/publish-item/Average processing time

adhoc-command/retrieve-item last {interval}

The number of times per interval that the retrieve-item command has been executed.

FINEST

Integer

hour minute second
pubsub/adhoc-command/retrieve-item last hour pubsub/adhoc-command/retrieve-item last minute pubsub/adhoc-command/retrieve-item last second

adhoc-command/retrieve-item/Average processing time

The average time in ms, returned as an integer, it takes for retrieve-item to execute.

FINEST

Integer

pubsub/adhoc-command/retrieve-item/Average processing time

AdHocConfigCommandModule last {interval}

The number of times per interval that the AdHocConfigCommandModule command has been executed.

FINEST

Integer

hour minute second
pubsub/AdHocConfigCommandModule last hour pubsub/AdHocConfigCommandModule last minute pubsub/AdHocConfigCommandModule last second

AdHocConfigCommandModule/Average processing time

The average time in ms, returned as an integer, it takes for AdHocConfigCommandModule to execute.

FINEST

Integer

pubsub/AdHocConfigCommandModule/Average processing time

Affiliations count (in cache)

The total number of pubsub affiliations that are resident in cache memory. Affiliations include JIDs that are one of the following; Owner, Publisher, Publish-Only, Member, None, Outcast. This may not reflect total pubsub affiliations in repository.

FINEST

Integer

pubsub/Affiliations count (in cache)

Average DB write time [ms]

The average time of all DB writes from PubSub component. Average is calculated using two other statistics: (Total writing time / Database writes)

FINEST

Integer

pubsub/Average DB write time [ms]

cache/hits last {interval}

The number of times the cache has achieved a hit within the last interval. A hit is when a request for information is matched to data that is inside the cache memory.

FINEST

Integer

hour minute second
pubsub/cache/hits last hour pubsub/cache/hits last minute pubsub/cache/hits last second

cache/hit-miss ratio per {interval}

The ratio of cache hits to cache misses over the specified period. A cache hit is when a request for information from the cache is matched with information in the cache. A miss is when that information request cannot find a match in cache. A miss only indicates that that information was not found in the cache, not that it is not in the repository.

FINE

Float

hour minute
pubsub/cache/hit-miss ratio per hour pubsub/cache/hit-miss ratio per minute

cache/requests last {interval}

The number of memory cache requests made within the last interval.

FINEST

Integer

hour minute second
pubsub/cache/Requests last hour pubsub/cache/Requests last minute pubsub/cache/Requests last second

Cached nodes

The number of nodes that is currently in memory cache.

FINEST

Integer

pubsub/Cached nodes

CapsModule

The number of times per interval that the CapsModule command has been executed.

FINEST

Integer

hour minute second
pubsub/CapsModule last hour pubsub/CapsModule last minute pubsub/CapsModule last second

CapsModule/Average processing time

The average time in ms, returned as an integer, it takes for CapsModule to execute.

FINEST

Integer

pubsub/CapsModule/Average processing time

db/GetNodeItems requests last {interval}

The number of times GetNodeItems command has been run within the specified interval.

FINEST

Integer

hour minute second
pubsub/db/GetNodeItems last hour pubsub/db/GetNodeItems last minute pubsub/db/GetNodeItems last second

db/GetNodeItems/Average processing time

The average time in ms, returned as an integer, it takes for GetNodeItems to execute.

FINEST

Integer

pubsub/db/GetNodeItems/Average processing time

DefaultConfigModule last {interval}

The number of times per interval that the DefaultConfigModule command has been executed.

FINEST

Integer

hour minute second
pubsub/DefaultConfigModule last hour pubsub/DefaultConfigModule last minute pubsub/DefaultConfigModule last second

DefaultConfigModule/Average processing time

The average time in ms, returned as an integer, it takes for DefaultConfigModule to execute.

FINEST

Integer

pubsub/DefaultConfigModule/Average processing time

DiscoverInfoModule last {interval}

The number of times per interval that the DiscoverInfoModule command has been executed.

FINEST

Integer

pubsub/DiscoverInfoModule last hour pubsub/DiscoverInfoModule last minute pubsub/DiscoverInfoModule last second

DiscoverInfoModule/Average processing time

The average time in ms, returned as an integer, it takes for DiscoverInfoModule to execute.

FINEST

Integer

pubsub/DiscoverInfoModule/Average processing time

DiscoverItemsModule last {interval}

The number of times per interval that the DiscoverItemsModule command has been executed.

FINEST

Integer

pubsub/DiscoverItemsModule last hour pubsub/DiscoverItemsModule last minute pubsub/DiscoverItemsModule last second

DiscoverItemsModule/Average processing time

The average time in ms, returned as an integer, it takes for DiscoverItemsModule to execute.

FINEST

Integer

pubsub/DiscoverItemsModule/Average processing time

JabberVersionModule last {interval}

The number of times per interval that the JabberVersionModule command has been executed.

FINEST

Integer

hour minute second
pubsub/JabberVersionModule last hour pubsub/JabberVersionModule last minute pubsub/JabberVersionModule last second

JabberVersionModule/Average processing time

The average time in ms, returned as an integer, it takes for JabberVersionModule to execute.

FINEST

Integer

pubsub/JabberVersionModule/Average processing time

ManageAffiiationsModule last {interval}

The number of times per interval that the ManageAffiliationsModule command has been executed.

FINEST

Integer

hour minute second
pubsub/ManageAffiliationsModule last hour pubsub/ManageAffiliationsModule last minute pubsub/ManageAffiliationsModule last second

ManageAffiliationsModule/Average processing time

The average time in ms, returned as an integer, it takes for ManageAffiliationsModule to execute.

FINEST

Integer

pubsub/ManageAffiliationsModule/Average processing time

ManageSubscriptionModule last {interval}

The number of times per interval that the ManageSubscriptionModule command has been executed.

FINEST

Integer

hour minute second
pubsub/ManageSubscriptionModule last hour pubsub/ManageSubscriptionModule last minute pubsub/ManageSubscriptionModule last second

ManageSubscriptionModule/Average processing time

The average time in ms, returned as an integer, it takes for ManageSubscriptionModule to execute.

FINEST

Integer

pubsub/ManageSubscriptionModule/Average processing time

NodeConfigModule last {interval}

The number of times per interval that the NodeConfigModule command has been executed.

FINEST

Integer

hour minute second
pubsub/NodeConfigModule last hour pubsub/NodeConfigModule last minute pubsub/NodeConfigModule last second

NodeConfigModule/Average processing time

The average time in ms, returned as an integer, it takes for NodeConfigModule to execute.

FINEST

Integer

pubsub/NodeConfigModule/Average processing time

NodeCreateModule last {interval}

The number of times per interval that the NodeCreateModule command has been executed.

FINEST

Integer

hour minute second
pubsub/NodeCreateModule last hour pubsub/NodeCreateModule last minute pubsub/NodeCreateModule last second

NodeCreateModule/Average processing time

The average time in ms, returned as an integer, it takes for NodeCreateModule to execute.

FINEST

Integer

pubsub/NodeCreateModule/Average processing time

NodeDeleteModule last {interval}

The number of times per interval that the NodeDeleteModule command has been executed.

FINEST

Integer

hour minute second
pubsub/NodeDeleteModule last hour pubsub/NodeDeleteModule last minute pubsub/NodeDeleteModule last second

NodeDeleteModule/Average processing time

The average time in ms, returned as an integer, it takes for NodeDeleteModule to execute.

FINEST

Integer

pubsub/NodeDeleteModule/Average processing time

PresenceCollectorModule last {interval}

The number of times per interval that the PresenceCollectorModule command has been executed.

FINEST

Integer

hour minute second
pubsub/PresenceCollectorModule last hour pubsub/PresenceCollectorModule last minute pubsub/PresenceCollectorModule last second

PresenceCollectorModule/Average processing time

The average time in ms, returned as an integer, it takes for PresenceCollectorModule to execute.

FINEST

Integer

pubsub/PresenceCollectorModule/Average processing time

PendingSubscriptionModule last {interval}

The number of times per interval that the PendingSubscriptionModule command has been executed.

FINEST

Integer

hour minute second
pubsub/PendingSubscriptionModule last hour pubsub/PendingSubscriptionModule last minute pubsub/PendingSubscriptionModule last second

PendingSubscriptionModule/Average processing time

The average time in ms, returned as an integer, it takes for PendingSubscriptionModule to execute.

FINEST

Integer

pubsub/PendingSubscriptionModule/Average processing time

PresenceNotifierModule last {interval}

The number of times per interval that the PresenceNotifierModule command has been executed.

FINEST

Integer

hour minute second
pubsub/PresenceNotifierModule last hour pubsub/PresenceNotifierModule last minute pubsub/PresenceNotifierModule last second

PresenceNotifierModule/Average processing time

The average time in ms, returned as an integer, it takes for PresenceNotifierModule to execute.

FINEST

Integer

pubsub/PresenceNotifierModule/Average processing time

PublishItemModule last {interval}

The number of times per interval that the PublishItemModule command has been executed.

FINEST

Integer

hour minute second
pubsub/PublishItemModule last hour pubsub/PublishItemModule last minute pubsub/PublishItemModule last second

PublishItemModule/Average processing time

The average time in ms, returned as an integer, it takes for PublishItemModule to execute.

FINEST

Integer

pubsub/PublishItemModule/Average processing time

PurgeItemsModule last {interval}

The number of times per interval that the PurgeItemsModule command has been executed.

FINEST

Integer

hour minute second
pubsub/PurgeItemsModule last hour pubsub/PurgeItemsModule last minute pubsub/PurgeItemsModule last second

PurgeItemsModule/Average processing time

The average time in ms, returned as an integer, it takes for PurgeItemsModule to execute.

FINEST

Integer

pubsub/PurgeItemsModule/Average processing time

Repository writes

Number of individual writes to Repository from the pubsub component since startup.

FINEST

Integer

pubsub/Repository writes

RetractItemModule last {interval}

The number of times per interval that the RetractItemModule command has been executed.

FINEST

Integer

hour minute second
pubsub/RetractItemModule last hour pubsub/RetractItemModule last minute pubsub/RetractItemModule last second

RetractItemModule/Average processing time

The average time in ms, returned as an integer, it takes for RetractItemModule to execute.

FINEST

Integer

pubsub/RetractItemModule/Average processing time

RetrieveAffiliationsModule last {interval}

The number of times per interval that the RetrieveAffiliationsModule command has been executed.

FINEST

Integer

hour minute second
pubsub/RetrieveAffiliationsModule last hour pubsub/RetrieveAffiliationsModule last minute pubsub/RetrieveAffiliationsModule last second

RetrieveAffiliationsModule/Average processing time

The average time in ms, returned as an integer, it takes for RetrieveAffiliationsModule to execute.

FINEST

Integer

pubsub/RetrieveAffiliationsModule/Average processing time

RetrieveItemsModule last {interval}

The number of times per interval that the RetrieveItemsModule command has been executed.

FINEST

Integer

hour minute second
pubsub/RetrieveItemsModule last hour pubsub/RetrieveItemsModule last minute pubsub/RetrieveItemsModule last second

RetrieveItemsModule/Average processing time

The average time in ms, returned as an integer, it takes for RetrieveItemsModule to execute.

FINEST

Integer

pubsub/RetrieveItemsModule/Average processing time

RetrieveSubscriptionsModule last {interval}

The number of times per interval that the RetrieveSubscriptionsModule command has been executed.

FINEST

Integer

hour minute second
pubsub/RetrieveSubscriptionsModule last hour pubsub/RetrieveSubscriptionsModule last minute pubsub/RetrieveSubscriptionsModule last second

RetrieveSubscriptionsModule/Average processing time

The average time in ms, returned as an integer, it takes for RetrieveSubscriptionsModule to execute.

FINEST

Integer

pubsub/RetrieveSubscriptionsModule/Average processing time

SubscribeNodeModule last {interval}

The number of times per interval that the SubscribeNodeModule command has been executed.

FINEST

Integer

hour minute second
pubsub/SubscribeNodeModule last hour pubsub/SubscribeNodeModule last minute pubsub/SubscribeNodeModule last second

SubscribeNodeModule/Average processing time

The average time in ms, returned as an integer, it takes for SubscribeNodeModule to execute.

FINEST

Integer

pubsub/SubscribeNodeModule/Average processing time

Subscription count (in cache)

The total number of pubsub subscriptions that are resident in cache memory. This may not reflect total pubsub subscriptions in repository.

FINEST

Integer

pubsub/Subscription count (in cache)

Total writing time

The cumulative total of time pubsub component has written to the database expressed in milliseconds.

FINEST

String (###ms)

pubsub/Total writing time

UnsubscribeNodeModule last {interval}

The number of times per interval that the UnsubscribeNodeModule command has been executed.

FINEST

Integer

hour minute second
pubsub/UnsubscribeNodeModule last hour pubsub/UnsubscribeNodeModule last minute pubsub/UnsubscribeNodeModule last second

UnsubscribeNodeModule/Average processing time

The average time in ms, returned as an integer, it takes for UnsubscribeNodeModule to execute.

FINEST

Integer

pubsub/UnsubscribeNodeModule/Average processing time

Update subscription calls

Number of times Subscriptions have been updated (this includes new, deleted, and edited).

FINEST

Integer

pubsub/Update subscriptions calls

XmppPingModule last {interval}

The number of times per interval that the XmppPingModule command has been executed.

FINEST

Integer

hour minute second
pubsub/XmppPingModule last hour pubsub/XmppPingModule last minute pubsub/XmppPingModule last second

XmppPingModule/Average processing time

The average time in ms, returned as an integer, it takes for XmppPingModule to execute.

FINEST

Integer

pubsub/XmppPingModule/Average processing time

12.6.12. repo-factory

Statistics Name

Description

Statistics Level

Format

List of Possible Statistics

Number of data repositories

The number of data repositories setup for this XMPP server.

FINE

Integer

repo-factory/Number of data repositories

Repository {jdbclocation} connections count

The number of connections made to this database.

FINE

Integer

repo-factory/repository {jdbclocation} connections count

repository {jdbclocation} reconnections

The number of reconnections made to this database.

FINEST

Integer

repo-factory/repository {jdbclocation} reconnections

repository {jdbclocation} failed reconnections

The number of reconnections that have failed to connect to this database.

FINEST

Integer

repo-factory/repository {jdbclocation} failed reconnections

12.6.13. rest

No exclusive rest specific statistics

12.6.14. s2s

Statistics Name Description Statistics Level Format Available {field} List of Possible Statistics

CIDs number

ConnectionID for the server. This may include multiple CIDs if server is running multiple vhosts.

FINEST

String

s2s/CIDs number

get-cid-connection last {interval}

The number of times get-cid-connection command has been executed within the specified interval.

FINEST

Integer

hour minute second
s2s/adhoc-command/get-cid-connection last hour s2s/adhoc-command/get-cid-connection last minute s2s/adhoc-command/get-cid-connection last second

get-cid-connection/Average processing time

The average time in ms, returned as an integer, it takes for get-cid-connection to execute.

FINEST

Integer

s2s/adhoc-command/get-cid-connection/Average processing time

s2s-bad-state-conns last {interval}

The number of times s2s-bad-state-conns command has been executed within the specified interval.

FINEST

Integer

hour minute second
s2s/adhoc-command/s2s-bad-state-conns last hour s2s/adhoc-command/s2s-bad-state-conns last minute s2s/adhoc-command/s2s-bad-state-conns last second

s2s-bad-state-conns/Average processing time

The average time in ms, returned as an integer, it takes for s2s-bad-state-conns to execute.

FINEST

Integer

s2s/adhoc-command/s2s-bad-state-conns/Average processing time

reset-bad-state-conns last {interval}

The number of times reset-bad-state-conns command has been executed within the specified interval.

FINEST

Integer

hour minute second
s2s/adhoc-command/reset-bad-state-conns last hour s2s/adhoc-command/reset-bad-state-conns last minute s2s/adhoc-command/reset-bad-state-conns last second

reset-bad-state-conns/Average processing time

The average time in ms, returned as an integer, it takes for reset-bad-state-conns to execute.

FINEST

Integer

s2s/adhoc-command/reset-bad-state-conns/Average processing time

Total DB keys

Total number of database keys.

FINEST

Integer

s2s/Total DB keys

Total {incoming/outgoing}

The total number of server-to-server connections, outgoing is local server connecting to other servers, and incoming is connections from other servers. The results may or may not be the same.

FINEST

Integer

s2s/Total incoming s2s/Total outgoing

Total {incoming/outgoing} TLS

The total number of server-to-server connections using TLS, outgoing is local server connecting to other servers, and incoming is connections from other servers. The results may or may not be the same.

FINEST

Integer

s2s/Total incoming TLS s2s/Total outgoing TLS

Total outgoing handshaking

Total number of outgoing connections that are currently handshaking to other servers.

FINEST

Integer

s2s/Total outgoing handshaking

Total control waiting

Total number of connections that were manually told to wait.

FINEST

Integer

s2s/Total control waiting

Total waiting

Total number of connections that are currently waiting for response from other server.

FINEST

Integer

s2s/Total waiting

12.6.15. sess-man

Statistics Name Description Statistics Level Format Available {field} List of Possible Statistics

Active user connections

Number of user connections that are considered active. An active user is a user that has sent stanzas to the server or through the server within the last 5 minutes.

FINER

Integer

sess-man/Active user connections

adhoc-command/connection-time last {interval}

The number of times connection-time command has been executed within the specified interval.

FINEST

Integer

hour minute second
sess-man/adhoc-command/connection-time last hour sess-man/adhoc-command/connection-time last minute sess-man/adhoc-command/connection-time last second

adhoc-command/connection-time/Average processing time

The average time in ms, returned as an integer, it takes for connection-time to execute.

FINEST

Integer

sess-man/adhoc-command/connection-time/Average processing time

adhoc-command/http://jabber.org/protocol/admin#add-user last {interval}

The number of times admin#add-user command has been executed within the specified interval.

FINEST

Integer

hour minute second
sess-man/adhoc-command/http://jabber.org/protocol/admin#add-user last hour sess-man/adhoc-command/http://jabber.org/protocol/admin#add-user last minute sess-man/adhoc-command/http://jabber.org/protocol/admin#add-user last second

adhoc-command/http://jabber.org/protocol/admin#add-user/Average processing time

The average time in ms, returned as an integer, it takes for admin#add-user to execute.

FINEST

Integer

sess-man/adhoc-command/http://jabber.org/protocol/admin#add-user/Average processing time

adhoc-command/http://jabber.org/protocol/admin#add-user-tracker last {interval}

The number of times admin#add-user-tracker command has been executed within the specified interval.

FINEST

Integer

hour minute second
sess-man/adhoc-command/http://jabber.org/protocol/admin#add-user-tracker last hour sess-man/adhoc-command/http://jabber.org/protocol/admin#add-user-tracker last minute sess-man/adhoc-command/http://jabber.org/protocol/admin#add-user-tracker last second

adhoc-command/http://jabber.org/protocol/admin#add-user-tracker/Average processing time

The average time in ms, returned as an integer, it takes for admin#add-user-tracker to execute.

FINEST

Integer

sess-man/adhoc-command/http://jabber.org/protocol/admin#add-user-tracker/Average processing time

adhoc-command/http://jabber.org/protocol/admin#announce last {interval}

The number of times admin#announce command has been executed within the specified interval.

FINEST

Integer

hour minute second
sess-man/adhoc-command/http://jabber.org/protocol/admin#announce last hour sess-man/adhoc-command/http://jabber.org/protocol/admin#announce last minute sess-man/adhoc-command/http://jabber.org/protocol/admin#announce last second

adhoc-command/http://jabber.org/protocol/admin#announce/Average processing time

The average time in ms, returned as an integer, it takes for admin#announce to execute.

FINEST

Integer

sess-man/adhoc-command/http://jabber.org/protocol/admin#announce/Average processing time

adhoc-command/http://jabber.org/protocol/admin#change-user-password last {interval}

The number of times admin#change-user-password command has been executed within the specified interval.

FINEST

Integer

hour minute second
sess-man/adhoc-command/http://jabber.org/protocol/admin#change-user-password last hour sess-man/adhoc-command/http://jabber.org/protocol/admin#change-user-password last minute sess-man/adhoc-command/http://jabber.org/protocol/admin#change-user-password last second

adhoc-command/http://jabber.org/protocol/admin#change-user-password/Average processing time

The average time in ms, returned as an integer, it takes for admin#change-user-password to execute.

FINEST

Integer

sess-man/adhoc-command/http://jabber.org/protocol/admin#change-user-password/Average processing time

adhoc-command/http://jabber.org/protocol/admin#delete-user last {interval}

The number of times admin#delete-user command has been executed within the specified interval.

FINEST

Integer

hour minute second
sess-man/adhoc-command/http://jabber.org/protocol/admin#delete-user last hour sess-man/adhoc-command/http://jabber.org/protocol/admin#delete-user last minute sess-man/adhoc-command/http://jabber.org/protocol/admin#delete-user last second

adhoc-command/http://jabber.org/protocol/admin#delete-user/Average processing time

The average time in ms, returned as an integer, it takes for admin#delete-user to execute.

FINEST

Integer

sess-man/adhoc-command/http://jabber.org/protocol/admin#delete-user/Average processing time

adhoc-comma