Commit ab4fe1ee authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

More clustering work.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@9217 b35dd754-fafc-0310-a699-88a17e54d16e
parent 39ddfe92
...@@ -233,13 +233,14 @@ ...@@ -233,13 +233,14 @@
## Updated key: 'sidebar.server-settings.descr' ## Updated key: 'sidebar.server-settings.descr'
## Updated key: 'index.title' ## Updated key: 'index.title'
## Updated key: 'index.title.info' ## Updated key: 'index.title.info'
## Updated key: 'index.home'
## Updated key: 'index.jvm'
## Added section 'system.clustering.*'
## Added key: 'user.roster.filter' ## Added key: 'user.roster.filter'
## Added key: 'user.roster.filter.all' ## Added key: 'user.roster.filter.all'
## Added key: 'user.roster.filter.noshared' ## Added key: 'user.roster.filter.noshared'
## Added key: 'user.roster.filter.onlyshared' ## Added key: 'user.roster.filter.onlyshared'
# Openfire # Openfire
short.title = Openfire short.title = Openfire
...@@ -256,6 +257,8 @@ tab.server.descr=Click to manage server settings ...@@ -256,6 +257,8 @@ tab.server.descr=Click to manage server settings
sidebar.system-props.descr=Click to manage server properties sidebar.system-props.descr=Click to manage server properties
sidebar.server-locale=Language and Time sidebar.server-locale=Language and Time
sidebar.server-locale.descr=Click to set the language and time zone sidebar.server-locale.descr=Click to set the language and time zone
sidebar.system-clustering=Clustering
sidebar.system-clustering.descr=Click to manage clustering settings
sidebar.system-cache=Cache Summary sidebar.system-cache=Cache Summary
sidebar.system-cache.descr=Click to manage data caches sidebar.system-cache.descr=Click to manage data caches
sidebar.server-db=Database sidebar.server-db=Database
...@@ -754,7 +757,7 @@ index.title.info=Below you will find server information, ports being used and la ...@@ -754,7 +757,7 @@ index.title.info=Below you will find server information, ports being used and la
index.properties=Server Properties index.properties=Server Properties
index.uptime=Server Uptime: index.uptime=Server Uptime:
index.version=Version: index.version=Version:
index.home=Server Home: index.home=Server Directory:
index.certificate-warning=Found RSA certificate that is not valid for the server domain. index.certificate-warning=Found RSA certificate that is not valid for the server domain.
index.server_name=Server Name: index.server_name=Server Name:
index.server_port=Server Ports index.server_port=Server Ports
...@@ -763,7 +766,7 @@ index.port_type=NORMAL ...@@ -763,7 +766,7 @@ index.port_type=NORMAL
index.port_type1=TLS (SSL) index.port_type1=TLS (SSL)
index.domain_name=Domain Name(s): index.domain_name=Domain Name(s):
index.environment=Environment index.environment=Environment
index.jvm=JVM Version and Vendor: index.jvm=Java Version:
index.app=Appserver: index.app=Appserver:
index.os=OS / Hardware: index.os=OS / Hardware:
index.local=Locale / Timezone: index.local=Locale / Timezone:
...@@ -1626,7 +1629,7 @@ setup.ldap.user.vcard.test.description=A random profile is selected for you to r ...@@ -1626,7 +1629,7 @@ setup.ldap.user.vcard.test.description=A random profile is selected for you to r
this window. this window.
setup.ldap.user.vcard.test.random=Next random profile setup.ldap.user.vcard.test.random=Next random profile
setup.ldap.user.test.users-not-found=No users were found using the specified configuration. Try changing the base DN, \ setup.ldap.user.test.users-not-found=No users were found using the specified configuration. Try changing the base DN, \
user filter or username field. user filter or username field.
setup.ldap.group.description=Configure how the server finds and loads groups from your LDAP directory. \ setup.ldap.group.description=Configure how the server finds and loads groups from your LDAP directory. \
If you need additional information about a field, hover your mouse over the corresponsing help icon. If you need additional information about a field, hover your mouse over the corresponsing help icon.
...@@ -1656,7 +1659,7 @@ setup.ldap.group.test.description=A small list of groups is selected for you to ...@@ -1656,7 +1659,7 @@ setup.ldap.group.test.description=A small list of groups is selected for you to
setup.ldap.group.test.label-description=Description setup.ldap.group.test.label-description=Description
setup.ldap.group.test.label-members=Members setup.ldap.group.test.label-members=Members
setup.ldap.group.test.group-not-found=No groups were found using the specified configuration. Try changing the base DN,\ setup.ldap.group.test.group-not-found=No groups were found using the specified configuration. Try changing the base DN,\
group filter or member field. group filter or member field.
# Setup finished Page # Setup finished Page
...@@ -1758,7 +1761,7 @@ ssl.certificates.expiration=Expires ...@@ -1758,7 +1761,7 @@ ssl.certificates.expiration=Expires
ssl.certificates.status=Status ssl.certificates.status=Status
ssl.certificates.self-signed=Self signed ssl.certificates.self-signed=Self signed
ssl.certificates.self-signed.info=Self-signed certificates should be signed by a Certificate Authority to be trusted \ ssl.certificates.self-signed.info=Self-signed certificates should be signed by a Certificate Authority to be trusted \
and accepted by clients and other servers. and accepted by clients and other servers.
ssl.certificates.signing-pending=Pending Verification ssl.certificates.signing-pending=Pending Verification
ssl.certificates.signing-pending.info=The certificate is not yet signed by a Certificate Authority. A signing request \ ssl.certificates.signing-pending.info=The certificate is not yet signed by a Certificate Authority. A signing request \
should be sent to the Certificate Authority so that it can be signed by the CA. The CA will return a new certificate \ should be sent to the Certificate Authority so that it can be signed by the CA. The CA will return a new certificate \
...@@ -1773,8 +1776,8 @@ ssl.certificates.deleted=Certificate deleted successfully. ...@@ -1773,8 +1776,8 @@ ssl.certificates.deleted=Certificate deleted successfully.
ssl.certificates.error=Error deleting the certificate. ssl.certificates.error=Error deleting the certificate.
ssl.certificates.error_messenge=Error message ssl.certificates.error_messenge=Error message
ssl.certificates.error_importing-reply=An error occured while importing the Certificate Authority reply. Verify that \ ssl.certificates.error_importing-reply=An error occured while importing the Certificate Authority reply. Verify that \
the reply is correct and that it belongs to the correct certificate. the reply is correct and that it belongs to the correct certificate.
ssl.certificates.imported=Certificate Authority reply was imported successfully. ssl.certificates.imported=Certificate Authority reply was imported successfully.
ssl.certificates.ca-reply=Certificate Authority Reply: ssl.certificates.ca-reply=Certificate Authority Reply:
ssl.certificates.restart_server=Certificates were modified so HTTP server needs to be restarted. Click {0}here{1} to \ ssl.certificates.restart_server=Certificates were modified so HTTP server needs to be restarted. Click {0}here{1} to \
restart HTTP server. restart HTTP server.
...@@ -1822,7 +1825,7 @@ ssl.signing-request.signing-request=Signing Request ...@@ -1822,7 +1825,7 @@ ssl.signing-request.signing-request=Signing Request
server-restart.title=HTTP Server Restart server-restart.title=HTTP Server Restart
server-restart.info=The HTTP server will be restarted. In a few seconds you will be redirected to the login page. \ server-restart.info=The HTTP server will be restarted. In a few seconds you will be redirected to the login page. \
In case that redirection fails click {0}here{1} to go to the login page. In case that redirection fails click {0}here{1} to go to the login page.
# Compression settings Page # Compression settings Page
...@@ -1944,10 +1947,6 @@ user.roster.items_per_page=Items per page ...@@ -1944,10 +1947,6 @@ user.roster.items_per_page=Items per page
user.roster.edit=Edit user.roster.edit=Edit
user.roster.add=Add New Item user.roster.add=Add New Item
user.roster.none_found=No roster items found. user.roster.none_found=No roster items found.
user.roster.filter=Show
user.roster.filter.all=All roster items
user.roster.filter.noshared=No shared groups
user.roster.filter.onlyshared=Only shared groups
user.roster.click_view=Click to view... user.roster.click_view=Click to view...
user.roster.deleted=Roster item deleted successfully. user.roster.deleted=Roster item deleted successfully.
user.roster.delete.title=Delete Roster Item user.roster.delete.title=Delete Roster Item
...@@ -2431,7 +2430,7 @@ ssl.import.certificate.title=Import Signed Certificate ...@@ -2431,7 +2430,7 @@ ssl.import.certificate.title=Import Signed Certificate
ssl.import.certificate.info=Use the form below to import a private key and certificate that was provided by a \ ssl.import.certificate.info=Use the form below to import a private key and certificate that was provided by a \
Certificate Authority. At this moment private keys encrypted with an AES algorithm cannot be imported. You will \ Certificate Authority. At this moment private keys encrypted with an AES algorithm cannot be imported. You will \
need to decrypt them before importing them. However, DES encrypted keys can be safely imported. To decrypt \ need to decrypt them before importing them. However, DES encrypted keys can be safely imported. To decrypt \
a private key file execute the following command: "openssl rsa -in ssl.key -out decryptedssl.key". a private key file execute the following command: "openssl rsa -in ssl.key -out decryptedssl.key".
ssl.import.certificate.boxtitle=Import Private Key and Certificate ssl.import.certificate.boxtitle=Import Private Key and Certificate
ssl.import.certificate.private-key=Content of Private Key file: ssl.import.certificate.private-key=Content of Private Key file:
ssl.import.certificate.certificate=Content of Certificate file: ssl.import.certificate.certificate=Content of Certificate file:
...@@ -2448,3 +2447,30 @@ muc.room.occupants.user=User ...@@ -2448,3 +2447,30 @@ muc.room.occupants.user=User
muc.room.occupants.nickname=Nickname muc.room.occupants.nickname=Nickname
muc.room.occupants.role=Role muc.room.occupants.role=Role
muc.room.occupants.affiliation=Affiliation muc.room.occupants.affiliation=Affiliation
# Clustering page
system.clustering.title=Clusterting
system.clustering.info=Clustering allows the server to scale a lot more and at the same time avoid a single point of \
failure. Use the form to below to enable or disable clustering for this system. After disabling clustering this \
system will leave the cluster but the cluster will remain active with the remaining cluster nodes. When clustering \
is enabled this page will show information about the load each cluster node is having.
system.clustering.enabled=Clustering was enabled successfully.
system.clustering.disabled=Clustering was disabled successfully.
system.clustering.failed-start=Failed to start or join an existing cluster. Check the error log for more information.
system.clustering.enabled.legend=Clustering Enabled
system.clustering.label_disable=Disabled
system.clustering.label_disable_info=This system is not running in a cluster.
system.clustering.label_enable=Enabled
system.clustering.label_enable_info=This system is part of a cluster.
system.clustering.label_enable_info2=Note: enabling clustering may take up to 30 seconds.
system.clustering.overview.label=Cluster Overview
system.clustering.overview.info=Below is an overview of your cluster. You have {0} node(s) running and you are \
licensed to {1} node(s) in this cluster. To see more information, click each node. The row in {2}yellow{3} \
indicates the local node.
system.clustering.overview.node=Nodes
system.clustering.overview.joined=Joined
system.clustering.overview.clients=Clients
system.clustering.overview.incoming_servers=Incoming Servers
system.clustering.overview.outgoing_servers=Outgoing Servers
system.clustering.overview.memory=Memory
...@@ -511,7 +511,7 @@ index.title.info=A continuaci\u00f3n est\u00e1n las propiedades de este servidor ...@@ -511,7 +511,7 @@ index.title.info=A continuaci\u00f3n est\u00e1n las propiedades de este servidor
index.properties=Propiedades del Servidor index.properties=Propiedades del Servidor
index.uptime=Tiempo de Actividad del Servidor: index.uptime=Tiempo de Actividad del Servidor:
index.version=Versi\u00f3n: index.version=Versi\u00f3n:
index.home=Ruta al Openfire: index.home=Ruta al servidor:
index.server_name=Nombre del Servidor: index.server_name=Nombre del Servidor:
index.server_port=Puertos del Servidor index.server_port=Puertos del Servidor
index.server_ip=IP:Puerto, Seguridad: index.server_ip=IP:Puerto, Seguridad:
...@@ -519,7 +519,7 @@ index.port_type=NORMAL ...@@ -519,7 +519,7 @@ index.port_type=NORMAL
index.port_type1=TLS (SSL) index.port_type1=TLS (SSL)
index.domain_name=Nombre(s) de Dominio: index.domain_name=Nombre(s) de Dominio:
index.environment=Ambiente index.environment=Ambiente
index.jvm=Versi\u00f3n y Fabricante de la JVM: index.jvm=Versi\u00f3n de Java:
index.app=Servidor de Aplicaciones: index.app=Servidor de Aplicaciones:
index.os=SO / Hardware: index.os=SO / Hardware:
index.local=Idioma / Huso Horario: index.local=Idioma / Huso Horario:
...@@ -2196,4 +2196,29 @@ muc.room.occupants.role=Rol ...@@ -2196,4 +2196,29 @@ muc.room.occupants.role=Rol
muc.room.occupants.title=Ocupantes en el cuarto muc.room.occupants.title=Ocupantes en el cuarto
muc.room.occupants.user=Usuario muc.room.occupants.user=Usuario
index.cs_blog=Novedades de Ignite Realtime index.cs_blog=Novedades de Ignite Realtime
index.cs_blog.unavilable=No se ha podido leer novedades de Ignite Realtime index.cs_blog.unavilable=No se ha podido leer novedades de Ignite Realtime
\ No newline at end of file system.clustering.disabled=Clustering fue deshabilitado exitosamente.
system.clustering.enabled=Clustering fue habilitado exitosamente.
system.clustering.enabled.legend=Clustering Habilitado
system.clustering.failed-start=No se ha podido iniciar o unirse al cluster. Verifique el log de errores para m\u00e1s informaci\u00f3n.
system.clustering.info=Clustering permite al servidor escalar a un numero mucho mayor de clientes y al mismo tiempo evitar tener \
un unico punto de falla. Utilice el siguiente formulario para habilitar o deshabilitar clustering para este \
sistema. Luego de deshabilitar clustering este servidor dejar\u00e1 el cluster pero el cluster seguir\u00e1 funcionando \
con los restantes nodos. Cuando clustering este habilitado esta p\u00e1gina mostrar\u00e1 informaciu00f3n sobre la carga de \
cada nodo del cluster.
system.clustering.label_disable=Deshabilitado
system.clustering.label_disable_info=Este sistema no es parte del cluster.
system.clustering.label_enable=Habilitado
system.clustering.label_enable_info=Este sistema es parte del cluster.
system.clustering.label_enable_info2=Nota: habilitar el cluster puede tardar hasta 30 segundos.
system.clustering.overview.clients=Clientes
system.clustering.overview.incoming_servers=Servidores Entrantes
system.clustering.overview.info=A continuaciu00f3n se puede observer el estado del cluster. Ud. tiene {0} nodo(s) corriendo y esta \
habilitado para tener {1} nodo(s) en este cluster. Para ver m\u00e1s informacion haga click en cada \
nodo. La fila en {2}amarillo{3} indica el nodo local.
system.clustering.overview.joined=Conectado
system.clustering.overview.label=Vision del Cluster
system.clustering.overview.memory=Memmoria
system.clustering.overview.node=Nodos
system.clustering.overview.outgoing_servers=Servidores Salientes
system.clustering.title=Clustering
\ No newline at end of file
...@@ -255,6 +255,15 @@ public interface RoutingTable { ...@@ -255,6 +255,15 @@ public interface RoutingTable {
*/ */
Collection<String> getServerHostnames(); Collection<String> getServerHostnames();
/**
* Returns the number of outgoing server sessions hosted in this JVM. When runing inside of
* a cluster you will need to get this value for each cluster node to learn the total number
* of outgoing server sessions.
*
* @return the number of outgoing server sessions hosted in this JVM.
*/
int getServerSessionsCount();
/** /**
* Returns the list of routes associated to the specified route address. When asking * Returns the list of routes associated to the specified route address. When asking
* for routes to a remote server then the requested JID will be included as the only * for routes to a remote server then the requested JID will be included as the only
......
...@@ -65,7 +65,9 @@ public class SessionManager extends BasicModule implements ClusterEventListener ...@@ -65,7 +65,9 @@ public class SessionManager extends BasicModule implements ClusterEventListener
/** /**
* Counter of user connections. A connection is counted just after it was created and not * Counter of user connections. A connection is counted just after it was created and not
* after the user became available. * after the user became available. This counter only considers sessions local to this JVM.
* That means that when running inside of a cluster you will need to add up this counter
* for each cluster node.
*/ */
private final AtomicInteger connectionsCounter = new AtomicInteger(0); private final AtomicInteger connectionsCounter = new AtomicInteger(0);
...@@ -862,6 +864,21 @@ public class SessionManager extends BasicModule implements ClusterEventListener ...@@ -862,6 +864,21 @@ public class SessionManager extends BasicModule implements ClusterEventListener
return total; return total;
} }
/**
* Returns number of sessions coming from remote servers. <i>Current implementation is only counting
* sessions connected to this JVM and not adding up sessions connected to other cluster nodes.</i>
*
* @param onlyLocal true if only sessions connected to this JVM will be considered. Otherwise count cluster wise.
* @return number of sessions coming from remote servers.
*/
public int getIncomingServerSessionsCount(boolean onlyLocal) {
int total = localSessionManager.getIncomingServerSessions().size();
if (!onlyLocal) {
// TODO Implement this when needed
}
return total;
}
/** /**
* Returns the number of sessions for a user that are available. For the count * Returns the number of sessions for a user that are available. For the count
* of all sessions for the user, including sessions that are just starting * of all sessions for the user, including sessions that are just starting
......
...@@ -19,8 +19,8 @@ import org.jivesoftware.util.cache.CacheFactory; ...@@ -19,8 +19,8 @@ import org.jivesoftware.util.cache.CacheFactory;
import org.jivesoftware.util.lock.LocalLockFactory; import org.jivesoftware.util.lock.LocalLockFactory;
import org.jivesoftware.util.lock.LockManager; import org.jivesoftware.util.lock.LockManager;
import java.util.Queue;
import java.util.Collection; import java.util.Collection;
import java.util.Queue;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
...@@ -32,8 +32,7 @@ import java.util.concurrent.LinkedBlockingQueue; ...@@ -32,8 +32,7 @@ import java.util.concurrent.LinkedBlockingQueue;
* @author Gaston Dombiak * @author Gaston Dombiak
*/ */
public class ClusterManager { public class ClusterManager {
public static String CLUSTER_PROPERTY_NAME = "clustering.enabled";
private static String CLUSTER_PROPERTY_NAME = "clustering.enabled";
private static Queue<ClusterEventListener> listeners = new ConcurrentLinkedQueue<ClusterEventListener>(); private static Queue<ClusterEventListener> listeners = new ConcurrentLinkedQueue<ClusterEventListener>();
private static BlockingQueue<Event> events = new LinkedBlockingQueue<Event>(); private static BlockingQueue<Event> events = new LinkedBlockingQueue<Event>();
...@@ -184,7 +183,6 @@ public class ClusterManager { ...@@ -184,7 +183,6 @@ public class ClusterManager {
* met again then this JVM stopped being the senior member. * met again then this JVM stopped being the senior member.
*/ */
public static void fireLeftCluster() { public static void fireLeftCluster() {
CacheFactory.leftCluster();
// Now notify rest of the listeners // Now notify rest of the listeners
for (ClusterEventListener listener : listeners) { for (ClusterEventListener listener : listeners) {
try { try {
...@@ -303,13 +301,13 @@ public class ClusterManager { ...@@ -303,13 +301,13 @@ public class ClusterManager {
} }
JiveGlobals.setXMLProperty(CLUSTER_PROPERTY_NAME, Boolean.toString(enabled)); JiveGlobals.setXMLProperty(CLUSTER_PROPERTY_NAME, Boolean.toString(enabled));
if (!enabled) { if (!enabled) {
CacheFactory.stopClustering(); shutdown();
} }
else { else {
// Reload Jive properties. This will ensure that this nodes copy of the // Reload Jive properties. This will ensure that this nodes copy of the
// properties starts correct. // properties starts correct.
JiveProperties.getInstance().init(); JiveProperties.getInstance().init();
CacheFactory.startClustering(); startup();
} }
} }
...@@ -355,6 +353,16 @@ public class ClusterManager { ...@@ -355,6 +353,16 @@ public class ClusterManager {
return CacheFactory.getClusterNodesInfo(); return CacheFactory.getClusterNodesInfo();
} }
/**
* Returns the maximum number of cluster members allowed. A value of 0 will
* be returned when clustering is not allowed.
*
* @return the maximum number of cluster members allowed or 0 if clustering is not allowed.
*/
public static int getMaxClusterNodes() {
return CacheFactory.getMaxClusterNodes();
}
/** /**
* Returns the id of the node that is the senior cluster member. When not in a cluster the returned * Returns the id of the node that is the senior cluster member. When not in a cluster the returned
* node id will be the {@link XMPPServer#getNodeID()}. * node id will be the {@link XMPPServer#getNodeID()}.
......
...@@ -541,6 +541,10 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust ...@@ -541,6 +541,10 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
return serversCache.keySet(); return serversCache.keySet();
} }
public int getServerSessionsCount() {
return localRoutingTable.getServerRoutes().size();
}
public boolean hasClientRoute(JID jid) { public boolean hasClientRoute(JID jid) {
return usersCache.containsKey(jid.toString()) || isAnonymousRoute(jid); return usersCache.containsKey(jid.toString()) || isAnonymousRoute(jid);
} }
......
...@@ -9,6 +9,8 @@ package org.jivesoftware.util.cache; ...@@ -9,6 +9,8 @@ package org.jivesoftware.util.cache;
import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.XMPPServerListener; import org.jivesoftware.openfire.XMPPServerListener;
import org.jivesoftware.openfire.cluster.ClusterEventListener;
import org.jivesoftware.openfire.cluster.ClusterManager;
import org.jivesoftware.openfire.cluster.ClusterNodeInfo; import org.jivesoftware.openfire.cluster.ClusterNodeInfo;
import org.jivesoftware.openfire.container.Plugin; import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginClassLoader; import org.jivesoftware.openfire.container.PluginClassLoader;
...@@ -167,6 +169,15 @@ public class CacheFactory { ...@@ -167,6 +169,15 @@ public class CacheFactory {
return cacheFactoryStrategy.getClusterNodesInfo(); return cacheFactoryStrategy.getClusterNodesInfo();
} }
/**
* Returns the maximum number of cluster members allowed. A value of 0 will
* be returned when clustering is not allowed.
*
* @return the maximum number of cluster members allowed or 0 if clustering is not allowed.
*/
public static int getMaxClusterNodes() {
return cacheFactoryStrategy.getMaxClusterNodes();
}
/** /**
* Invokes a task on other cluster members in an asynchronous fashion. The task will not be * Invokes a task on other cluster members in an asynchronous fashion. The task will not be
* executed on the local cluster member. If clustering is not enabled, this method * executed on the local cluster member. If clustering is not enabled, this method
...@@ -279,9 +290,23 @@ public class CacheFactory { ...@@ -279,9 +290,23 @@ public class CacheFactory {
destroyed = true; destroyed = true;
} }
}); });
ClusterManager.addListener(new ClusterEventListener() {
public void joinedCluster() {}
public void joinedCluster(byte[] nodeID) {}
public void leftCluster() {
destroyed = true;
ClusterManager.removeListener(this);
}
public void leftCluster(byte[] nodeID) {}
public void markedAsSeniorClusterMember() {}
});
// Run the timer indefinitely. // Run the timer indefinitely.
while (!destroyed) { while (!destroyed && ClusterManager.isClusteringEnabled()) {
// Publish cache stats for this cluster node (assuming clustering is // Publish cache stats for this cluster node (assuming clustering is
// enabled and there are stats to publish). // enabled and there are stats to publish).
try { try {
...@@ -298,6 +323,7 @@ public class CacheFactory { ...@@ -298,6 +323,7 @@ public class CacheFactory {
// Ignore. // Ignore.
} }
} }
statsThread = null;
Log.debug("Cache stats thread terminated."); Log.debug("Cache stats thread terminated.");
} }
}; };
......
...@@ -63,6 +63,14 @@ public interface CacheFactoryStrategy { ...@@ -63,6 +63,14 @@ public interface CacheFactoryStrategy {
*/ */
Collection<ClusterNodeInfo> getClusterNodesInfo(); Collection<ClusterNodeInfo> getClusterNodesInfo();
/**
* Returns the maximum number of cluster members allowed. A value of 0 will
* be returned when clustering is not allowed.
*
* @return the maximum number of cluster members allowed or 0 if clustering is not allowed.
*/
int getMaxClusterNodes();
/** /**
* Returns a byte[] that uniquely identifies this senior cluster member or <tt>null</tt> * Returns a byte[] that uniquely identifies this senior cluster member or <tt>null</tt>
* when not in a cluster. * when not in a cluster.
......
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
*/ */
package org.jivesoftware.util.cache; package org.jivesoftware.util.cache;
import org.jivesoftware.openfire.cluster.ClusterNodeInfo;
import org.jivesoftware.util.JiveConstants; import org.jivesoftware.util.JiveConstants;
import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.openfire.cluster.ClusterNodeInfo;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
...@@ -164,6 +164,10 @@ public class DefaultLocalCacheStrategy implements CacheFactoryStrategy { ...@@ -164,6 +164,10 @@ public class DefaultLocalCacheStrategy implements CacheFactoryStrategy {
return Collections.emptyList(); return Collections.emptyList();
} }
public int getMaxClusterNodes() {
return 0;
}
public byte[] getSeniorClusterMemberID() { public byte[] getSeniorClusterMemberID() {
return null; return null;
} }
......
...@@ -28,6 +28,11 @@ ...@@ -28,6 +28,11 @@
url="server-locale.jsp" url="server-locale.jsp"
description="${sidebar.server-locale.descr}"/> description="${sidebar.server-locale.descr}"/>
<!-- Clustering -->
<item id="system-clustering" name="${sidebar.system-clustering}"
url="system-clustering.jsp"
description="${sidebar.system-clustering.descr}"/>
<!-- System Cache --> <!-- System Cache -->
<item id="system-cache" name="${sidebar.system-cache}" <item id="system-cache" name="${sidebar.system-cache}"
url="system-cache.jsp" url="system-cache.jsp"
......
...@@ -8,14 +8,19 @@ ...@@ -8,14 +8,19 @@
- a copy of which is included in this distribution. - a copy of which is included in this distribution.
--%> --%>
<%@ page import="org.apache.mina.transport.socket.nio.SocketAcceptor, <%@ page import="com.sun.syndication.feed.synd.SyndEntry,
org.jivesoftware.admin.AdminConsole, com.sun.syndication.feed.synd.SyndFeed,
org.jivesoftware.openfire.Connection" com.sun.syndication.fetcher.FeedFetcher"
%> %>
<%@ page import="org.jivesoftware.openfire.ServerPort"%> <%@ page import="com.sun.syndication.fetcher.impl.FeedFetcherCache"%>
<%@ page import="org.jivesoftware.openfire.XMPPServer"%> <%@ page import="com.sun.syndication.fetcher.impl.HashMapFeedInfoCache"%>
<%@ page import="org.jivesoftware.openfire.container.AdminConsolePlugin"%> <%@ page import="org.apache.mina.transport.socket.nio.SocketAcceptor"%>
<%@ page import="org.jivesoftware.openfire.filetransfer.proxy.FileTransferProxy"%> <%@ page import="org.jivesoftware.admin.AdminConsole"%>
<%@ page import="org.jivesoftware.openfire.Connection" %>
<%@ page import="org.jivesoftware.openfire.ServerPort" %>
<%@ page import="org.jivesoftware.openfire.XMPPServer" %>
<%@ page import="org.jivesoftware.openfire.container.AdminConsolePlugin" %>
<%@ page import="org.jivesoftware.openfire.filetransfer.proxy.FileTransferProxy" %>
<%@ page import="org.jivesoftware.openfire.http.HttpBindManager" %> <%@ page import="org.jivesoftware.openfire.http.HttpBindManager" %>
<%@ page import="org.jivesoftware.openfire.mediaproxy.MediaProxyService" %> <%@ page import="org.jivesoftware.openfire.mediaproxy.MediaProxyService" %>
<%@ page import="org.jivesoftware.openfire.net.SSLConfig" %> <%@ page import="org.jivesoftware.openfire.net.SSLConfig" %>
...@@ -25,18 +30,12 @@ ...@@ -25,18 +30,12 @@
<%@ page import="org.jivesoftware.openfire.stun.STUNService" %> <%@ page import="org.jivesoftware.openfire.stun.STUNService" %>
<%@ page import="org.jivesoftware.openfire.update.Update" %> <%@ page import="org.jivesoftware.openfire.update.Update" %>
<%@ page import="org.jivesoftware.openfire.update.UpdateManager" %> <%@ page import="org.jivesoftware.openfire.update.UpdateManager" %>
<%@ page import="org.jivesoftware.util.*" %>
<%@ page import="java.net.InetSocketAddress" %> <%@ page import="java.net.InetSocketAddress" %>
<%@ page import="java.net.SocketAddress" %> <%@ page import="java.net.SocketAddress" %>
<%@ page import="java.text.DecimalFormat" %>
<%@ page import="java.net.URL" %> <%@ page import="java.net.URL" %>
<%@ page import="java.text.DecimalFormat" %>
<%@ page import="java.util.List" %> <%@ page import="java.util.List" %>
<%@ page import="org.jivesoftware.util.*" %>
<%@ page import="com.sun.syndication.fetcher.FeedFetcher" %>
<%@ page import="com.sun.syndication.fetcher.impl.FeedFetcherCache" %>
<%@ page import="com.sun.syndication.fetcher.impl.HashMapFeedInfoCache" %>
<%@ page import="com.sun.syndication.io.FeedException" %>
<%@ page import="com.sun.syndication.feed.synd.SyndEntry" %>
<%@ page import="com.sun.syndication.feed.synd.SyndFeed" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %> <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %> <%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
...@@ -370,7 +369,7 @@ ...@@ -370,7 +369,7 @@
List entries = lastBlogFeed.getEntries(); List entries = lastBlogFeed.getEntries();
for (int i = 0; i < entries.size() && i < 3; i++) { for (int i = 0; i < entries.size() && i < 3; i++) {
SyndEntry entry = (SyndEntry) entries.get(i); %> SyndEntry entry = (SyndEntry) entries.get(i); %>
<h5><a href="<%= entry.getLink() %>"><%= entry.getTitle()%></a>, <h5><a href="<%= entry.getLink() %>" target="_blank"><%= entry.getTitle()%></a>,
<span class="jive-blog-date"><%= JiveGlobals.formatDateTime(entry.getPublishedDate())%></span></h5> <span class="jive-blog-date"><%= JiveGlobals.formatDateTime(entry.getPublishedDate())%></span></h5>
<% } <% }
...@@ -384,7 +383,7 @@ ...@@ -384,7 +383,7 @@
List entries = lastReleaseFeed.getEntries(); List entries = lastReleaseFeed.getEntries();
for (int i = 0; i < entries.size() && i < 3; i++) { for (int i = 0; i < entries.size() && i < 3; i++) {
SyndEntry entry = (SyndEntry) entries.get(i); %> SyndEntry entry = (SyndEntry) entries.get(i); %>
<h5><a href="<%= entry.getLink() %>"><%= entry.getTitle()%></a>, <h5><a href="<%= entry.getLink() %>" target="_blank"><%= entry.getTitle()%></a>,
<span class="jive-blog-date"><%= JiveGlobals.formatDateTime(entry.getPublishedDate())%></span></h5> <span class="jive-blog-date"><%= JiveGlobals.formatDateTime(entry.getPublishedDate())%></span></h5>
<% } <% }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment