001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or modify it
007: * under the terms of the GNU Lesser General Public License as published by the
008: * Free Software Foundation; either version 2.1 of the License, or any later
009: * version.
010: *
011: * This library is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
014: * for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public License
017: * along with this library; if not, write to the Free Software Foundation,
018: * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
019: * --------------------------------------------------------------------------
020: * $Id: DiscoveryManager.java 9249 2006-07-27 09:13:54Z durieuxp $
021: * --------------------------------------------------------------------------
022: */package org.objectweb.jonas.discovery;
023:
024: /**
025: * @author Takoua Abdellatif
026: */
027: import javax.management.JMException;
028: import javax.management.MBeanRegistration;
029: import javax.management.MBeanServer;
030: import javax.management.MBeanServerNotification;
031: import javax.management.Notification;
032: import javax.management.NotificationListener;
033: import javax.management.ObjectName;
034:
035: import org.objectweb.jonas.common.Log;
036: import org.objectweb.jonas.jmx.J2eeObjectName;
037: import org.objectweb.util.monolog.api.BasicLevel;
038: import org.objectweb.util.monolog.api.Logger;
039:
040: /**
041: * DiscoveryManager goal is to listen to a well known and reconfigurable
042: * IpAddress and to give appropriate JMXURL to manage remotely Jonas server.
043: *
044: * @author <a href="mailto:Takoua.Abdellatif@inria.fr">Takoua Abdellatif </a>
045: * @author Vivek Lakshmanan
046: * @version 1.0
047: *
048: */
049: public class DiscoveryManager implements DiscoveryManagerMBean,
050: MBeanRegistration, NotificationListener {
051:
052: private static Logger logger = Log
053: .getLogger(Log.JONAS_DISCOVERY_PREFIX);
054:
055: /**
056: * <code>greetingListeningPort</code> unicast port to listen to for
057: * responses to greeting message
058: */
059: private int greetingListeningPort;
060:
061: /**
062: * <code>listeningPort</code> for multicast socket creation
063: */
064: private int listeningPort;
065:
066: /**
067: * <code>listeningIp</code> for multicast socket creation
068: */
069: private String listeningIp;
070:
071: /**
072: * Runnable object that implements multicast communication with the servers
073: * in the management domain
074: */
075: private DiscoveryComm dc;
076:
077: private DiscoveryGreetingResponder dgr;
078:
079: private DiscoveryGreetingListener dgl;
080:
081: /**
082: * Thread associated to DiscoveryManager
083: */
084: private Thread commDaemon;
085:
086: /**
087: * Thread associated with DiscoveryGreetingListener. This will continue
088: * listening on the multicast port throughout the life of the server for
089: * greeting messages from new servers.
090: */
091: private Thread discoveryGreetingListenerThread;
092:
093: /**
094: * Current MBean Server
095: */
096: private MBeanServer mbeanServer;
097:
098: private ObjectName myOn;
099:
100: private int ttl = 1;
101:
102: private int greetingAckTimeOut;
103:
104: private String jonasName = null;
105:
106: private String domainName = null;
107:
108: private String serverId = null;
109:
110: private String[] urls = null;
111:
112: /**
113: * @param serverId TODO
114: * @param listeningPort
115: * Port to listen to for multicast messages.
116: * @param listeningIp
117: * IP where the multicast group will listen.
118: * @param greetingListeningPort
119: * Port to listen to greeting replies on. A message on this port
120: * signifies that a server already in the group has the same
121: * server name as used by this instance.
122: * @param greetingAckTimeOut
123: * The amount of time the server will listen to
124: * greetingListeningPort for replies.
125: */
126: public DiscoveryManager(String serverId, int listeningPort,
127: String listeningIp, int greetingListeningPort,
128: int greetingAckTimeOut) {
129: this .serverId = serverId;
130: this .listeningIp = listeningIp;
131: this .listeningPort = listeningPort;
132: this .greetingListeningPort = greetingListeningPort;
133: this .greetingAckTimeOut = greetingAckTimeOut;
134: }
135:
136: /*
137: * (non-Javadoc)
138: *
139: * @see org.objectweb.jonas.server.discovery.DiscoveryManagerMBean#start()
140: */
141: public void start() {
142:
143: dgl = new DiscoveryGreetingListener(this );
144: dgr = new DiscoveryGreetingResponder(this );
145:
146: // Start greeting listener and greeting responder in this order.
147: if (discoveryGreetingListenerThread == null) {
148: discoveryGreetingListenerThread = new Thread(dgl,
149: "GreetingListener");
150: }
151: discoveryGreetingListenerThread.start();
152:
153: try {
154: // We dont need this to happen inside a thread since it is a
155: // serial operation, this will only listen for greetingAckTimeOut
156: // and listen for rejection messages.
157: dgr.handleGreeting();
158: } catch (DuplicateServerNameException e) {
159: // A server with the same servername already exists.
160: logger
161: .log(
162: BasicLevel.ERROR,
163: "Discovery manager failed to start due to a pre-existing"
164: + " server in the domain with the same ID.",
165: e);
166: throw e;
167: }
168:
169: // creates an instance of the Discovery communication class
170: dc = new DiscoveryComm(this );
171: if (commDaemon == null) {
172: commDaemon = new Thread(dc, "commDaemon");
173: }
174: commDaemon.start();
175: }
176:
177: /**
178: * @see org.objectweb.jonas.server.discovery.DiscoveryManagerMBean#getGreetingAckTimeOut()
179: */
180: public int getGreetingAckTimeOut() {
181: return greetingAckTimeOut;
182:
183: }
184:
185: /**
186: * (non-Javadoc)
187: *
188: * @see org.objectweb.jonas.server.discovery.DiscoveryManagerMBean#setGreetingAckTimeOut()
189: */
190: public void setGreetingAckTimeOut(int greetingAckTimeOut) {
191: this .greetingAckTimeOut = greetingAckTimeOut;
192:
193: }
194:
195: /**
196: * @see org.objectweb.jonas.server.discovery.DiscoveryManagerMBean#getGreetingListeningPort()
197: */
198: public int getGreetingListeningPort() {
199: return greetingListeningPort;
200:
201: }
202:
203: /**
204: * (non-Javadoc)
205: *
206: * @see org.objectweb.jonas.server.discovery.DiscoveryManagerMBean#setGreetingListeningPort()
207: */
208: public void setGreetingListeningPort(int greetingListeningPort) {
209: this .greetingListeningPort = greetingListeningPort;
210:
211: }
212:
213: /**
214: * @see org.objectweb.jonas.server.discovery.DiscoveryManagerMBean#getListeningPort()
215: */
216: public int getListeningPort() {
217: return listeningPort;
218: }
219:
220: /**
221: * (non-Javadoc)
222: *
223: * @see org.objectweb.jonas.server.discovery.DiscoveryManagerMBean#setListeningPort()
224: */
225: public void setListeningPort(int listeningPort) {
226: this .listeningPort = listeningPort;
227:
228: }
229:
230: /**
231: * @see org.objectweb.jonas.server.discovery.DiscoveryManagerMBean#getListeningIp()
232: */
233: public String getListeningIp() {
234: return listeningIp;
235: }
236:
237: /**
238: * @see org.objectweb.jonas.server.discovery.DiscoveryManagerMBean#setListeningIp()
239: */
240: public void setListeningIp(String listeningIp) {
241: this .listeningIp = listeningIp;
242:
243: }
244:
245: /**
246: * @see org.objectweb.jonas.server.discovery.DiscoveryManagerMBean#setTimeToLive()
247: */
248: public void setTimeToLive(int ttl) {
249: this .ttl = ttl;
250: }
251:
252: /**
253: * @see org.objectweb.jonas.server.discovery.DiscoveryManagerMBean#getTimeToLive()
254: */
255: public int getTimeToLive() {
256: return this .ttl;
257: }
258:
259: /**
260: * @see javax.management.MBeanRegistration#preRegister(javax.management.MBeanServer,
261: * javax.management.ObjectName)
262: */
263: public ObjectName preRegister(MBeanServer mbeanServer, ObjectName on)
264: throws Exception {
265: // set mbeanServer
266: this .mbeanServer = mbeanServer;
267: this .myOn = on;
268:
269: return myOn;
270: }
271:
272: /**
273: * @see javax.management.MBeanRegistration#postRegister(java.lang.Boolean)
274: */
275: public void postRegister(Boolean arg0) {
276: // Add discovery manager as a listener of the delegate object to receive
277: // unregistration notification of the j2EEServer.
278: ObjectName delegate;
279: try {
280: delegate = new ObjectName(
281: "JMImplementation:type=MBeanServerDelegate");
282: mbeanServer.addNotificationListener(delegate, this , null,
283: null);
284: } catch (JMException e) {
285: e.printStackTrace();
286: }
287: }
288:
289: /**
290: * @see javax.management.MBeanRegistration#preDeregister()
291: */
292: public void preDeregister() throws Exception {
293: // stop the Discovery Manager
294: stop();
295: }
296:
297: /**
298: * @see javax.management.MBeanRegistration#postDeregister()
299: */
300: public void postDeregister() {
301:
302: }
303:
304: /**
305: * @see javax.management.NotificationListener#handleNotification(javax.management.Notification,
306: * java.lang.Object)
307: */
308: public void handleNotification(Notification notification,
309: Object handback) {
310: if (notification.getType().equals(
311: MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
312: ObjectName notificationSender = ((MBeanServerNotification) notification)
313: .getMBeanName();
314: ObjectName j2eeServerName = J2eeObjectName.J2EEServer(
315: domainName, jonasName);
316: if (notificationSender.equals(j2eeServerName)) {
317: // If DiscoveryComm has been created then stop it.
318: // If the discovery greeting checks passed then dc != null.
319: if (dc != null) {
320: dc.stop();
321: }
322:
323: }
324: }
325: }
326:
327: /**
328: * @return jonasName The jonasName.
329: */
330: public String getJonasName() {
331: return jonasName;
332: }
333:
334: /**
335: * @param jonasName
336: * The jonasName to set.
337: */
338: protected void setJonasName(String jonasName) {
339: this .jonasName = jonasName;
340: }
341:
342: /**
343: * @return jonasName The domain name.
344: */
345: public String getDomainName() {
346: return domainName;
347: }
348:
349: /**
350: * @param domainNamle
351: * The domainName to set.
352: */
353: protected void setDomainName(String domainNamle) {
354: this .domainName = domainNamle;
355: }
356:
357: /**
358: * @param urls
359: * The urls.
360: */
361: protected String[] getUrls() {
362: return urls;
363: }
364:
365: /**
366: * @param urls
367: * The urls to set.
368: */
369: protected void setUrls(String[] urls) {
370: this .urls = urls;
371: }
372:
373: /**
374: * Stop
375: */
376: public void stop() {
377: // dc is null if a DuplicateServerNameException is thrown
378: // at start up time, so do not send a notification.
379: if (dc != null) {
380: dc.stop();
381: }
382: dgl.stop();
383: }
384:
385: public String getServerId() {
386: return serverId;
387: }
388:
389: public void setServerId(String serverId) {
390: this.serverId = serverId;
391: }
392: }
|