Commit be7b6729 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@9228 b35dd754-fafc-0310-a699-88a17e54d16e
parent 0d96ef97
...@@ -2474,3 +2474,7 @@ system.clustering.overview.clients=Clients ...@@ -2474,3 +2474,7 @@ system.clustering.overview.clients=Clients
system.clustering.overview.incoming_servers=Incoming Servers system.clustering.overview.incoming_servers=Incoming Servers
system.clustering.overview.outgoing_servers=Outgoing Servers system.clustering.overview.outgoing_servers=Outgoing Servers
system.clustering.overview.memory=Memory system.clustering.overview.memory=Memory
system.clustering.not-available=Clustering not available
system.clustering.not-installed=Clustering support was not found on the system. Install Openfire Enterprise to enable it.
system.clustering.not-valid-license=Openfire Enterprise license is not valid for clustering. You need to update your license to enable clustering.
system.clustering.starting=Clustering is being started. It may take up to 30 seconds to complete. Click {0}here{1} to refresh.
...@@ -2222,3 +2222,7 @@ system.clustering.overview.memory=Memmoria ...@@ -2222,3 +2222,7 @@ system.clustering.overview.memory=Memmoria
system.clustering.overview.node=Nodos system.clustering.overview.node=Nodos
system.clustering.overview.outgoing_servers=Servidores Salientes system.clustering.overview.outgoing_servers=Servidores Salientes
system.clustering.title=Clustering system.clustering.title=Clustering
system.clustering.not-available=Clustering no esta disponible
system.clustering.not-installed=No se ha encontrado soporte para clustering en el sistema. Instale Openfire Corporativo para habilitarlo.
system.clustering.not-valid-license=La licencia de Openfire Corporativo no incluye clustering. Necesita actualizar su licencia para habilitar clustering.
system.clustering.starting=Clustering esta arrancando. Puede tardar hasta 30 segundos para completar. Haga clic {0}aqui{1} para refrescar.
...@@ -321,6 +321,27 @@ public class ClusterManager { ...@@ -321,6 +321,27 @@ public class ClusterManager {
return JiveGlobals.getXMLProperty(CLUSTER_PROPERTY_NAME, false); return JiveGlobals.getXMLProperty(CLUSTER_PROPERTY_NAME, false);
} }
/**
* Returns true if clustering is installed and can be used by
* this JVM to join a cluster.
*
* @return true if clustering is installed and can be used by
* this JVM to join a cluster.
*/
public static boolean isClusteringAvailable() {
return CacheFactory.isClusteringAvailable();
}
/**
* Returns true is clustering is currently being started. Once the cluster
* is started or failed to be started this value will be false.
*
* @return true is clustering is currently being started.
*/
public static boolean isClusteringStarting() {
return CacheFactory.isClusteringStarting();
}
/** /**
* Returns true if this JVM is part of a cluster. The cluster may have many nodes * Returns true if this JVM is part of a cluster. The cluster may have many nodes
* or this JVM could be the only node. * or this JVM could be the only node.
......
...@@ -41,6 +41,7 @@ public class CacheFactory { ...@@ -41,6 +41,7 @@ public class CacheFactory {
public static String CLUSTERED_CACHE_PROPERTY_NAME = "cache.clustering.clustered.class"; public static String CLUSTERED_CACHE_PROPERTY_NAME = "cache.clustering.clustered.class";
private static boolean clusteringStarted = false; private static boolean clusteringStarted = false;
private static boolean clusteringStarting = false;
/** /**
* Storage for all caches that get created. * Storage for all caches that get created.
...@@ -110,6 +111,33 @@ public class CacheFactory { ...@@ -110,6 +111,33 @@ public class CacheFactory {
return cache; return cache;
} }
/**
* Returns true if clustering is installed and can be used by
* this JVM to join a cluster.
*
* @return true if clustering is installed and can be used by
* this JVM to join a cluster.
*/
public static boolean isClusteringAvailable() {
try {
Class.forName(clusteredCacheFactoryClass, true,
getClusteredCacheStrategyClassLoader("enterprise"));
} catch (ClassNotFoundException e) {
return false;
}
return true;
}
/**
* Returns true is clustering is currently being started. Once the cluster
* is started or failed to be started this value will be false.
*
* @return true is clustering is currently being started.
*/
public static boolean isClusteringStarting() {
return clusteringStarting;
}
/** /**
* Returns true if this node is currently a member of a cluster. The last step of application * Returns true if this node is currently a member of a cluster. The last step of application
* initialization is to join a cluster, so this method returns false during most of application startup. * initialization is to join a cluster, so this method returns false during most of application startup.
...@@ -170,13 +198,23 @@ public class CacheFactory { ...@@ -170,13 +198,23 @@ public class CacheFactory {
} }
/** /**
* Returns the maximum number of cluster members allowed. A value of 0 will * Returns the maximum number of cluster members allowed. A value of 0 or 1 will
* be returned when clustering is not allowed. * be returned when clustering is not allowed.
* *
* @return the maximum number of cluster members allowed or 0 if clustering is not allowed. * @return the maximum number of cluster members allowed or 0 or 1 if clustering is not allowed.
*/ */
public static int getMaxClusterNodes() { public static int getMaxClusterNodes() {
return cacheFactoryStrategy.getMaxClusterNodes(); if (isClusteringAvailable()) {
try {
CacheFactoryStrategy cacheFactory = (CacheFactoryStrategy) Class.forName(
clusteredCacheFactoryClass, true,
getClusteredCacheStrategyClassLoader("enterprise")).newInstance();
return cacheFactory.getMaxClusterNodes();
} catch (Exception e) {
Log.error("Error instantiating clustered cache factory", e);
}
}
return 0;
} }
/** /**
* 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
...@@ -259,6 +297,7 @@ public class CacheFactory { ...@@ -259,6 +297,7 @@ public class CacheFactory {
public static void startClustering() { public static void startClustering() {
clusteringStarted = false; clusteringStarted = false;
clusteringStarting = true;
try { try {
cacheFactoryStrategy = (CacheFactoryStrategy) Class.forName(clusteredCacheFactoryClass, true, cacheFactoryStrategy = (CacheFactoryStrategy) Class.forName(clusteredCacheFactoryClass, true,
getClusteredCacheStrategyClassLoader("enterprise")) getClusteredCacheStrategyClassLoader("enterprise"))
...@@ -331,6 +370,7 @@ public class CacheFactory { ...@@ -331,6 +370,7 @@ public class CacheFactory {
statsThread.start(); statsThread.start();
} }
} }
clusteringStarting = false;
} }
public static void stopClustering() { public static void stopClustering() {
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
<%@ page import="java.util.Collection" %> <%@ page import="java.util.Collection" %>
<%@ page import="java.util.Date" %> <%@ page import="java.util.Date" %>
<%@ page import="java.util.Map" %> <%@ page import="java.util.Map" %>
<%@ page import="org.jivesoftware.util.Log" %>
<html> <html>
<head> <head>
...@@ -48,19 +49,26 @@ ...@@ -48,19 +49,26 @@
if (!clusteringEnabled) { if (!clusteringEnabled) {
ClusterManager.setClusteringEnabled(false); ClusterManager.setClusteringEnabled(false);
updateSucess = true; updateSucess = true;
} } else {
else { if (ClusterManager.isClusteringAvailable()) {
ClusterManager.setClusteringEnabled(true); ClusterManager.setClusteringEnabled(true);
updateSucess = ClusterManager.isClusteringStarted(); updateSucess = ClusterManager.isClusteringStarted();
} else {
Log.error("Failed to enable clustering. Clustering is not installed.");
}
} }
} }
clusteringEnabled = ClusterManager.isClusteringStarted(); boolean clusteringAvailable = ClusterManager.isClusteringAvailable();
boolean clusteringStarting = ClusterManager.isClusteringStarting();
int maxClusterNodes = ClusterManager.getMaxClusterNodes();
clusteringEnabled = ClusterManager.isClusteringStarted() || ClusterManager.isClusteringStarting();
Collection<ClusterNodeInfo> clusterNodesInfo = ClusterManager.getNodesInfo(); Collection<ClusterNodeInfo> clusterNodesInfo = ClusterManager.getNodesInfo();
// Get some basic statistics from the cluster nodes // Get some basic statistics from the cluster nodes
// TODO Set a timeout so the page can load fast even if a node is taking too long to answer // TODO Set a timeout so the page can load fast even if a node is taking too long to answer
Collection<Object> statistics = CacheFactory.doSynchronousClusterTask(new GetBasicStatistics(), true); Collection<Object> statistics =
CacheFactory.doSynchronousClusterTask(new GetBasicStatistics(), true);
// Calculate percentages // Calculate percentages
int clients = 0; int clients = 0;
int incoming = 0; int incoming = 0;
...@@ -125,12 +133,28 @@ ...@@ -125,12 +133,28 @@
</div> </div>
<br> <br>
<% } <% }
} } else if (!clusteringAvailable) {
%>
<%
// TODO Check that clustering is available. Give a new error message if not.
%> %>
<div class="warning">
<table cellpadding="0" cellspacing="0" border="0" >
<tbody>
<tr>
<td class="jive-icon-label">
<b><fmt:message key="system.clustering.not-available" /></b><br/><br/>
</td>
</tr>
<td valign="top" align="left" colspan="2">
<% if (maxClusterNodes == 0) { %>
<span><fmt:message key="system.clustering.not-installed"/></span>
<% } else { %>
<span><fmt:message key="system.clustering.not-valid-license"/></span>
<% } %>
</td>
</tbody>
</table>
</div>
<br>
<% } %>
<!-- BEGIN 'Clustering Enabled' --> <!-- BEGIN 'Clustering Enabled' -->
<form action="system-clustering.jsp" method="post"> <form action="system-clustering.jsp" method="post">
...@@ -143,7 +167,7 @@ ...@@ -143,7 +167,7 @@
<tr> <tr>
<td width="1%" valign="top" nowrap> <td width="1%" valign="top" nowrap>
<input type="radio" name="clusteringEnabled" value="false" id="rb01" <input type="radio" name="clusteringEnabled" value="false" id="rb01"
<%= (!clusteringEnabled ? "checked" : "") %>> <%= (!clusteringEnabled ? "checked" : "") %> <%= (!clusteringAvailable || clusteringStarting ? "disabled" : "") %>>
</td> </td>
<td width="99%"> <td width="99%">
<label for="rb01"> <label for="rb01">
...@@ -154,7 +178,7 @@ ...@@ -154,7 +178,7 @@
<tr> <tr>
<td width="1%" valign="top" nowrap> <td width="1%" valign="top" nowrap>
<input type="radio" name="clusteringEnabled" value="true" id="rb02" <input type="radio" name="clusteringEnabled" value="true" id="rb02"
<%= (clusteringEnabled ? "checked" : "") %>> <%= (clusteringEnabled ? "checked" : "") %> <%= (!clusteringAvailable || clusteringStarting ? "disabled" : "") %>>
</td> </td>
<td width="99%"> <td width="99%">
<label for="rb02"> <label for="rb02">
...@@ -165,7 +189,9 @@ ...@@ -165,7 +189,9 @@
</tbody> </tbody>
</table> </table>
<br/> <br/>
<% if (clusteringAvailable && !clusteringStarting) { %>
<input type="submit" name="update" value="<fmt:message key="global.save_settings" />"> <input type="submit" name="update" value="<fmt:message key="global.save_settings" />">
<% } %>
</div> </div>
</form> </form>
<!-- END 'Clustering Enabled' --> <!-- END 'Clustering Enabled' -->
...@@ -177,7 +203,7 @@ ...@@ -177,7 +203,7 @@
<p> <p>
<fmt:message key="system.clustering.overview.info"> <fmt:message key="system.clustering.overview.info">
<fmt:param value="<%= clusterNodesInfo.size() %>" /> <fmt:param value="<%= clusterNodesInfo.size() %>" />
<fmt:param value="<%= ClusterManager.getMaxClusterNodes() %>" /> <fmt:param value="<%= maxClusterNodes %>" />
<fmt:param value="<%= "<span style='background-color:#ffc;'>" %>" /> <fmt:param value="<%= "<span style='background-color:#ffc;'>" %>" />
<fmt:param value="<%= "</span>" %>" /> <fmt:param value="<%= "</span>" %>" />
</fmt:message> </fmt:message>
...@@ -208,26 +234,29 @@ ...@@ -208,26 +234,29 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% for (ClusterNodeInfo nodeInfo : clusterNodesInfo) { <% if (!clusterNodesInfo.isEmpty()) {
boolean isLocalMember = XMPPServer.getInstance().getNodeID().equals(nodeInfo.getNodeID()); for (ClusterNodeInfo nodeInfo : clusterNodesInfo) {
String nodeID = new String(nodeInfo.getNodeID().toByteArray()); boolean isLocalMember =
XMPPServer.getInstance().getNodeID().equals(nodeInfo.getNodeID());
int nodeID = nodeInfo.getNodeID().hashCode();
Map<String, Object> nodeStats = null; Map<String, Object> nodeStats = null;
for (Object stat : statistics) { for (Object stat : statistics) {
Map<String, Object> statsMap = (Map<String, Object>) stat; Map<String, Object> statsMap = (Map<String, Object>) stat;
if (Arrays.equals((byte[]) statsMap.get(GetBasicStatistics.NODE), nodeInfo.getNodeID().toByteArray())) { if (Arrays.equals((byte[]) statsMap.get(GetBasicStatistics.NODE),
nodeInfo.getNodeID().toByteArray())) {
nodeStats = statsMap; nodeStats = statsMap;
break; break;
} }
} }
%> %>
<tr valign="top" class="<%= (isLocalMember ? "local" : "") %>" valign="middle"> <tr class="<%= (isLocalMember ? "local" : "") %>" valign="middle">
<td align="center" width="1%"> <td align="center" width="1%">
<a href="system-clustering-node.jsp?UID=<%= nodeID%>" <a href="plugins/enterprise/system-clustering-node.jsp?UID=<%= nodeID %>"
title="Click for more details" title="Click for more details"
><img src="images/server-network-24x24.gif" width="24" height="24" border="0" alt=""></a> ><img src="images/server-network-24x24.gif" width="24" height="24" border="0" alt=""></a>
</td> </td>
<td class="jive-description" nowrap width="1%" valign="middle"> <td class="jive-description" nowrap width="1%" valign="middle">
<a href="system-clustering.jsp?UID=<%= nodeID %>"> <a href="plugins/enterprise/system-clustering-node.jsp?UID=<%= nodeID %>">
<% if (isLocalMember) { %> <% if (isLocalMember) { %>
<b><%= nodeInfo.getHostName() %></b> <b><%= nodeInfo.getHostName() %></b>
<% } else { %> <% } else { %>
...@@ -297,6 +326,16 @@ ...@@ -297,6 +326,16 @@
</td> </td>
<td width="20%">&nbsp;</td> <td width="20%">&nbsp;</td>
</tr> </tr>
<% }
} else if (clusteringStarting) { %>
<tr valign="middle" align="middle" class="local">
<td colspan=8>
<fmt:message key="system.clustering.starting">
<fmt:param value="<%= "<a href='system-clustering.jsp'>" %>" />
<fmt:param value="<%= "</a>" %>" />
</fmt:message>
</td>
</tr>
<% } %> <% } %>
</tbody> </tbody>
</table> </table>
......
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