[jboss-cvs] JBossAS SVN: r87971 - in projects/bootstrap/trunk: impl-base/src/main/java/org/jboss/bootstrap/impl/base/server and 4 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Wed Apr 29 00:13:43 EDT 2009
Author: ALRubinger
Date: 2009-04-29 00:13:43 -0400 (Wed, 29 Apr 2009)
New Revision: 87971
Added:
projects/bootstrap/trunk/impl-base/src/test/java/org/jboss/bootstrap/impl/base/server/TestNoOpServerMBean.java
projects/bootstrap/trunk/impl-base/src/test/java/org/jboss/bootstrap/impl/base/server/unit/JmxNotificationsTestCase.java
Modified:
projects/bootstrap/trunk/impl-as/src/main/java/org/jboss/bootstrap/impl/as/server/JBossASServer.java
projects/bootstrap/trunk/impl-base/src/main/java/org/jboss/bootstrap/impl/base/server/AbstractServer.java
projects/bootstrap/trunk/impl-base/src/test/java/org/jboss/bootstrap/impl/base/server/TestNoOpServer.java
projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/lifecycle/LifecycleState.java
projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/Server.java
Log:
[JBBOOT-53] Fire JMX start/stop events in server lifecycle
Modified: projects/bootstrap/trunk/impl-as/src/main/java/org/jboss/bootstrap/impl/as/server/JBossASServer.java
===================================================================
--- projects/bootstrap/trunk/impl-as/src/main/java/org/jboss/bootstrap/impl/as/server/JBossASServer.java 2009-04-29 02:11:13 UTC (rev 87970)
+++ projects/bootstrap/trunk/impl-as/src/main/java/org/jboss/bootstrap/impl/as/server/JBossASServer.java 2009-04-29 04:13:43 UTC (rev 87971)
@@ -39,12 +39,10 @@
*/
public interface JBossASServer extends MCBasedServer<JBossASServer, JBossASServerConfig>
{
- /** The JMX notification event type sent on end of server startup */
- public final String START_NOTIFICATION_TYPE = "org.jboss.system.server.started";
+ //-------------------------------------------------------------------------------------||
+ // Contracts --------------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
- /** The JMX notification event type sent on begin of the server shutdown */
- public final String STOP_NOTIFICATION_TYPE = "org.jboss.system.server.stopped";
-
/** @return The server start date */
Date getStartDate();
Modified: projects/bootstrap/trunk/impl-base/src/main/java/org/jboss/bootstrap/impl/base/server/AbstractServer.java
===================================================================
--- projects/bootstrap/trunk/impl-base/src/main/java/org/jboss/bootstrap/impl/base/server/AbstractServer.java 2009-04-29 02:11:13 UTC (rev 87970)
+++ projects/bootstrap/trunk/impl-base/src/main/java/org/jboss/bootstrap/impl/base/server/AbstractServer.java 2009-04-29 04:13:43 UTC (rev 87971)
@@ -30,6 +30,10 @@
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
+import javax.management.Notification;
+import javax.management.NotificationBroadcaster;
+import javax.management.NotificationBroadcasterSupport;
+
import org.jboss.bootstrap.spi.Bootstrap;
import org.jboss.bootstrap.spi.config.ConfigurationInitializer;
import org.jboss.bootstrap.spi.config.ConfigurationValidator;
@@ -45,12 +49,14 @@
/**
* AbstractServer
*
- * Generic support for
+ * Generic support for Server implementations
*
* @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
* @version $Revision: $
*/
-public abstract class AbstractServer<K extends Server<K, T>, T extends ServerConfig<T>> implements Server<K, T>
+public abstract class AbstractServer<K extends Server<K, T>, T extends ServerConfig<T>>
+ extends
+ NotificationBroadcasterSupport implements Server<K, T>, NotificationBroadcaster
{
//-------------------------------------------------------------------------------------||
@@ -73,7 +79,7 @@
* Underlying configuration. Must be a Thread-safe implementation
* as it's exported
*/
- private T configuration;
+ private volatile T configuration;
/**
* Validator for the configuration. Synchronized on "this". Requires
@@ -83,15 +89,17 @@
/**
* Initializer for the configuration. Synchronized on "this". Requires
- * Thread-safe impl (as it's exported)
+ * Thread-safe impl (as it's exported). Volatile for immediate
+ * accessor return.
*/
- private ConfigurationInitializer<T> configInitializer;
+ private volatile ConfigurationInitializer<T> configInitializer;
/**
* Server initializer. Synchronized on "this". Requires
- * Thread-safe impl (as it's exported)
+ * Thread-safe impl (as it's exported). Volatile for immediate
+ * accessor return.
*/
- private ServerInitializer<K, T> serverInitializer;
+ private volatile ServerInitializer<K, T> serverInitializer;
/**
* The list of bootstraps to run upon start, requires Thread-safe impl.
@@ -169,15 +177,9 @@
// Set properties
this.setConfiguration(configToSet);
- try
- {
- this.setState(LifecycleState.PRE_INIT);
- }
- catch (final LifecycleEventException e)
- {
- // No handlers can be registered yet (this is still construction),
- // so we can safely ignore lifecycle event problems
- }
+ // Set the state directly (ie. bypass callback contract of setState()),
+ // this isn't *really* a state change so much as an initialization
+ this.state = LifecycleState.PRE_INIT;
}
//-------------------------------------------------------------------------------------||
@@ -195,7 +197,9 @@
/* (non-Javadoc)
* @see org.jboss.bootstrap.spi.server.Server#setConfiguration(org.jboss.bootstrap.spi.config.ServerConfig)
*/
- public void setConfiguration(final T configuration)
+ // Synchronized on "this" to ensure we don't set the config in the middle of some
+ // other lifecycle operation
+ public synchronized void setConfiguration(final T configuration)
{
// Log and set
if (log.isTraceEnabled())
@@ -221,6 +225,7 @@
/* (non-Javadoc)
* @see org.jboss.bootstrap.spi.server.Server#shutdown()
*/
+ // Synchronized for atomicity
public synchronized void shutdown() throws IllegalStateException, Exception
{
// Log
@@ -263,14 +268,21 @@
serverInitializer.cleanup(this);
}
- // Done
+ // Send JMX Notification
+ this.sendStopJmxNotification();
+
+ // Done and set states
log.info("Stopped: " + this);
+ // So we fire "stopped" events and draw the difference
+ // between IDLE (which may also designate pre-start)
+ this.setState(LifecycleState.STOPPED);
this.setState(LifecycleState.IDLE);
}
/* (non-Javadoc)
* @see org.jboss.bootstrap.spi.server.Server#start()
*/
+ // Synchronized for atomicity
public synchronized void start() throws IllegalStateException, Exception
{
// Log
@@ -309,6 +321,9 @@
}
this.startBootstraps();
+ // Send JMX Start Notification
+ this.sendStartJmxNotification();
+
// Done
log.info("Started: " + this);
this.setState(LifecycleState.STARTED);
@@ -356,6 +371,7 @@
/* (non-Javadoc)
* @see org.jboss.bootstrap.spi.server.Server#initialize()
*/
+ // Synchronized for atomicity
public synchronized void initialize() throws IllegalStateException, InvalidConfigurationException,
LifecycleEventException
{
@@ -428,7 +444,7 @@
/* (non-Javadoc)
* @see org.jboss.bootstrap.spi.server.Server#getInitializer()
*/
- public synchronized final ServerInitializer<K, T> getServerInitializer()
+ public final ServerInitializer<K, T> getServerInitializer()
{
return this.serverInitializer;
}
@@ -449,7 +465,7 @@
/* (non-Javadoc)
* @see org.jboss.bootstrap.spi.server.Server#getConfigInitializer()
*/
- public synchronized final ConfigurationInitializer<T> getConfigInitializer()
+ public final ConfigurationInitializer<T> getConfigInitializer()
{
return this.configInitializer;
}
@@ -608,6 +624,38 @@
//-------------------------------------------------------------------------------------||
/**
+ * Sends the JMX Notification with type signaling the start of the server
+ */
+ protected void sendStartJmxNotification()
+ {
+ this.sendNotificationWithCurrentTimeUserData(START_NOTIFICATION_TYPE, 1);
+ }
+
+ /**
+ * Sends the JMX Notification with type signaling the stop of the server
+ */
+ protected void sendStopJmxNotification()
+ {
+ this.sendNotificationWithCurrentTimeUserData(STOP_NOTIFICATION_TYPE, 2);
+ }
+
+ /**
+ * Sends a JMX Notification with specified type and sequence number,
+ * setting user data to the number of milliseconds since the epoch.
+ *
+ * @param type
+ * @param sequenceNumber
+ */
+ protected final void sendNotificationWithCurrentTimeUserData(final String type, final int sequenceNumber)
+ {
+ // Send JMX Notification
+ final Notification startNotification = new Notification(type, this, sequenceNumber);
+ startNotification.setUserData(System.currentTimeMillis());
+ this.sendNotification(startNotification);
+ log.debug("Sent JMX Notification: " + type);
+ }
+
+ /**
* Starts the bootstraps
*
* @throws Exception
@@ -634,13 +682,13 @@
final List<Bootstrap> startedBootstraps = this.getStartedBootstraps();
// Signal
- for (Bootstrap bootstrap : startedBootstraps)
+ for (final Bootstrap bootstrap : startedBootstraps)
{
bootstrap.prepareShutdown(this);
}
// Do the bootstraps in reverse order
- for (Bootstrap bootstrap : startedBootstraps)
+ for (final Bootstrap bootstrap : startedBootstraps)
{
try
{
@@ -721,7 +769,7 @@
* @throws InvalidConfigurationException If the configuration is invalid
* @throws IllegalArgumentException If the confirguation has not been set
*/
- private void validate(T configuration) throws InvalidConfigurationException, IllegalArgumentException
+ private void validate(final T configuration) throws InvalidConfigurationException, IllegalArgumentException
{
// Precondition check
if (configuration == null)
@@ -730,7 +778,7 @@
}
// Get the validator
- ConfigurationValidator<T> validator = this.getValidator();
+ final ConfigurationValidator<T> validator = this.getValidator();
// Is specified, validate
if (validator != null)
Modified: projects/bootstrap/trunk/impl-base/src/test/java/org/jboss/bootstrap/impl/base/server/TestNoOpServer.java
===================================================================
--- projects/bootstrap/trunk/impl-base/src/test/java/org/jboss/bootstrap/impl/base/server/TestNoOpServer.java 2009-04-29 02:11:13 UTC (rev 87970)
+++ projects/bootstrap/trunk/impl-base/src/test/java/org/jboss/bootstrap/impl/base/server/TestNoOpServer.java 2009-04-29 04:13:43 UTC (rev 87971)
@@ -36,7 +36,8 @@
*/
public class TestNoOpServer extends AbstractServer<TestNoOpServer, TestServerConfig>
implements
- Server<TestNoOpServer, TestServerConfig>
+ Server<TestNoOpServer, TestServerConfig>,
+ TestNoOpServerMBean
{
//-------------------------------------------------------------------------------------||
Added: projects/bootstrap/trunk/impl-base/src/test/java/org/jboss/bootstrap/impl/base/server/TestNoOpServerMBean.java
===================================================================
--- projects/bootstrap/trunk/impl-base/src/test/java/org/jboss/bootstrap/impl/base/server/TestNoOpServerMBean.java (rev 0)
+++ projects/bootstrap/trunk/impl-base/src/test/java/org/jboss/bootstrap/impl/base/server/TestNoOpServerMBean.java 2009-04-29 04:13:43 UTC (rev 87971)
@@ -0,0 +1,37 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, 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.bootstrap.impl.base.server;
+
+/**
+ * TestNoOpServerMBean
+ *
+ * Interface to meet JMX standard for registry of the
+ * {@link TestNoOpServer} with an MBean Server
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface TestNoOpServerMBean
+{
+ // Marker only
+}
Added: projects/bootstrap/trunk/impl-base/src/test/java/org/jboss/bootstrap/impl/base/server/unit/JmxNotificationsTestCase.java
===================================================================
--- projects/bootstrap/trunk/impl-base/src/test/java/org/jboss/bootstrap/impl/base/server/unit/JmxNotificationsTestCase.java (rev 0)
+++ projects/bootstrap/trunk/impl-base/src/test/java/org/jboss/bootstrap/impl/base/server/unit/JmxNotificationsTestCase.java 2009-04-29 04:13:43 UTC (rev 87971)
@@ -0,0 +1,188 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, 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.bootstrap.impl.base.server.unit;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.MBeanServer;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+
+import junit.framework.TestCase;
+
+import org.jboss.bootstrap.impl.base.server.TestNoOpServer;
+import org.jboss.bootstrap.spi.server.Server;
+import org.jboss.logging.Logger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * JmxNotificationsTestCase
+ *
+ * Tests to ensure that the JMX Notifications for
+ * start/stop are received
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class JmxNotificationsTestCase
+{
+ //-------------------------------------------------------------------------------------||
+ // Class Members ----------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ private static final Logger log = Logger.getLogger(JmxNotificationsTestCase.class);
+
+ /**
+ * JMX Object Name of the test server
+ */
+ private static final String OBJECT_NAME_TEST_SERVER = "org.jboss:type=TestServer";
+
+ //-------------------------------------------------------------------------------------||
+ // Instance Members -------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * The Server
+ */
+ private TestNoOpServer server;
+
+ /**
+ * Whether or not we got the start notification
+ */
+ private boolean gotStartNotification;
+
+ /**
+ * Whether or not we got the stop notification
+ */
+ private boolean gotStopNotification;
+
+ //-------------------------------------------------------------------------------------||
+ // Lifecycle --------------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Initializes the test server, MBean server, and registers
+ * our test event listener
+ */
+ @Before
+ public void init() throws Throwable
+ {
+ // Make and set the test server
+ final TestNoOpServer server = new TestNoOpServer();
+ this.server = server;
+
+ // Make and set the MBean Server
+ final MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
+
+ // Install the test server into the MBean server
+ final ObjectName serverName = new ObjectName(OBJECT_NAME_TEST_SERVER);
+ mbeanServer.registerMBean(server, serverName);
+
+ // Register a listener
+ final NotificationListener listener = new JmxNotificationListener();
+ mbeanServer.addNotificationListener(serverName, listener, null, null);
+ }
+
+ @After
+ public void cleanup() throws Throwable
+ {
+ // Reset everything
+ this.gotStartNotification = false;
+ this.server = null;
+ }
+
+ //-------------------------------------------------------------------------------------||
+ // Tests ------------------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Ensures that the JMX Notifications for start and stop
+ * were fired
+ */
+ @Test
+ public void testJmxNotifications() throws Throwable
+ {
+ // Log
+ log.info("testJmxNotifications");
+
+ // Get the server
+ final TestNoOpServer server = this.server;
+
+ // Start the server
+ server.start();
+
+ // Test
+ TestCase.assertTrue("Did not receive start notification", this.gotStartNotification);
+
+ // Stop the server
+ server.shutdown();
+
+ // Test
+ TestCase.assertTrue("Did not receive stop notification", this.gotStopNotification);
+
+ }
+
+ //-------------------------------------------------------------------------------------||
+ // Inner Classes ----------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Listens for JMX Notification events
+ */
+ private class JmxNotificationListener implements NotificationListener
+ {
+ //-------------------------------------------------------------------------------------||
+ // Required Implementations -----------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /* (non-Javadoc)
+ * @see javax.management.NotificationListener#handleNotification(javax.management.Notification, java.lang.Object)
+ */
+ public void handleNotification(final Notification notification, final Object handback)
+ {
+ // Log
+ log.info("Got notification: " + notification);
+ log.debug("Notification handback: " + handback);
+
+ // Figure out the notification received
+ final String type = notification.getType();
+
+ // Take appropriate action
+ if (Server.START_NOTIFICATION_TYPE.equals(type))
+ {
+ // Set received
+ gotStartNotification = true;
+ }
+ else if (Server.STOP_NOTIFICATION_TYPE.equals(type))
+ {
+ // Set received
+ gotStopNotification = true;
+ }
+
+ }
+ }
+
+}
Modified: projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/lifecycle/LifecycleState.java
===================================================================
--- projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/lifecycle/LifecycleState.java 2009-04-29 02:11:13 UTC (rev 87970)
+++ projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/lifecycle/LifecycleState.java 2009-04-29 04:13:43 UTC (rev 87971)
@@ -28,10 +28,11 @@
* Describes current state of the Server lifecycle
*
* PREINIT == Instanciated, open to configuration, mutable operations permitted
- * IDLE == Not yet started, or has stopped. Awaiting start.
+ * IDLE == Not yet started, or has previously stopped. Awaiting start.
* STARTING == In start lifecycle
* STARTED == Fully started, in service
* STOPPING == In stop lifecycle
+ * STOPPED == Transition state to denote fully stopped before returning to IDLE
*
* @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
* @version $Revision: $
@@ -42,5 +43,5 @@
* Lifecycle States for Servers
*/
- PRE_INIT, IDLE, STARTING, STARTED, STOPPING
+ PRE_INIT, IDLE, STARTING, STARTED, STOPPING, STOPPED
}
Modified: projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/Server.java
===================================================================
--- projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/Server.java 2009-04-29 02:11:13 UTC (rev 87970)
+++ projects/bootstrap/trunk/spi/src/main/java/org/jboss/bootstrap/spi/server/Server.java 2009-04-29 04:13:43 UTC (rev 87971)
@@ -43,7 +43,20 @@
*/
public interface Server<K extends Server<K, T>, T extends ServerConfig<T>>
{
+ //-------------------------------------------------------------------------------------||
+ // Constants --------------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+ /**
+ * The JMX notification event type sent on end of server startup
+ */
+ public final String START_NOTIFICATION_TYPE = "org.jboss.system.server.started";
+
+ /**
+ * The JMX notification event type sent on begin of the server shutdown
+ */
+ public final String STOP_NOTIFICATION_TYPE = "org.jboss.system.server.stopped";
+
//-------------------------------------------------------------------------------------||
// Contracts --------------------------------------------------------------------------||
//-------------------------------------------------------------------------------------||
More information about the jboss-cvs-commits
mailing list