Author: pferraro
Date: 2008-09-05 10:47:30 -0400 (Fri, 05 Sep 2008)
New Revision: 1780
Added:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertiseListenerFactory.java
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseEventType.java
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerFactoryImpl.java
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerImpl.java
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertisedServer.java
Removed:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertiseEventType.java
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertisedServer.java
Modified:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/DefaultJBossWebEventHandler.java
trunk/mod_cluster/src/main/java/org/jboss/modcluster/ModClusterService.java
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertiseListener.java
Log:
Extract interface from AdvertiseListener and create factory to decouple implementation
from DefaultJBossWebEventHandler. DefaultJBossWebEventHandler and AdvertiseListener can
now be unit tested independently.
Code cleanup.
Modified:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/DefaultJBossWebEventHandler.java
===================================================================
---
trunk/mod_cluster/src/main/java/org/jboss/modcluster/DefaultJBossWebEventHandler.java 2008-09-05
14:44:11 UTC (rev 1779)
+++
trunk/mod_cluster/src/main/java/org/jboss/modcluster/DefaultJBossWebEventHandler.java 2008-09-05
14:47:30 UTC (rev 1780)
@@ -30,10 +30,10 @@
import org.apache.catalina.Engine;
import org.apache.catalina.Server;
import org.apache.catalina.Service;
-import org.apache.catalina.core.StandardContext;
import org.apache.catalina.util.StringManager;
import org.jboss.logging.Logger;
import org.jboss.modcluster.advertise.AdvertiseListener;
+import org.jboss.modcluster.advertise.AdvertiseListenerFactory;
import org.jboss.modcluster.config.BalancerConfiguration;
import org.jboss.modcluster.config.MCMPHandlerConfiguration;
import org.jboss.modcluster.config.NodeConfiguration;
@@ -62,7 +62,8 @@
private final BalancerConfiguration balancerConfiguration;
private final MCMPHandler mcmpHandler;
private final LoadBalanceFactorProvider loadBalanceFactorProvider;
-
+ private final AdvertiseListenerFactory listenerFactory;
+
private boolean init;
private AdvertiseListener advertiseListener;
@@ -70,12 +71,13 @@
// ----------------------------------------------------------- Constructors
public DefaultJBossWebEventHandler(NodeConfiguration nodeConfiguration,
BalancerConfiguration balancerConfiguration,
- MCMPHandler mcmpHandler, LoadBalanceFactorProvider loadBalanceFactorProvider)
+ MCMPHandler mcmpHandler, LoadBalanceFactorProvider loadBalanceFactorProvider,
AdvertiseListenerFactory listenerFactory)
{
this.nodeConfiguration = nodeConfiguration;
this.balancerConfiguration = balancerConfiguration;
this.mcmpHandler = mcmpHandler;
this.loadBalanceFactorProvider = loadBalanceFactorProvider;
+ this.listenerFactory = listenerFactory;
}
// ---------------------------------------------------- JBossWebEventHandler
@@ -88,9 +90,19 @@
Boolean advertise = handlerConfig.getAdvertise();
- if (Boolean.TRUE.equals(advertise) || (advertise == null &&
initialProxies.size() == 0))
+ if (Boolean.TRUE.equals(advertise) || (advertise == null &&
initialProxies.isEmpty()))
{
- this.advertiseListener = new AdvertiseListener(this.mcmpHandler);
+ this.advertiseListener = this.listenerFactory.createListener(this.mcmpHandler);
+
+ try
+ {
+ this.advertiseListener.start();
+ }
+ catch (IOException e)
+ {
+ // TODO What now?
+ log.error(e.getMessage(), e);
+ }
}
this.init = true;
@@ -112,16 +124,16 @@
this.checkInit();
Service[] services = server.findServices();
- for (Service service : services)
+ for (Service service: services)
{
Engine engine = (Engine) service.getContainer();
this.config(engine);
Container[] children = engine.findChildren();
- for (Container element : children)
+ for (Container element: children)
{
Container[] children2 = element.findChildren();
- for (Container element2 : children2)
+ for (Container element2: children2)
{
this.addContext((Context) element2);
}
@@ -140,8 +152,11 @@
Service[] services = server.findServices();
for (Service service : services)
{
- this.removeAll((Engine) service.getContainer());
- Container[] children = service.getContainer().findChildren();
+ Engine engine = (Engine) service.getContainer();
+
+ this.removeAll(engine);
+
+ Container[] children = engine.findChildren();
for (Container element : children)
{
Container[] children2 = element.findChildren();
@@ -164,12 +179,13 @@
}
catch (Exception e)
{
+ e.printStackTrace();
this.mcmpHandler.markProxiesInError();
log.info(this.sm.getString("modcluster.error.addressJvmRoute"), e);
return;
}
- MCMPRequest request = MCMPUtils.createConfigRequest(engine,
this.getNodeConfiguration(), this.getBalancerConfiguration());
+ MCMPRequest request = MCMPUtils.createConfigRequest(engine, this.nodeConfiguration,
this.balancerConfiguration);
// Send CONFIG request
this.mcmpHandler.sendRequest(request);
@@ -179,7 +195,7 @@
{
this.checkInit();
- log.debug(this.sm.getString("modcluster.context.enable",
context.getPath(), context.getParent().getName(), ((StandardContext)
context).getState()));
+ log.debug(this.sm.getString("modcluster.context.enable",
context.getPath(), context.getParent().getName()));
// Send ENABLE-APP if state is started
if (context.isStarted())
@@ -215,7 +231,7 @@
{
this.checkInit();
- log.debug(this.sm.getString("modcluster.context.disable",
context.getPath(), context.getParent().getName(), ((StandardContext)
context).getState()));
+ log.debug(this.sm.getString("modcluster.context.disable",
context.getPath(), context.getParent().getName()));
// JVMRoute can be null here if nothing was ever initialized
if (Utils.getJvmRoute(context) != null)
@@ -249,7 +265,7 @@
this.mcmpHandler.status();
// Send STATUS request
- int lbf = this.getLoadBalanceFactorProvider().getLoadBalanceFactor();
+ int lbf = this.loadBalanceFactorProvider.getLoadBalanceFactor();
MCMPRequest request = MCMPUtils.createStatusRequest(engine, lbf);
this.mcmpHandler.sendRequest(request);
}
Modified: trunk/mod_cluster/src/main/java/org/jboss/modcluster/ModClusterService.java
===================================================================
--- trunk/mod_cluster/src/main/java/org/jboss/modcluster/ModClusterService.java 2008-09-05
14:44:11 UTC (rev 1779)
+++ trunk/mod_cluster/src/main/java/org/jboss/modcluster/ModClusterService.java 2008-09-05
14:47:30 UTC (rev 1780)
@@ -46,6 +46,7 @@
import org.jboss.ha.framework.server.HAServiceImpl;
import org.jboss.ha.framework.server.HAServiceRpcHandler;
import org.jboss.ha.framework.server.HASingletonImpl;
+import org.jboss.modcluster.advertise.impl.AdvertiseListenerFactoryImpl;
import org.jboss.modcluster.config.BalancerConfiguration;
import org.jboss.modcluster.config.MCMPHandlerConfiguration;
import org.jboss.modcluster.config.ModClusterConfig;
@@ -151,7 +152,7 @@
// this.localHandler.init();
this.clusteredHandler = new ClusteredMCMPHandlerImpl(this.localHandler, this);
this.loadManager = loadFactorProvider;
- this.eventHandlerDelegate = new DefaultJBossWebEventHandler(config, config,
this.clusteredHandler, loadFactorProvider);
+ this.eventHandlerDelegate = new DefaultJBossWebEventHandler(config, config,
this.clusteredHandler, loadFactorProvider, new AdvertiseListenerFactoryImpl());
this.domain = config.getDomain();
this.masterPerDomain = config.isMasterPerDomain();
@@ -184,6 +185,7 @@
HASingletonAwareResetRequestSource resetRequestSource,
ClusteredMCMPHandler clusteredHandler,
LoadBalanceFactorProvider loadManager,
+ JBossWebEventHandler eventHandler,
HASingletonElectionPolicy electionPolicy)
{
super(new HAServiceEventFactory());
@@ -195,6 +197,7 @@
assert nodeConfig != null :
this.sm.getString("modcluster.error.iae.null", "nodeConfig");
assert balancerConfig != null :
this.sm.getString("modcluster.error.iae.null", "balancerConfig");
assert clusteredHandler != null :
this.sm.getString("modcluster.error.iae.null", "clusteredHandler");
+ assert eventHandler != null :
this.sm.getString("modcluster.error.iae.null", "eventHandler");
this.setHAPartition(partition);
@@ -202,7 +205,7 @@
this.resetRequestSource = resetRequestSource;
this.clusteredHandler = clusteredHandler;
this.loadManager = loadManager;
- this.eventHandlerDelegate = new DefaultJBossWebEventHandler(nodeConfig,
balancerConfig, clusteredHandler, loadManager);
+ this.eventHandlerDelegate = eventHandler;
this.domain = nodeConfig.getDomain();
this.masterPerDomain = mcmpHandlerConfig.isMasterPerDomain();
Deleted:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertiseEventType.java
===================================================================
---
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertiseEventType.java 2008-09-05
14:44:11 UTC (rev 1779)
+++
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertiseEventType.java 2008-09-05
14:47:30 UTC (rev 1780)
@@ -1,62 +0,0 @@
-/*
- *
- * Copyright(c) 2008 Red Hat Middleware, LLC,
- * and individual contributors as indicated by the @authors tag.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library in the file COPYING.LIB;
- * if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- */
-
-package org.jboss.modcluster.advertise;
-
-/**
- * Set what type of event the AdvertiseEvent signals.
- * @param type The type of event. One of:
- * <PRE>
- * ON_NEW_SERVER -- New AdvertisedServer detected
- * ON_STATUS_CHANGE -- AdvertisedServer server changed status
- * </PRE>
- */
-public enum AdvertiseEventType
-{
- /** New AdvertisedServer detected */
- ON_NEW_SERVER( 0),
- /** AdvertisedServer server changed status */
- ON_STATUS_CHANGE( 1);
-
- private int value;
- private AdvertiseEventType(int v)
- {
- value = v;
- }
-
- public int valueOf()
- {
- return value;
- }
-
- public static AdvertiseEventType valueOf(int value)
- {
- for (AdvertiseEventType e : values()) {
- if (e.value == value)
- return e;
- }
- throw new IllegalArgumentException("Invalid initializer: " + value);
- }
-
-}
Modified:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertiseListener.java
===================================================================
---
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertiseListener.java 2008-09-05
14:44:11 UTC (rev 1779)
+++
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertiseListener.java 2008-09-05
14:47:30 UTC (rev 1780)
@@ -1,479 +1,58 @@
/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
*
- * Copyright(c) 2008 Red Hat Middleware, LLC,
- * and individual contributors as indicated by the @authors tag.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library in the file COPYING.LIB;
- * if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
*/
-
package org.jboss.modcluster.advertise;
import java.io.IOException;
-import java.net.DatagramPacket;
-import java.net.InetAddress;
-import java.net.MulticastSocket;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Locale;
-import org.apache.catalina.util.StringManager;
-import org.jboss.logging.Logger;
-import org.jboss.modcluster.config.MCMPHandlerConfiguration;
-import org.jboss.modcluster.mcmp.MCMPHandler;
-import org.jboss.modcluster.Constants;
-
-
-/** AdvertiseListener
- * Listens for Advertise messages from mod_cluster
+/**
+ * @author Paul Ferraro
*
- * @author Mladen Turk
- *
*/
-public class AdvertiseListener
+public interface AdvertiseListener
{
- /** Default port for listening Advertise messages.
- */
- public static int DEFAULT_PORT = 23364;
- /** Default Multicast group address for listening Advertise messages.
- */
- public static String DEFAULT_GROUP = "224.0.1.105";
+ /**
+ * Start the Listener, creating listener thread.
+ */
+ void start() throws IOException;
- private static final Logger log = Logger.getLogger(AdvertiseListener.class);
-
- private static String RFC_822_FMT = "EEE, d MMM yyyy HH:mm:ss Z";
- private int advertisePort = DEFAULT_PORT;
- private String groupAddress = DEFAULT_GROUP;
- private MulticastSocket ms;
- private SimpleDateFormat df;
- private boolean listening = true;
- private boolean initialized = false;
- private boolean running = false;
- private boolean paused = false;
- private boolean daemon = true;
- private byte [] secure = new byte[16];
- private String securityKey = null;
- private MessageDigest md = null;
+ /**
+ * Pause the listener, which will make it stop accepting new advertise
+ * messages.
+ */
+ void pause();
- private HashMap<String, AdvertisedServer> servers;
+ /**
+ * Resume the listener, which will make it start accepting new advertise
+ * messages again.
+ */
+ void resume();
- private MCMPHandler commHandler;
- private Thread workerThread;
-
- /**
- * The string manager for this package.
- */
- private StringManager sm = StringManager.getManager(Constants.Package);
+ /**
+ * Stop the endpoint. This will cause all processing threads to stop.
+ */
+ void stop();
-
- private static void digestString(MessageDigest md, String s)
- {
- int len = s.length();
- byte [] b = new byte[len];
- for (int i = 0; i < len; i++) {
- char c = s.charAt(i);
- if (c < 127)
- b[i] = (byte)c;
- else
- b[i] = '?';
- }
- md.update(b);
- }
-
- /** Create AdvertiseListener instance
- * @param eventHandler The event handler that will be used for
- * status and new server notifications.
- */
- public AdvertiseListener(MCMPHandler commHandler)
- {
- df = new SimpleDateFormat(RFC_822_FMT, Locale.US);
- servers = new HashMap<String, AdvertisedServer>();
- this.commHandler = commHandler;
-
- MCMPHandlerConfiguration config = commHandler.getConfiguration();
-
- if (config.getAdvertiseGroupAddress() != null) {
- setGroupAddress(config.getAdvertiseGroupAddress());
- }
- if (config.getAdvertisePort() > 0) {
- setAdvertisePort(config.getAdvertisePort());
- }
- try {
- if (config.getAdvertiseSecurityKey() != null) {
- setSecurityKey(config.getAdvertiseSecurityKey());
- }
- start();
- } catch (IOException e) {
- log.error(sm.getString("modcluster.error.startListener"), e);
- } catch (NoSuchAlgorithmException e) {
- // Should never happen
- log.error(sm.getString("modcluster.error.startListener"), e);
- }
- }
-
- /**
- * The default is true - the control thread will be
- * in daemon mode. If set to false, the control thread
- * will not be daemon - and will keep the process alive.
- */
- public void setDaemon(boolean b)
- {
- daemon = b;
- }
-
- public boolean getDaemon()
- {
- return daemon;
- }
-
- /** Set Advertise security key
- * @param key The key to use.<br/>
- * Security key must match the AdvertiseKey
- * on the advertised server.
- */
- public void setSecurityKey(String key)
- throws NoSuchAlgorithmException
- {
- securityKey = key;
- if (md == null)
- md = MessageDigest.getInstance("MD5");
- }
-
- /** Set Advertise port
- * @param port The UDP port to use.
- */
- public void setAdvertisePort(int port)
- {
- advertisePort = port;
- }
-
- public int getAdvertisePort()
- {
- return advertisePort;
- }
-
- /** Set Advertise Multicaset group address
- * @param address The IP or host address to use.
- */
- public void setGroupAddress(String address)
- {
- groupAddress = address;
- }
-
- /** Get Advertise Multicaset group address
- */
- public String getGroupAddress()
- {
- return groupAddress;
- }
-
- /** Get Collection of all AdvertisedServer instances.
- */
- public Collection<AdvertisedServer> getServers()
- {
- return servers.values();
- }
-
- /** Get AdvertiseServer server.
- * @param name Server name to get.
- */
- public AdvertisedServer getServer(String name)
- {
- return servers.get(name);
- }
-
- /** Remove the AdvertisedServer from the collection.
- * @param server Server to remove.
- */
- public void removeServer(AdvertisedServer server)
- {
- servers.remove(server);
- }
-
- private void init()
- throws IOException
- {
- ms = new MulticastSocket(advertisePort);
- ms.setTimeToLive(16);
- ms.joinGroup(InetAddress.getByName(groupAddress));
- initialized = true;
- }
-
- private void interruptDatagramReader()
- {
- if (!initialized)
- return;
- try {
- // Restrict to localhost.
- ms.setTimeToLive(0);
- DatagramPacket dp = new DatagramPacket(secure, secure.length,
- InetAddress.getByName(groupAddress),
- advertisePort);
- ms.send(dp);
- } catch (IOException e) {
- // Ignore
- }
- }
-
- /** Start the Listener, creating listener thread.
- */
- public void start()
- throws IOException
- {
- if (!initialized) {
- init();
- }
- if (!running) {
- SecureRandom random = new SecureRandom();
- random.nextBytes(secure);
- secure[0] = 0;
- running = true;
- paused = false;
- listening = true;
- AdvertiseListenerWorker aw = new AdvertiseListenerWorker();
- workerThread = new Thread(aw);
- workerThread.setDaemon(daemon);
- workerThread.start();
- }
- }
-
- /**
- * Pause the listener, which will make it stop accepting new advertise
- * messages.
- */
- public void pause()
- {
- if (running && !paused) {
- paused = true;
- interruptDatagramReader();
- }
- }
-
-
- /**
- * Resume the listener, which will make it start accepting new advertise
- * messages again.
- */
- public void resume()
- {
- if (running && paused) {
- // Genererate new private secure
- SecureRandom random = new SecureRandom();
- random.nextBytes(secure);
- secure[0] = 0;
- paused = false;
- }
- }
-
-
- /**
- * Stop the endpoint. This will cause all processing threads to stop.
- */
- public void stop()
- {
- if (running) {
- running = false;
- interruptDatagramReader();
- workerThread = null;
- }
- }
-
-
- /**
- * Deallocate listener and close sockets.
- */
- public void destroy()
- throws IOException
- {
- if (running) {
- stop();
- }
- if (initialized) {
- ms.leaveGroup(InetAddress.getByName(groupAddress));
- ms.close();
- initialized = false;
- ms = null;
- }
- }
-
- private boolean verifyDigest(String digest, String server, String date)
- {
- if (md == null)
- return true;
- md.reset();
- digestString(md, securityKey);
- digestString(md, date);
- digestString(md, server);
- byte [] our = md.digest();
- byte [] dst = new byte[digest.length() * 2];
- for (int i = 0, j = 0; i < digest.length(); i++) {
- char ch = digest.charAt(i);
- dst[j++] = (byte)((ch >= 'A') ? ((ch & 0xdf) - 'A') +
10 : (ch - '0'));
- }
- return true;
- }
-
- /**
- * True if listener is accepting the advetise messages.<br/>
- * If false it means that listener is experiencing some
- * network problems if running.
- */
- public boolean isListening()
- {
- return listening;
- }
-
-
- // ------------------------------------ AdvertiseListenerWorker Inner Class
- private class AdvertiseListenerWorker implements Runnable
- {
-
- protected AdvertiseListenerWorker()
- {
- // Nothing
- }
- /**
- * The background thread that listens for incoming Advertise packets
- * and hands them off to an appropriate AdvertiseEvent handler.
- */
- public void run() {
- byte[] buffer = new byte[512];
- // Loop until we receive a shutdown command
- while (running) {
- // Loop if endpoint is paused
- while (paused) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // Ignore
- }
- }
- try {
- DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
- ms.receive(dp);
- if (!running)
- break;
- byte [] data = dp.getData();
- boolean intr = false;
- if (dp.getLength() == secure.length) {
- int i;
- for (i = 0; i < secure.length; i++) {
- if (data[i] != secure[i])
- break;
- }
- if (i == secure.length)
- intr = true;
- }
- if (intr)
- continue;
- String s = new String(data, 0, dp.getLength(), "8859_1");
- if (!s.startsWith("HTTP/1."))
- continue;
-
- String [] headers = s.split("\r\n");
- String date_str = null;
- Date date = null;
- int status = 0;
- String status_desc = null;
- String digest = null;
- String server_name = null;
- AdvertisedServer server = null;
- boolean added = false;
- for (int i = 0; i < headers.length; i++) {
- if (i == 0) {
- String [] sline = headers[i].split(" ", 3);
- if (sline == null || sline.length != 3)
- break;
- status = Integer.parseInt(sline[1]);
- if (status < 100)
- break;
- status_desc = sline[2];
- }
- else {
- String [] hdrv = headers[i].split(": ", 2);
- if (hdrv == null || hdrv.length != 2)
- break;
- if (hdrv[0].equals("Date")) {
- date_str = hdrv[1];
- try {
- date = df.parse(date_str);
- } catch (ParseException e) {
- date = new Date();
- }
- }
- else if (hdrv[0].equals("Digest")) {
- digest = hdrv[1];
- }
- else if (hdrv[0].equals("Server")) {
- server_name = hdrv[1];
- server = servers.get(server_name);
- if (server == null) {
- server = new AdvertisedServer(server_name);
- added = true;
- }
- }
- else if (server != null) {
- server.setParameter(hdrv[0], hdrv[1]);
- }
- }
- }
- if (server != null && status > 0) {
- if (md != null) {
- /* We need a digest to match */
- if (!verifyDigest(digest, server_name, date_str)) {
- System.out.println("Digest mismatch");
- continue;
- }
- }
- server.setDate(date);
- boolean rc = server.setStatus(status, status_desc);
- if (added) {
- servers.put(server_name, server);
- // Call the new server callback
- //eventHandler.onEvent(AdvertiseEventType.ON_NEW_SERVER,
server);
- String proxy =
server.getParameter(AdvertisedServer.MANAGER_ADDRESS);
- if (proxy != null) {
- commHandler.addProxy(proxy);
- }
- }
- else if (rc) {
- // Call the status change callback
- //eventHandler.onEvent(AdvertiseEventType.ON_STATUS_CHANGE,
server);
- }
- }
- listening = true;
- } catch (IOException e) {
- // Do not blow the CPU in case of communication error
- listening = false;
- try {
- Thread.sleep(100);
- } catch (InterruptedException x) {
- // Ignore
- }
- }
- }
- }
- }
-
-}
+ /**
+ * Deallocate listener and close sockets.
+ */
+ void destroy() throws IOException;
+}
\ No newline at end of file
Added:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertiseListenerFactory.java
===================================================================
---
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertiseListenerFactory.java
(rev 0)
+++
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertiseListenerFactory.java 2008-09-05
14:47:30 UTC (rev 1780)
@@ -0,0 +1,33 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.modcluster.advertise;
+
+import org.jboss.modcluster.mcmp.MCMPHandler;
+
+/**
+ * @author Paul Ferraro
+ *
+ */
+public interface AdvertiseListenerFactory
+{
+ public AdvertiseListener createListener(MCMPHandler handler);
+}
Deleted:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertisedServer.java
===================================================================
---
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertisedServer.java 2008-09-05
14:44:11 UTC (rev 1779)
+++
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertisedServer.java 2008-09-05
14:47:30 UTC (rev 1780)
@@ -1,122 +0,0 @@
-/*
- *
- * Copyright(c) 2008 Red Hat Middleware, LLC,
- * and individual contributors as indicated by the @authors tag.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library in the file COPYING.LIB;
- * if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- */
-
-package org.jboss.modcluster.advertise;
-
-import java.util.Date;
-import java.util.HashMap;
-
-/**
- * Advertised server instance
- *
- * @author Mladen Turk
- *
- */
-public class AdvertisedServer
-{
- private String server;
- private Date date;
- private int status;
- private String status_desc;
- private HashMap<String, String> headers;
-
- /** Manager-Address header */
- public static String MANAGER_ADDRESS = "X-Manager-Address";
- /** Manager-Url header */
- public static String MANAGER_URL = "X-Manager-Url";
- /** Manager-Protocol header */
- public static String MANAGER_PROTOCOL = "X-Manager-Protocol";
- /** Manager-Version header */
- public static String MANAGER_VERSION = "X-Manager-Version";
- /** Manager-Host header */
- public static String MANAGER_HOST = "X-Manager-Host";
-
- protected AdvertisedServer(String server)
- {
- this.server = server;
- headers = new HashMap<String, String>();
- }
-
- protected boolean setStatus(int status, String desc)
- {
- boolean rv = false;
- status_desc = desc;
- if (this.status == 0 ) {
- // First time
- this.status = status;
- }
- else if (this.status != status) {
- this.status = status;
- rv = true;
- }
- return rv;
- }
-
- /** Set the Date of the last Advertise message
- */
- protected void setDate(Date date)
- {
- this.date = date;
- }
-
- /** Set the Header
- */
- protected void setParameter(String name, String value)
- {
- headers.put(name, value);
- }
-
- /** Get Date of the last Advertise message
- */
- public Date getDate()
- {
- return date;
- }
-
- /** Get Status code of the last Advertise message
- */
- public int getStatusCode()
- {
- return status;
- }
-
- /** Get Status description of the last Advertise message
- */
- public String getStatusDescription()
- {
- return status_desc;
- }
-
- /** Get Advertise parameter
- */
- public String getParameter(String name)
- {
- return headers.get(name);
- }
-
- public String toString()
- {
- return server;
- }
-}
Copied:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseEventType.java
(from rev 1774,
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertiseEventType.java)
===================================================================
---
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseEventType.java
(rev 0)
+++
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseEventType.java 2008-09-05
14:47:30 UTC (rev 1780)
@@ -0,0 +1,63 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.modcluster.advertise.impl;
+
+/**
+ * Set what type of event the AdvertiseEvent signals.
+ * @param type The type of event. One of:
+ * <PRE>
+ * ON_NEW_SERVER -- New AdvertisedServer detected
+ * ON_STATUS_CHANGE -- AdvertisedServer server changed status
+ * </PRE>
+ */
+public enum AdvertiseEventType
+{
+ /** New AdvertisedServer detected */
+ ON_NEW_SERVER(0),
+ /** AdvertisedServer server changed status */
+ ON_STATUS_CHANGE(1);
+
+ private int value;
+
+ private AdvertiseEventType(int v)
+ {
+ this.value = v;
+ }
+
+ public int valueOf()
+ {
+ return this.value;
+ }
+
+ public static AdvertiseEventType valueOf(int value)
+ {
+ for (AdvertiseEventType e : values())
+ {
+ if (e.value == value) return e;
+ }
+
+ throw new IllegalArgumentException("Invalid initializer: " + value);
+ }
+}
Property changes on:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseEventType.java
___________________________________________________________________
Name: svn:mergeinfo
+
Added:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerFactoryImpl.java
===================================================================
---
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerFactoryImpl.java
(rev 0)
+++
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerFactoryImpl.java 2008-09-05
14:47:30 UTC (rev 1780)
@@ -0,0 +1,43 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.modcluster.advertise.impl;
+
+import org.jboss.modcluster.advertise.AdvertiseListener;
+import org.jboss.modcluster.advertise.AdvertiseListenerFactory;
+import org.jboss.modcluster.mcmp.MCMPHandler;
+
+/**
+ * @author Paul Ferraro
+ *
+ */
+public class AdvertiseListenerFactoryImpl implements AdvertiseListenerFactory
+{
+
+ /**
+ * @{inheritDoc}
+ * @see
org.jboss.modcluster.advertise.AdvertiseListenerFactory#createListener(org.jboss.modcluster.mcmp.MCMPHandler)
+ */
+ public AdvertiseListener createListener(MCMPHandler handler)
+ {
+ return new AdvertiseListenerImpl(handler);
+ }
+}
Copied:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerImpl.java
(from rev 1774,
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertiseListener.java)
===================================================================
---
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerImpl.java
(rev 0)
+++
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerImpl.java 2008-09-05
14:47:30 UTC (rev 1780)
@@ -0,0 +1,540 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.modcluster.advertise.impl;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+import java.net.UnknownHostException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.catalina.util.StringManager;
+import org.jboss.logging.Logger;
+import org.jboss.modcluster.Constants;
+import org.jboss.modcluster.advertise.AdvertiseListener;
+import org.jboss.modcluster.config.MCMPHandlerConfiguration;
+import org.jboss.modcluster.mcmp.MCMPHandler;
+
+/**
+ * Listens for Advertise messages from mod_cluster
+ *
+ * @author Mladen Turk
+ *
+ */
+public class AdvertiseListenerImpl implements AdvertiseListener
+{
+ /** Default port for listening Advertise messages. */
+ public static int DEFAULT_PORT = 23364;
+ /** Default Multicast group address for listening Advertise messages. */
+ public static String DEFAULT_GROUP = "224.0.1.105";
+
+ private static final Logger log = Logger.getLogger(AdvertiseListenerImpl.class);
+ private static final String RFC_822_FMT = "EEE, d MMM yyyy HH:mm:ss Z";
+
+ private int advertisePort = DEFAULT_PORT;
+ private InetAddress groupAddress = null;
+
+ MulticastSocket ms;
+
+ private boolean initialized = false;
+ volatile boolean listening = true;
+ final AtomicBoolean running = new AtomicBoolean(false);
+ final AtomicBoolean paused = new AtomicBoolean(false);
+ private boolean daemon = true;
+
+ private final byte[] secure = new byte[16];
+ private String securityKey = null;
+ MessageDigest md = null;
+
+ final Map<String, AdvertisedServer> servers = new HashMap<String,
AdvertisedServer>();
+ final MCMPHandler commHandler;
+
+ private Thread workerThread;
+
+ /**
+ * The string manager for this package.
+ */
+ private StringManager sm = StringManager.getManager(Constants.Package);
+
+ private static void digestString(MessageDigest md, String s)
+ {
+ int len = s.length();
+ byte[] b = new byte[len];
+ for (int i = 0; i < len; i++)
+ {
+ char c = s.charAt(i);
+ if (c < 127)
+ {
+ b[i] = (byte) c;
+ }
+ else
+ {
+ b[i] = '?';
+ }
+ }
+ md.update(b);
+ }
+
+ /**
+ * Create AdvertiseListener instance
+ * @param eventHandler The event handler that will be used for
+ * status and new server notifications.
+ */
+ public AdvertiseListenerImpl(MCMPHandler commHandler)
+ {
+ this.commHandler = commHandler;
+
+ MCMPHandlerConfiguration config = commHandler.getConfiguration();
+
+ try
+ {
+ this.setGroupAddress(config.getAdvertiseGroupAddress());
+ this.setAdvertisePort(config.getAdvertisePort());
+ this.setSecurityKey(config.getAdvertiseSecurityKey());
+ }
+ catch (IOException e)
+ {
+ log.error(this.sm.getString("modcluster.error.startListener"), e);
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ // Should never happen
+ log.error(this.sm.getString("modcluster.error.startListener"), e);
+ }
+ }
+
+ /**
+ * The default is true - the control thread will be
+ * in daemon mode. If set to false, the control thread
+ * will not be daemon - and will keep the process alive.
+ */
+ public void setDaemon(boolean b)
+ {
+ this.daemon = b;
+ }
+
+ public boolean getDaemon()
+ {
+ return this.daemon;
+ }
+
+ /** Set Advertise security key
+ * @param key The key to use.<br/>
+ * Security key must match the AdvertiseKey
+ * on the advertised server.
+ */
+ public void setSecurityKey(String key) throws NoSuchAlgorithmException
+ {
+ this.securityKey = key;
+ if (this.md == null)
+ {
+ this.md = MessageDigest.getInstance("MD5");
+ }
+ }
+
+ /** Set Advertise port
+ * @param port The UDP port to use.
+ */
+ public void setAdvertisePort(int port)
+ {
+ this.advertisePort = (port > 0) ? port : DEFAULT_PORT;
+ }
+
+ public int getAdvertisePort()
+ {
+ return this.advertisePort;
+ }
+
+ /** Set Advertise Multicaset group address
+ * @param address The IP or host address to use.
+ * @throws UnknownHostException
+ */
+ public void setGroupAddress(String address) throws UnknownHostException
+ {
+ this.groupAddress = InetAddress.getByName((address != null) ? address :
DEFAULT_GROUP);
+ }
+
+ /** Get Advertise Multicaset group address
+ */
+ public String getGroupAddress()
+ {
+ return this.groupAddress.getHostAddress();
+ }
+
+ /** Get Collection of all AdvertisedServer instances.
+ */
+ public Collection<AdvertisedServer> getServers()
+ {
+ return this.servers.values();
+ }
+
+ /** Get AdvertiseServer server.
+ * @param name Server name to get.
+ */
+ public AdvertisedServer getServer(String name)
+ {
+ return this.servers.get(name);
+ }
+
+ /** Remove the AdvertisedServer from the collection.
+ * @param server Server to remove.
+ */
+ public void removeServer(AdvertisedServer server)
+ {
+ this.servers.remove(server);
+ }
+
+ private synchronized void init() throws IOException
+ {
+ if (!this.initialized)
+ {
+ this.ms = new MulticastSocket(this.advertisePort);
+ this.ms.setTimeToLive(16);
+ this.ms.joinGroup(this.groupAddress);
+
+ this.initialized = true;
+ }
+ }
+
+ private void interruptDatagramReader()
+ {
+ if (!this.initialized) return;
+
+ try
+ {
+ // Restrict to localhost.
+ this.ms.setTimeToLive(0);
+ DatagramPacket dp = new DatagramPacket(this.secure, this.secure.length,
this.groupAddress, this.advertisePort);
+ this.ms.send(dp);
+ }
+ catch (IOException e)
+ {
+ // Ignore
+ }
+ }
+
+ /**
+ * @{inheritDoc}
+ * @see org.jboss.modcluster.advertise.AdvertiseListener#start()
+ */
+ public void start() throws IOException
+ {
+ this.init();
+
+ if (this.running.compareAndSet(false, true))
+ {
+ SecureRandom random = new SecureRandom();
+
+ synchronized (this.secure)
+ {
+ random.nextBytes(this.secure);
+ this.secure[0] = 0;
+ }
+
+ this.paused.set(false);
+ this.listening = true;
+
+ AdvertiseListenerWorker aw = new AdvertiseListenerWorker();
+ this.workerThread = new Thread(aw);
+ this.workerThread.setDaemon(this.daemon);
+ this.workerThread.start();
+ }
+ }
+
+ /**
+ * @{inheritDoc}
+ * @see org.jboss.modcluster.advertise.AdvertiseListener#pause()
+ */
+ public void pause()
+ {
+ if (this.running.get() && this.paused.compareAndSet(false, true))
+ {
+ this.interruptDatagramReader();
+ }
+ }
+
+ /**
+ * @{inheritDoc}
+ * @see org.jboss.modcluster.advertise.AdvertiseListener#resume()
+ */
+ public void resume()
+ {
+ if (this.running.get() && this.paused.compareAndSet(true, false))
+ {
+ // Genererate new private secure
+ SecureRandom random = new SecureRandom();
+
+ synchronized (this.secure)
+ {
+ random.nextBytes(this.secure);
+ this.secure[0] = 0;
+ }
+ }
+ }
+
+ /**
+ * @{inheritDoc}
+ * @see org.jboss.modcluster.advertise.AdvertiseListener#stop()
+ */
+ public void stop()
+ {
+ if (this.running.compareAndSet(true, false))
+ {
+ this.interruptDatagramReader();
+ this.workerThread = null;
+ }
+ }
+
+ /**
+ * @{inheritDoc}
+ * @see org.jboss.modcluster.advertise.AdvertiseListener#destroy()
+ */
+ public void destroy() throws IOException
+ {
+ this.stop();
+
+ if (this.initialized)
+ {
+ this.ms.leaveGroup(this.groupAddress);
+ this.ms.close();
+ this.initialized = false;
+ this.ms = null;
+ }
+ }
+
+ // TODO This isn't correct - it always returns true!
+ boolean verifyDigest(String digest, String server, String date)
+ {
+ if (this.md == null) return true;
+
+ this.md.reset();
+ digestString(this.md, this.securityKey);
+ digestString(this.md, date);
+ digestString(this.md, server);
+ byte[] our = this.md.digest();
+ byte[] dst = new byte[digest.length() * 2];
+ for (int i = 0, j = 0; i < digest.length(); i++)
+ {
+ char ch = digest.charAt(i);
+ dst[j++] = (byte) ((ch >= 'A') ? ((ch & 0xdf) - 'A') + 10
: (ch - '0'));
+ }
+ return true;
+ }
+
+ /**
+ * True if listener is accepting the advetise messages.<br/>
+ * If false it means that listener is experiencing some
+ * network problems if running.
+ */
+ public boolean isListening()
+ {
+ return this.listening;
+ }
+
+ boolean matchesSecure(DatagramPacket dp)
+ {
+ byte[] data = dp.getData();
+
+ synchronized (this.secure)
+ {
+ if (dp.getLength() != this.secure.length) return false;
+
+ for (int i = 0; i < this.secure.length; i++)
+ {
+ if (data[i] != this.secure[i])
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ // ------------------------------------ AdvertiseListenerWorker Inner Class
+ class AdvertiseListenerWorker implements Runnable
+ {
+ private DateFormat df = new SimpleDateFormat(RFC_822_FMT, Locale.US);
+
+ /**
+ * The background thread that listens for incoming Advertise packets
+ * and hands them off to an appropriate AdvertiseEvent handler.
+ */
+ public void run()
+ {
+ byte[] buffer = new byte[512];
+ // Loop until we receive a shutdown command
+ while (AdvertiseListenerImpl.this.running.get())
+ {
+ // Loop if endpoint is paused
+ while (AdvertiseListenerImpl.this.paused.get())
+ {
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ }
+ try
+ {
+ DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
+ AdvertiseListenerImpl.this.ms.receive(dp);
+ if (!AdvertiseListenerImpl.this.running.get())
+ {
+ break;
+ }
+
+ if (AdvertiseListenerImpl.this.matchesSecure(dp)) continue;
+
+ byte[] data = dp.getData();
+
+ String s = new String(data, 0, dp.getLength(), "8859_1");
+ if (!s.startsWith("HTTP/1."))
+ {
+ continue;
+ }
+
+ String[] headers = s.split("\r\n");
+ String date_str = null;
+ Date date = null;
+ int status = 0;
+ String status_desc = null;
+ String digest = null;
+ String server_name = null;
+ AdvertisedServer server = null;
+ boolean added = false;
+ for (int i = 0; i < headers.length; i++)
+ {
+ if (i == 0)
+ {
+ String[] sline = headers[i].split(" ", 3);
+ if (sline == null || sline.length != 3)
+ {
+ break;
+ }
+ status = Integer.parseInt(sline[1]);
+ if (status < 100)
+ {
+ break;
+ }
+ status_desc = sline[2];
+ }
+ else
+ {
+ String[] hdrv = headers[i].split(": ", 2);
+ if (hdrv == null || hdrv.length != 2)
+ {
+ break;
+ }
+ if (hdrv[0].equals("Date"))
+ {
+ date_str = hdrv[1];
+ try
+ {
+ date = this.df.parse(date_str);
+ }
+ catch (ParseException e)
+ {
+ date = new Date();
+ }
+ }
+ else if (hdrv[0].equals("Digest"))
+ {
+ digest = hdrv[1];
+ }
+ else if (hdrv[0].equals("Server"))
+ {
+ server_name = hdrv[1];
+ server = AdvertiseListenerImpl.this.servers.get(server_name);
+ if (server == null)
+ {
+ server = new AdvertisedServer(server_name);
+ added = true;
+ }
+ }
+ else if (server != null)
+ {
+ server.setParameter(hdrv[0], hdrv[1]);
+ }
+ }
+ }
+ if (server != null && status > 0)
+ {
+ if (AdvertiseListenerImpl.this.md != null)
+ {
+ /* We need a digest to match */
+ if (!AdvertiseListenerImpl.this.verifyDigest(digest, server_name,
date_str))
+ {
+ System.out.println("Digest mismatch");
+ continue;
+ }
+ }
+ server.setDate(date);
+ boolean rc = server.setStatus(status, status_desc);
+ if (added)
+ {
+ AdvertiseListenerImpl.this.servers.put(server_name, server);
+ // Call the new server callback
+ //eventHandler.onEvent(AdvertiseEventType.ON_NEW_SERVER, server);
+ String proxy =
server.getParameter(AdvertisedServer.MANAGER_ADDRESS);
+ if (proxy != null)
+ {
+ AdvertiseListenerImpl.this.commHandler.addProxy(proxy);
+ }
+ }
+ else if (rc)
+ {
+ // Call the status change callback
+ //eventHandler.onEvent(AdvertiseEventType.ON_STATUS_CHANGE,
server);
+ }
+ }
+ AdvertiseListenerImpl.this.listening = true;
+ }
+ catch (IOException e)
+ {
+ // Do not blow the CPU in case of communication error
+ AdvertiseListenerImpl.this.listening = false;
+ Thread.yield();
+ }
+ }
+ }
+ }
+
+}
Property changes on:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertiseListenerImpl.java
___________________________________________________________________
Name: svn:mergeinfo
+
Copied:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertisedServer.java
(from rev 1774,
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/AdvertisedServer.java)
===================================================================
---
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertisedServer.java
(rev 0)
+++
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertisedServer.java 2008-09-05
14:47:30 UTC (rev 1780)
@@ -0,0 +1,123 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.modcluster.advertise.impl;
+
+import java.util.Date;
+import java.util.HashMap;
+
+/**
+ * Advertised server instance
+ *
+ * @author Mladen Turk
+ */
+public class AdvertisedServer
+{
+ /** Manager-Address header */
+ public static String MANAGER_ADDRESS = "X-Manager-Address";
+ /** Manager-Url header */
+ public static String MANAGER_URL = "X-Manager-Url";
+ /** Manager-Protocol header */
+ public static String MANAGER_PROTOCOL = "X-Manager-Protocol";
+ /** Manager-Version header */
+ public static String MANAGER_VERSION = "X-Manager-Version";
+ /** Manager-Host header */
+ public static String MANAGER_HOST = "X-Manager-Host";
+
+ private String server;
+ private Date date;
+ private int status;
+ private String status_desc;
+ private HashMap<String, String> headers = new HashMap<String, String>();
+
+ protected AdvertisedServer(String server)
+ {
+ this.server = server;
+ }
+
+ protected boolean setStatus(int status, String desc)
+ {
+ boolean rv = false;
+ this.status_desc = desc;
+ if (this.status == 0)
+ {
+ // First time
+ this.status = status;
+ }
+ else if (this.status != status)
+ {
+ this.status = status;
+ rv = true;
+ }
+ return rv;
+ }
+
+ /** Set the Date of the last Advertise message
+ */
+ protected void setDate(Date date)
+ {
+ this.date = date;
+ }
+
+ /** Set the Header
+ */
+ protected void setParameter(String name, String value)
+ {
+ this.headers.put(name, value);
+ }
+
+ /** Get Date of the last Advertise message
+ */
+ public Date getDate()
+ {
+ return this.date;
+ }
+
+ /** Get Status code of the last Advertise message
+ */
+ public int getStatusCode()
+ {
+ return this.status;
+ }
+
+ /** Get Status description of the last Advertise message
+ */
+ public String getStatusDescription()
+ {
+ return this.status_desc;
+ }
+
+ /** Get Advertise parameter
+ */
+ public String getParameter(String name)
+ {
+ return this.headers.get(name);
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.server;
+ }
+}
Property changes on:
trunk/mod_cluster/src/main/java/org/jboss/modcluster/advertise/impl/AdvertisedServer.java
___________________________________________________________________
Name: svn:mergeinfo
+