001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 2006 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * --------------------------------------------------------------------------
022: * $Id: TomcatClusterFactory.java 9864 2006-11-24 10:14:22Z danesa $
023: * --------------------------------------------------------------------------
024: */package org.objectweb.jonas.management.cluster;
025:
026: import java.util.Collection;
027: import java.util.HashMap;
028: import java.util.Set;
029:
030: import javax.management.Attribute;
031: import javax.management.AttributeList;
032: import javax.management.JMException;
033: import javax.management.MalformedObjectNameException;
034: import javax.management.ObjectName;
035:
036: import org.objectweb.jonas.jmx.CatalinaObjectName;
037: import org.objectweb.jonas.management.monitoring.DomainMonitor;
038: import org.objectweb.jonas.management.monitoring.ServerProxy;
039:
040: import org.objectweb.util.monolog.api.BasicLevel;
041:
042: /**
043: * Factory for clusters used by Tomact for Session Replication
044: * These Clusters are built dynamically, when a new server is discovered
045: * as being part of a cluster of this type.
046: * @author durieuxp
047: */
048: public class TomcatClusterFactory extends ClusterFactory {
049:
050: /**
051: * List of TomcatCluster objects
052: * There may be more than 1 TomcatCluster in the domain.
053: * key = clusterName, value = TomcatCluster
054: */
055: private HashMap myclusters = new HashMap();
056:
057: /**
058: * Constructor
059: */
060: public TomcatClusterFactory(DomainMonitor dm) {
061: super (dm);
062: }
063:
064: /**
065: * Look for a cluster by its name
066: * @param name fo the cluster
067: * @return cluster or null if not found
068: */
069: public BaseCluster getCluster(String name) {
070: return (BaseCluster) myclusters.get(name);
071: }
072:
073: /**
074: * A new server has been discovered.
075: * In case this server is recognized, it is added in a Cluster.
076: * If not, nothing is done.
077: * @param proxy The new ServerProxy
078: * @return True if recognized as a tomcat server.
079: */
080: public boolean notifyServer(ServerProxy proxy) {
081:
082: String serverName = proxy.getServerName();
083: logger.log(BasicLevel.DEBUG, serverName);
084:
085: // Determine if a Tomcat Cluster MBean exists in the server
086: // referenced by this proxy.
087: // It should have been created by Tomcat in each server where the
088: // tomcat HTTP replication has been defined (in server.xml)
089: ObjectName clusterOns;
090: try {
091: clusterOns = CatalinaObjectName
092: .catalinaClusters(domainName);
093: } catch (MalformedObjectNameException e2) {
094: logger.log(BasicLevel.WARN, e2);
095: return false;
096: }
097: Set clusterOnSet = proxy.queryNames(clusterOns);
098: if (clusterOnSet == null) {
099: logger.log(BasicLevel.DEBUG, "Cannot reach " + serverName);
100: return false;
101: }
102: if (clusterOnSet.isEmpty()) {
103: logger.log(BasicLevel.DEBUG, "No Tomcat Cluster declared");
104: return false;
105: }
106:
107: // A Server can be part of only 1 TomcatCluster : Take the first and only one.
108: ObjectName clusterOn = (ObjectName) clusterOnSet.iterator()
109: .next();
110: // CatalinaObjectName = "<domain>:type=Cluster,host=<hostname>"
111: String hostName = clusterOn.getKeyProperty("host");
112: String clusterName = (String) proxy.getAttribute(clusterOn,
113: "clusterName");
114: logger.log(BasicLevel.DEBUG, "Found Tomcat cluster: "
115: + hostName + "," + clusterName);
116:
117: // Get cluster config info from the ClusterMembership MBean
118: // It should be registered on the related server.
119: ObjectName cmon = null;
120: try {
121: cmon = CatalinaObjectName.catalinaClusterMembership(
122: domainName, hostName);
123: } catch (MalformedObjectNameException e1) {
124: logger.log(BasicLevel.WARN, e1);
125: return false;
126: }
127: if (!proxy.isRegistered(cmon)) {
128: logger.log(BasicLevel.ERROR,
129: "CatalinaClusterMembership not registered:" + cmon);
130: return false;
131: }
132: String mcastAddr = null;
133: int mcastPort = 0;
134: long mcastDropTime = 0;
135: long mcastFrequency = 0;
136: int mcastSoTimeout = 0;
137: String[] attNames = new String[] { "mcastAddr", "mcastPort",
138: "mcastDropTime", "mcastFrequency", "mcastTTL",
139: "mcastBindAddress", "mcastClusterDomain",
140: "mcastSoTimeout" };
141: AttributeList attList = proxy.getAttributes(cmon, attNames);
142: for (int i = 0; i < attList.size(); i++) {
143: Attribute att = (Attribute) attList.get(i);
144: String attName = att.getName();
145: Object attValue = att.getValue();
146: if ("mcastAddr".equals(attName)) {
147: mcastAddr = (String) attValue;
148: }
149: if ("mcastPort".equals(attName)) {
150: mcastPort = ((Integer) attValue).intValue();
151: }
152: if ("mcastDropTime".equals(attName)) {
153: mcastDropTime = ((Long) attValue).longValue();
154: }
155: if ("mcastFrequency".equals(attName)) {
156: mcastFrequency = ((Long) attValue).longValue();
157: }
158: if ("mcastSoTimeout".equals(attName)) {
159: mcastSoTimeout = ((Integer) attValue).intValue();
160: }
161: // etc.
162: }
163:
164: // Retrieve the TomcatCluster. Create it if necessary.
165: TomcatCluster cluster = (TomcatCluster) myclusters
166: .get(clusterName);
167: if (cluster == null) {
168: ObjectName clon = null;
169: try {
170: cluster = new TomcatCluster(this );
171: cluster.setHost(hostName);
172: clon = cluster.setName(clusterName);
173: } catch (JMException e) {
174: logger.log(BasicLevel.ERROR,
175: "Cannot create tomcat SessionCluster:" + e);
176: return false;
177: }
178: // Set config info
179: cluster.setMcastAddr(mcastAddr);
180: cluster.setMcastPort(mcastPort);
181: cluster.setMcastDropTime(mcastDropTime);
182: cluster.setMcastFrequency(mcastFrequency);
183: cluster.setMcastSocketTimeout(mcastSoTimeout);
184:
185: // Register the MBean if not done
186: if (!mbeanServer.isRegistered(clon)) {
187: try {
188: // A MBean is registered for each Cluster
189: mbeanServer.registerMBean(cluster, clon);
190: } catch (Exception e) {
191: logger.log(BasicLevel.ERROR,
192: "Cannot register tomcat cluster:" + e);
193: return false;
194: }
195: }
196: myclusters.put(clusterName, cluster);
197: } else {
198: // check configuration
199: boolean ok = true;
200: String currentMcastAddr = cluster.getMcastAddr();
201: if (!currentMcastAddr.equals(mcastAddr)) {
202: logger.log(BasicLevel.ERROR, "Tomcat cluster "
203: + clusterName
204: + " configuration error: found mcastAddr "
205: + mcastAddr + ", got mcastAddr "
206: + currentMcastAddr);
207: ok = false;
208: }
209: int currentMcastPort = cluster.getMcastPort();
210: if (currentMcastPort != mcastPort) {
211: logger.log(BasicLevel.ERROR, "Tomcat cluster "
212: + clusterName
213: + " configuration error: found mcastPort "
214: + mcastPort + ", got mcastPort "
215: + currentMcastPort);
216: ok = false;
217: }
218: // Policy has to be defined for missconfigured cluster members
219: // if (!ok) {}
220: }
221:
222: // add a server to the cluster
223: return cluster.addTomcatServer(serverName, proxy);
224: }
225:
226: public Collection getClusterList() {
227: return myclusters.values();
228: }
229:
230: }
|