/* * Copyright (C) 2004-2008 Jive Software, 2016-2026 Ignite Realtime Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jivesoftware.openfire; import com.google.common.reflect.ClassPath; import com.google.common.util.concurrent.SimpleTimeLimiter; import com.google.common.util.concurrent.ThreadFactoryBuilder; import org.apache.logging.log4j.LogManager; import org.jivesoftware.database.DbConnectionManager; import org.jivesoftware.database.JNDIDataSourceProvider; import org.jivesoftware.openfire.admin.AdminManager; import org.jivesoftware.openfire.archive.ArchiveManager; import org.jivesoftware.openfire.audit.AuditManager; import org.jivesoftware.openfire.audit.spi.AuditManagerImpl; import org.jivesoftware.openfire.auth.AuthFactory; import org.jivesoftware.openfire.cluster.ClusterManager; import org.jivesoftware.openfire.cluster.ClusterMonitor; import org.jivesoftware.openfire.cluster.NodeID; import org.jivesoftware.openfire.commands.AdHocCommandHandler; import org.jivesoftware.openfire.component.InternalComponentManager; import org.jivesoftware.openfire.container.AdminConsolePlugin; import org.jivesoftware.openfire.container.Module; import org.jivesoftware.openfire.container.PluginManager; import org.jivesoftware.openfire.disco.*; import org.jivesoftware.openfire.entitycaps.EntityCapabilitiesManager; import org.jivesoftware.openfire.filetransfer.DefaultFileTransferManager; import org.jivesoftware.openfire.filetransfer.FileTransferManager; import org.jivesoftware.openfire.filetransfer.proxy.FileTransferProxy; import org.jivesoftware.openfire.group.GroupManager; import org.jivesoftware.openfire.handler.*; import org.jivesoftware.openfire.keystore.CertificateStoreManager; import org.jivesoftware.openfire.keystore.IdentityStore; import org.jivesoftware.openfire.lockout.LockOutManager; import org.jivesoftware.openfire.mediaproxy.MediaProxyService; import org.jivesoftware.openfire.muc.MultiUserChatManager; import org.jivesoftware.openfire.net.MulticastDNSService; import org.jivesoftware.openfire.net.ServerTrafficCounter; import org.jivesoftware.openfire.pep.IQPEPHandler; import org.jivesoftware.openfire.pep.IQPEPOwnerHandler; import org.jivesoftware.openfire.pubsub.PubSubModule; import org.jivesoftware.openfire.roster.DefaultRosterItemProvider; import org.jivesoftware.openfire.roster.RosterItem; import org.jivesoftware.openfire.roster.RosterItemProvider; import org.jivesoftware.openfire.roster.RosterManager; import org.jivesoftware.openfire.sasl.AnonymousSaslServer; import org.jivesoftware.openfire.security.SecurityAuditManager; import org.jivesoftware.openfire.session.ConnectionSettings; import org.jivesoftware.openfire.session.RemoteSessionLocator; import org.jivesoftware.openfire.session.SoftwareServerVersionManager; import org.jivesoftware.openfire.session.SoftwareVersionManager; import org.jivesoftware.openfire.spi.*; import org.jivesoftware.openfire.transport.TransportHandler; import org.jivesoftware.openfire.update.UpdateManager; import org.jivesoftware.openfire.user.User; import org.jivesoftware.openfire.user.UserManager; import org.jivesoftware.openfire.vcard.xep0398.UserAvatarToVCardConvertor; import org.jivesoftware.openfire.vcard.VCardManager; import org.jivesoftware.util.*; import org.jivesoftware.util.cache.CacheFactory; import org.jivesoftware.util.cert.CertificateExpiryChecker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xmpp.packet.JID; import org.xmpp.packet.Message; import javax.annotation.Nonnull; import java.io.*; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; /** * The main XMPP server that will load, initialize and start all the server's * modules. The server is unique in the JVM and could be obtained by using the * {@link #getInstance()} method. *
* The loaded modules will be initialized and may access through the server other * modules. This means that the only way for a module to locate another module is * through the server. The server maintains a list of loaded modules. *
** After starting up all the modules the server will load any available plugin. * For more information see: {@link org.jivesoftware.openfire.container.PluginManager}. *
*A configuration file keeps the server configuration. This information is required for the * server to work correctly. The server assumes that the configuration file is named * openfire.xml and is located in the conf folder. The folder that keeps * the configuration file must be located under the home folder. The server will try different * methods to locate the home folder.
*Following the loading and initialization of all the modules * this method is called to iterate through the known modules and * start them.
*/ private void startModules() { for (Module module : modules.values()) { try { logger.debug( "Starting module: " + module.getName() ); module.start(); } catch (Exception e) { logger.error( "An exception occurred while starting module '{}'.", module.getName(), e ); } } } /** * Restarts the server and all it's modules only if the server is restartable. Otherwise do * nothing. */ public void restart() { if (isStandAlone() && isRestartable()) { try { Class> wrapperClass = Class.forName(WRAPPER_CLASSNAME); Method restartMethod = wrapperClass.getMethod("restart", (Class []) null); restartMethod.invoke(null, (Object []) null); } catch (Exception e) { logger.error("Could not restart container", e); } } } /** * Restarts the HTTP server only when running in stand alone mode. The restart * process will be done in another thread that will wait 1 second before doing * the actual restart. The delay will give time to the page that requested the * restart to fully render its content. */ public void restartHTTPServer() { Thread restartThread = new Thread(() -> { if (isStandAlone()) { // Restart the HTTP server manager. This covers the case // of changing the ports, as well as generating self-signed certificates. // Wait a short period before shutting down the admin console. // Otherwise, this page won't render properly! try { Thread.sleep(1000); pluginManager.getPluginByCanonicalName("admin").ifPresent(plugin -> ((AdminConsolePlugin) plugin).restart()); } catch (Exception e) { e.printStackTrace(); } } }); restartThread.setContextClassLoader(loader); restartThread.start(); } /** * Stops the server only if running in standalone mode. Do nothing if the server is running * inside of another server. */ public void stop() { logger.info("Initiating shutdown ..."); // Only do a system exit if we're running standalone if (isStandAlone()) { // if we're in a wrapper, we have to tell the wrapper to shut us down if (isRestartable()) { try { Class> wrapperClass = Class.forName(WRAPPER_CLASSNAME); Method stopMethod = wrapperClass.getMethod("stop", Integer.TYPE); stopMethod.invoke(null, 0); } catch (Exception e) { logger.error("Could not stop container", e); } } else { shutdownServer(); Thread shutdownThread = new ShutdownThread(); shutdownThread.setDaemon(true); shutdownThread.start(); } } else { // Close listening socket no matter what the condition is in order to be able // to be restartable inside a container. shutdownServer(); } } public boolean isSetupMode() { return setupMode; } public boolean isRestartable() { boolean restartable; try { restartable = Class.forName(WRAPPER_CLASSNAME) != null; } catch (ClassNotFoundException e) { restartable = false; } return restartable; } /** * Returns if the server is running in standalone mode. We consider that it's running in * standalone if the "org.jivesoftware.openfire.starter.ServerStarter" class is present in the * system. * * @return true if the server is running in standalone mode. */ public boolean isStandAlone() { boolean standalone; try { standalone = Class.forName(STARTER_CLASSNAME) != null; } catch (ClassNotFoundException e) { standalone = false; } return standalone; } /** * Verify that the database is accessible. */ private void verifyDataSource() { Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; try { con = DbConnectionManager.getConnection(); pstmt = con.prepareStatement("SELECT count(*) FROM ofID"); rs = pstmt.executeQuery(); rs.next(); } catch (Exception e) { System.err.println("Database setup or configuration error: " + "Please verify your database settings and check the " + "logs/openfire.log file for detailed error messages."); logger.error("Database could not be accessed", e); throw new IllegalArgumentException(e); } finally { DbConnectionManager.closeConnection(rs, pstmt, con); } } /** * Verifies that the given home guess is a real Openfire home directory. * We do the verification by checking for the Openfire config file in * the config dir of jiveHome. * * @param homeGuess a guess at the path to the home directory. * @param jiveConfigName the name of the config file to check. * @return a file pointing to the home directory or null if the * home directory guess was wrong. * @throws java.io.FileNotFoundException if there was a problem with the home * directory provided */ private Path verifyHome(String homeGuess, String jiveConfigName) throws FileNotFoundException { final Path openfireHome = Paths.get(homeGuess); final Path configFile = openfireHome.resolve(jiveConfigName); if (!Files.exists(configFile)) { throw new FileNotFoundException(); } else { try { return openfireHome.toAbsolutePath(); } catch (Exception ex) { throw new FileNotFoundException(); } } } /** *Retrieve the jive home for the container.
* * @throws FileNotFoundException If jiveHome could not be located */ private void locateOpenfire() throws FileNotFoundException { final String configName = "conf" + File.separator + "openfire.xml"; final String[] extensions = new String[] { "", // no extension ".tmp" // For when Openfire was shutdown uncleanly. See OF-2594. }; for (final String extension : extensions) { final String jiveConfigName = configName + extension; // First, try to load it openfireHome as a system property. if (openfireHome == null) { String homeProperty = System.getProperty("openfireHome"); try { if (homeProperty != null) { openfireHome = verifyHome(homeProperty, jiveConfigName); } } catch (FileNotFoundException fe) { // Ignore. } } // If we still don't have home, let's assume this is standalone // and just look for home in a standard sub-dir location and verify // by looking for the config file if (openfireHome == null) { try { openfireHome = verifyHome("..", jiveConfigName); } catch (IOException ie) { // Ignore. } } // If home is still null, no outside process has set it and // we have to attempt to load the value from openfire_init.xml, // which must be in the classpath. if (openfireHome == null) { try (InputStream in = getClass().getResourceAsStream("/openfire_init.xml")) { if (in != null) { String path = SAXReaderUtil.readRootElement(in).getText(); try { if (path != null) { openfireHome = verifyHome(path, jiveConfigName); } } catch (FileNotFoundException fe) { fe.printStackTrace(); } } } catch (Exception e) { System.err.println("Error loading openfire_init.xml to find home."); e.printStackTrace(); if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } } } if (openfireHome != null) { break; } } if (openfireHome == null) { System.err.println("Could not locate home"); throw new FileNotFoundException(); } else { // Set the home directory for the config file JiveGlobals.setHomePath(openfireHome); // Set the name of the config file JiveGlobals.setConfigName(configName); } } /** * This timer task is used to monitor the System input stream * for a "terminate" command from the launcher (or the console). * This allows for a graceful shutdown when Openfire is started * via the launcher, especially in Windows. */ private class Terminator extends TimerTask { private BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); @Override public void run() { try { if (stdin.ready()) { if (EXIT.equalsIgnoreCase(stdin.readLine())) { System.exit(0); // invokes shutdown hook(s) } } } catch (IOException ioe) { logger.error("Error reading console input", ioe); } } } /** *A thread to ensure the server shuts down no matter what.
*Spawned when stop() is called in standalone mode, we wait a few * seconds then call system exit().
* * @author Iain Shigeoka */ private class ShutdownHookThread extends Thread { /** *Logs the server shutdown.
*/ @Override public void run() { System.err.println("Halting server..."); shutdownServer(); System.err.println("Server halted"); } } /** *A thread to ensure the server shuts down no matter what.
*Spawned when stop() is called in standalone mode, we wait a few * seconds then call system exit().
* * @author Iain Shigeoka */ private class ShutdownThread extends Thread { /** *Shuts down the JVM after a 5 second delay.
*/ @Override public void run() { try { Thread.sleep(5000); // No matter what, we make sure it's dead System.out.println( "Openfire process forcefully killed." ); System.exit(0); } catch (InterruptedException e) { // Ignore. } } } /** * Makes a best effort attempt to shutdown the server */ private void shutdownServer() { shuttingDown = true; if (terminatorTimer != null) { terminatorTimer.cancel(); } ClusterManager.shutdown(); // Notify server listeners that the server is about to be stopped for (XMPPServerListener listener : listeners) { try { listener.serverStopping(); } catch (Exception ex) { logger.error("Exception during listener shutdown", ex); } } // If we don't have modules then the server has already been shutdown if (modules.isEmpty()) { return; } // Stop all plugins logger.info("Shutting down plugins ..."); if (pluginManager != null) { try { pluginManager.shutdown(); } catch (Exception ex) { logger.error("Exception during plugin shutdown", ex); } } logger.info("Shutting down " + modules.size() + " modules ..."); final SimpleTimeLimiter timeLimiter = SimpleTimeLimiter.create( Executors.newSingleThreadExecutor( new ThreadFactoryBuilder() .setDaemon( true ) .setNameFormat( "shutdown-thread-%d" ) .build() ) ); // OF-1996" Get all modules and stop and destroy them. Do this in the reverse order in which the were created. // This ensures that the 'most important' / core modules are shut down last, giving other modules the // opportunity to make use of their functionality during their shutdown (eg: MUC wants to send messages during // shutdown). final ListConnectionManager registered with this server. The
* ConnectionManager was registered with the server as a module while starting up
* the server.
*
* @return the ConnectionManager registered with this server.
*/
public ConnectionManager getConnectionManager() {
return (ConnectionManager) modules.get(ConnectionManagerImpl.class);
}
/**
* Returns the RoutingTable registered with this server. The
* RoutingTable was registered with the server as a module while starting up
* the server.
*
* @return the RoutingTable registered with this server.
*/
public RoutingTable getRoutingTable() {
return (RoutingTable) modules.get(RoutingTableImpl.class);
}
/**
* Returns the PacketDeliverer registered with this server. The
* PacketDeliverer was registered with the server as a module while starting up
* the server.
*
* @return the PacketDeliverer registered with this server.
*/
public PacketDeliverer getPacketDeliverer() {
return (PacketDeliverer) modules.get(PacketDelivererImpl.class);
}
/**
* Returns the RosterManager registered with this server. The
* RosterManager was registered with the server as a module while starting up
* the server.
*
* @return the RosterManager registered with this server.
*/
public RosterManager getRosterManager() {
return (RosterManager) modules.get(RosterManager.class);
}
/**
* Returns the PresenceManager registered with this server. The
* PresenceManager was registered with the server as a module while starting up
* the server.
*
* @return the PresenceManager registered with this server.
*/
public PresenceManager getPresenceManager() {
return (PresenceManager) modules.get(PresenceManagerImpl.class);
}
/**
* Returns the OfflineMessageStore registered with this server. The
* OfflineMessageStore was registered with the server as a module while starting up
* the server.
*
* @return the OfflineMessageStore registered with this server.
*/
public OfflineMessageStore getOfflineMessageStore() {
return (OfflineMessageStore) modules.get(OfflineMessageStore.class);
}
/**
* Returns the OfflineMessageStrategy registered with this server. The
* OfflineMessageStrategy was registered with the server as a module while starting
* up the server.
*
* @return the OfflineMessageStrategy registered with this server.
*/
public OfflineMessageStrategy getOfflineMessageStrategy() {
return (OfflineMessageStrategy) modules.get(OfflineMessageStrategy.class);
}
/**
* Returns the PacketRouter registered with this server. The
* PacketRouter was registered with the server as a module while starting up
* the server.
*
* @return the PacketRouter registered with this server.
*/
public PacketRouter getPacketRouter() {
return (PacketRouter) modules.get(PacketRouterImpl.class);
}
/**
* Returns the IQRegisterHandler registered with this server. The
* IQRegisterHandler was registered with the server as a module while starting up
* the server.
*
* @return the IQRegisterHandler registered with this server.
*/
public IQRegisterHandler getIQRegisterHandler() {
return (IQRegisterHandler) modules.get(IQRegisterHandler.class);
}
/**
* Returns the IQPEPHandler registered with this server. The
* IQPEPHandler was registered with the server as a module while starting up
* the server.
*
* @return the IQPEPHandler registered with this server.
*/
public IQPEPHandler getIQPEPHandler() {
return (IQPEPHandler) modules.get(IQPEPHandler.class);
}
/**
* Returns the PluginManager instance registered with this server.
*
* @return the PluginManager instance.
*/
public PluginManager getPluginManager() {
return pluginManager;
}
/**
* Returns the PubSubModule registered with this server. The
* PubSubModule was registered with the server as a module while starting up
* the server.
*
* @return the PubSubModule registered with this server.
*/
public PubSubModule getPubSubModule() {
return (PubSubModule) modules.get(PubSubModule.class);
}
/**
* Returns the ArchiveManager registered with this server. The
* ArchiveManager was registered with the server as a module while starting up
* the server.
*
* @return the ArchiveManager registered with this server.
*/
public ArchiveManager getArchiveManager() {
return (ArchiveManager) modules.get(ArchiveManager.class);
}
/**
* Returns a list with all the modules registered with the server that inherit from IQHandler.
*
* @return a list with all the modules registered with the server that inherit from IQHandler.
*/
public ListSessionManager registered with this server. The
* SessionManager was registered with the server as a module while starting up
* the server.
*
* @return the SessionManager registered with this server.
*/
public SessionManager getSessionManager() {
return (SessionManager) modules.get(SessionManager.class);
}
/**
* Returns the TransportHandler registered with this server. The
* TransportHandler was registered with the server as a module while starting up
* the server.
*
* @return the TransportHandler registered with this server.
*/
public TransportHandler getTransportHandler() {
return (TransportHandler) modules.get(TransportHandler.class);
}
/**
* Returns the PresenceUpdateHandler registered with this server. The
* PresenceUpdateHandler was registered with the server as a module while starting
* up the server.
*
* @return the PresenceUpdateHandler registered with this server.
*/
public PresenceUpdateHandler getPresenceUpdateHandler() {
return (PresenceUpdateHandler) modules.get(PresenceUpdateHandler.class);
}
/**
* Returns the PresenceSubscribeHandler registered with this server. The
* PresenceSubscribeHandler was registered with the server as a module while
* starting up the server.
*
* @return the PresenceSubscribeHandler registered with this server.
*/
public PresenceSubscribeHandler getPresenceSubscribeHandler() {
return (PresenceSubscribeHandler) modules.get(PresenceSubscribeHandler.class);
}
/**
* Returns the IQRouter registered with this server. The
* IQRouter was registered with the server as a module while starting up
* the server.
*
* @return the IQRouter registered with this server.
*/
public IQRouter getIQRouter() {
return (IQRouter) modules.get(IQRouter.class);
}
/**
* Returns the MessageRouter registered with this server. The
* MessageRouter was registered with the server as a module while starting up
* the server.
*
* @return the MessageRouter registered with this server.
*/
public MessageRouter getMessageRouter() {
return (MessageRouter) modules.get(MessageRouter.class);
}
/**
* Returns the PresenceRouter registered with this server. The
* PresenceRouter was registered with the server as a module while starting up
* the server.
*
* @return the PresenceRouter registered with this server.
*/
public PresenceRouter getPresenceRouter() {
return (PresenceRouter) modules.get(PresenceRouter.class);
}
/**
* Returns the MulticastRouter registered with this server. The
* MulticastRouter was registered with the server as a module while starting up
* the server.
*
* @return the MulticastRouter registered with this server.
*/
public MulticastRouter getMulticastRouter() {
return (MulticastRouter) modules.get(MulticastRouter.class);
}
/**
* Returns the UserManager registered with this server. The
* UserManager was registered with the server as a module while starting up
* the server.
*
* @return the UserManager registered with this server.
*/
public UserManager getUserManager() {
return UserManager.getInstance();
}
/**
* Returns the LockOutManager registered with this server. The
* LockOutManager was registered with the server as a module while starting up
* the server.
*
* @return the LockOutManager registered with this server.
*/
public LockOutManager getLockOutManager() {
return LockOutManager.getInstance();
}
/**
* Returns the UpdateManager registered with this server. The
* UpdateManager was registered with the server as a module while starting up
* the server.
*
* @return the UpdateManager registered with this server.
*/
public UpdateManager getUpdateManager() {
return (UpdateManager) modules.get(UpdateManager.class);
}
/**
* Returns the AuditManager registered with this server. The
* AuditManager was registered with the server as a module while starting up
* the server.
*
* @return the AuditManager registered with this server.
*/
public AuditManager getAuditManager() {
return (AuditManager) modules.get(AuditManagerImpl.class);
}
/**
* Returns the EntityCapabilitiesManager registered with this server. The
* EntityCapabilitiesManager was registered with the server as a module while starting up
* the server.
*
* @return the EntityCapabilitiesManager registered with this server.
*/
public EntityCapabilitiesManager getEntityCapabilitiesManager() {
return (EntityCapabilitiesManager) modules.get(EntityCapabilitiesManager.class);
}
/**
* Returns the IQDiscoInfoHandler registered with this server. The
* IQDiscoInfoHandler was registered with the server as a module while starting up
* the server.
*
* @return the IQDiscoInfoHandler registered with this server.
*/
public IQDiscoInfoHandler getIQDiscoInfoHandler() {
return (IQDiscoInfoHandler) modules.get(IQDiscoInfoHandler.class);
}
/**
* Returns the IQDiscoItemsHandler registered with this server. The
* IQDiscoItemsHandler was registered with the server as a module while starting up
* the server.
*
* @return the IQDiscoItemsHandler registered with this server.
*/
public IQDiscoItemsHandler getIQDiscoItemsHandler() {
return (IQDiscoItemsHandler) modules.get(IQDiscoItemsHandler.class);
}
/**
* Returns the PrivateStorage registered with this server. The
* PrivateStorage was registered with the server as a module while starting up
* the server.
*
* @return the PrivateStorage registered with this server.
*/
public PrivateStorage getPrivateStorage() {
return (PrivateStorage) modules.get(PrivateStorage.class);
}
/**
* Returns the MultiUserChatManager registered with this server. The
* MultiUserChatManager was registered with the server as a module while starting up
* the server.
*
* @return the MultiUserChatManager registered with this server.
*/
public MultiUserChatManager getMultiUserChatManager() {
return (MultiUserChatManager) modules.get(MultiUserChatManager.class);
}
/**
* Returns the AdHocCommandHandler registered with this server. The
* AdHocCommandHandler was registered with the server as a module while starting up
* the server.
*
* @return the AdHocCommandHandler registered with this server.
*/
public AdHocCommandHandler getAdHocCommandHandler() {
return (AdHocCommandHandler) modules.get(AdHocCommandHandler.class);
}
/**
* Returns the FileTransferProxy registered with this server. The
* FileTransferProxy was registered with the server as a module while starting up
* the server.
*
* @return the FileTransferProxy registered with this server.
*/
public FileTransferProxy getFileTransferProxy() {
return (FileTransferProxy) modules.get(FileTransferProxy.class);
}
/**
* Returns the FileTransferManager registered with this server. The
* FileTransferManager was registered with the server as a module while starting up
* the server.
*
* @return the FileTransferProxy registered with this server.
*/
public FileTransferManager getFileTransferManager() {
return (FileTransferManager) modules.get(DefaultFileTransferManager.class);
}
/**
* Returns the MediaProxyService registered with this server. The
* MediaProxyService was registered with the server as a module while starting up
* the server.
*
* @return the MediaProxyService registered with this server.
*/
public MediaProxyService getMediaProxyService() {
return (MediaProxyService) modules.get(MediaProxyService.class);
}
/**
* Returns the VCardManager registered with this server. The
* VCardManager was registered with the server as a module while starting up
* the server.
* @return the VCardManager registered with this server.
*/
public VCardManager getVCardManager() {
return VCardManager.getInstance();
}
/**
* Returns the InternalComponentManager registered with this server. The
* InternalComponentManager was registered with the server as a module while starting up
* the server.
*
* @return the InternalComponentManager registered with this server.
*/
private InternalComponentManager getComponentManager() {
return (InternalComponentManager) modules.get(InternalComponentManager.class);
}
/**
* Returns the CertificateStoreManager registered with this server. The
* CertificateStoreManager was registered with the server as a module while starting up
* the server.
*
* @return the CertificateStoreManager registered with this server.
*/
public CertificateStoreManager getCertificateStoreManager() {
return (CertificateStoreManager) modules.get( CertificateStoreManager.class );
}
/**
* Returns the CertificateExpiryChecker registered with this server. The
* CertificateExpiryChecker was registered with the server as a module while starting up
* the server.
*
* @return the CertificateExpiryChecker registered with this server.
*/
public CertificateExpiryChecker getCertificateExpiryChecker() {
return (CertificateExpiryChecker) modules.get(CertificateExpiryChecker.class);
}
/**
* Returns the UserAvatarToVCardConvertor registered with this server. The
* UserAvatarToVCardConvertor was registered with the server as a module while starting up
* the server.
*
* @return the UserAvatarToVCardConvertor registered with this server.
*/
public UserAvatarToVCardConvertor getUserAvatarToVCardConvertor() {
return (UserAvatarToVCardConvertor) modules.get(UserAvatarToVCardConvertor.class);
}
/**
* Returns the locator to use to find sessions hosted in other cluster nodes. When not running
* in a cluster a {@code null} value is returned.
*
* @return the locator to use to find sessions hosted in other cluster nodes.
*/
public RemoteSessionLocator getRemoteSessionLocator() {
return remoteSessionLocator;
}
/**
* Sets the locator to use to find sessions hosted in other cluster nodes. When not running
* in a cluster set a {@code null} value.
*
* @param remoteSessionLocator the locator to use to find sessions hosted in other cluster nodes.
*/
public void setRemoteSessionLocator(RemoteSessionLocator remoteSessionLocator) {
this.remoteSessionLocator = remoteSessionLocator;
}
/**
* Returns whether or not the server has been started.
*
* @return whether or not the server has been started.
*/
public boolean isStarted() {
return started;
}
/**
* Asynchronously send a message to every administrator on the system.
*
* @param message The message to send
* @return the future result of sending the message.
*/
public Future> sendMessageToAdmins(final String message) {
return TaskEngine.getInstance().submit(() -> {
final MessageRouter messageRouter = getMessageRouter();
final Collection