You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by da...@apache.org on 2003/08/17 01:16:18 UTC
cvs commit: incubator-geronimo/modules/core/src/java/org/apache/geronimo/common StartException.java J2EENotification.java AbstractRPCContainer.java AbstractStateManageable.java AbstractContainer.java State.java AbstractComponent.java StateManageable.java
dain 2003/08/16 16:16:18
Modified: modules/core/src/java/org/apache/geronimo/common
AbstractRPCContainer.java
AbstractStateManageable.java AbstractContainer.java
State.java AbstractComponent.java
StateManageable.java
Added: modules/core/src/java/org/apache/geronimo/common
StartException.java J2EENotification.java
Log:
Initial revision of deployment dependency management system.
Revision Changes Path
1.2 +91 -132 incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/AbstractRPCContainer.java
Index: AbstractRPCContainer.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/AbstractRPCContainer.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AbstractRPCContainer.java 15 Aug 2003 14:11:26 -0000 1.1
+++ AbstractRPCContainer.java 16 Aug 2003 23:16:18 -0000 1.2
@@ -6,138 +6,97 @@
import java.util.ListIterator;
import java.util.Map;
import javax.management.ObjectName;
+
/**
- * AbstractRPCContainer.java
- *
- * Base class for a Container that can be remotely invoked.
- *
+ * Base class for a Container that can be accecpt invocation.
*
- *
* @version $Revision$ $Date$
*/
-public class AbstractRPCContainer
- extends AbstractContainer
- implements RPCContainer {
-
- protected final Map plugins = new LinkedHashMap();
- protected final Map pluginObjects = new LinkedHashMap();
- protected final LinkedList interceptors = new LinkedList();
- // for efficency keep a reference to the first interceptor
- protected Interceptor firstInterceptor;
-
- /**
- * Begin the invocation chain.
- *
- * @todo Check that invoke() is illegal unless Container has started
- * @param invocation
- * @return InvocationResult
- * @exception Exception if an error occurs
- */
- public InvocationResult invoke(Invocation invocation) throws Exception {
-
- if (getStateInstance() != State.RUNNING)
- throw new IllegalStateException("invoke can only be called after the Container has started");
-
- return firstInterceptor.invoke(invocation);
- }
-
- /**
- * Add a Component to this Container.
- *
- * @param component a <code>Component</code> value
- */
- public void addComponent(Component component) {
- if (component == null)
- return;
-
- if (component instanceof Interceptor) {
- addInterceptor((Interceptor) component);
- return;
- }
-
- //Is there a type for Plugins?
-
- throw new IllegalStateException(
- "Cannot add component of type "
- + component.getClass()
- + " to an RPCContainer");
- }
-
- /**
- * Add an Interceptor to the end of the Interceptor list.
- *
- * @todo Can interceptors be added after the Container is started?
- * @param interceptor
- */
- public void addInterceptor(Interceptor interceptor) {
-
- if (getStateInstance() != State.STOPPED)
- throw new IllegalStateException("Interceptors cannot be added unless the Container is stopped");
-
- if (firstInterceptor == null) {
- firstInterceptor = interceptor;
- interceptors.addLast(interceptor);
- } else {
- Interceptor lastInterceptor = (Interceptor) interceptors.getLast();
- lastInterceptor.setNext(interceptor);
- interceptors.addLast(interceptor);
- }
-
- super.addComponent(interceptor);
- }
-
- public ObjectName getPlugin(String logicalPluginName) {
- return (ObjectName) plugins.get(logicalPluginName);
- }
-
- public void putPlugin(String logicalPluginName, ObjectName objectName) {
- if (getStateInstance() != State.STOPPED) {
- throw new IllegalStateException(
- "putPluginObject can only be called while in the stopped state: state="
- + getState());
- }
- plugins.put(logicalPluginName, objectName);
- }
-
- public Object getPluginObject(String logicalPluginName) {
- return pluginObjects.get(logicalPluginName);
- }
-
- public void putPluginObject(String logicalPluginName, Object plugin) {
- if (getStateInstance() != State.STOPPED) {
- throw new IllegalStateException(
- "putPluginObject can only be called while in the not-created or destroyed states: state="
- + getState());
- }
- pluginObjects.put(logicalPluginName, plugin);
- }
-
-
-
- /**
- * Start the Container
- * The Interceptors will be handled by
- * @exception Exception if an error occurs
- */
- public void doStart() throws Exception {
- // Start all the Plugins in forward insertion order
- for (Iterator iterator = pluginObjects.values().iterator();iterator.hasNext();) {
- Object object = iterator.next();
- // TODO Start the plugin - are these Components also maybe they should just be StateManageable
- }
- }
-
- /**
- * Stop the container
- *
- */
- public void doStop() {
- // Stop all the plugins in reverse insertion order
- LinkedList list = new LinkedList();
- for (Iterator iterator = pluginObjects.values().iterator();iterator.hasNext();) {
- Object object = iterator.next();
- //TODO work out what has to be done to stop a Plugin
- }
- }
-
-} // AbstractRPCContainer
+public class AbstractRPCContainer extends AbstractContainer implements RPCContainer {
+ // @todo access to these objects must be synchronized
+ private final Map plugins = new LinkedHashMap();
+ private final Map pluginObjects = new LinkedHashMap();
+ private final LinkedList interceptors = new LinkedList();
+ private Interceptor firstInterceptor;
+
+ public void postDeregister() {
+ plugins.clear();
+ pluginObjects.clear();
+ interceptors.clear();
+ firstInterceptor = null;
+ super.postDeregister();
+ }
+
+ public final InvocationResult invoke(Invocation invocation) throws Exception {
+ if (getStateInstance() != State.RUNNING) {
+ throw new IllegalStateException("invoke can only be called after the Container has started");
+ }
+ return firstInterceptor.invoke(invocation);
+ }
+
+ /**
+ * Add a Component to this Container.
+ *
+ * @param component a <code>Component</code> value
+ */
+ public final void addComponent(Component component) {
+ if (component == null) {
+ return;
+ }
+
+ if (component instanceof Interceptor) {
+ addInterceptor((Interceptor) component);
+ return;
+ }
+
+ throw new IllegalStateException("Cannot add component of type " + component.getClass() + " to an RPCContainer");
+ }
+
+ /**
+ * Add an Interceptor to the end of the Interceptor list.
+ *
+ * @param interceptor
+ */
+ public final void addInterceptor(Interceptor interceptor) {
+ if (getStateInstance() != State.STOPPED) {
+ throw new IllegalStateException("Interceptors cannot be added unless the Container is stopped");
+ }
+
+ if (firstInterceptor == null) {
+ firstInterceptor = interceptor;
+ interceptors.addLast(interceptor);
+ } else {
+ Interceptor lastInterceptor = (Interceptor) interceptors.getLast();
+ lastInterceptor.setNext(interceptor);
+ interceptors.addLast(interceptor);
+ }
+
+ super.addComponent(interceptor);
+ }
+
+ public final ObjectName getPlugin(String logicalPluginName) {
+ return (ObjectName) plugins.get(logicalPluginName);
+ }
+
+ public final void putPlugin(String logicalPluginName, ObjectName objectName) {
+ if (getStateInstance() != State.STOPPED) {
+ throw new IllegalStateException(
+ "putPluginObject can only be called while in the stopped state: state="
+ + getState());
+ }
+ plugins.put(logicalPluginName, objectName);
+ }
+
+ public final Object getPluginObject(String logicalPluginName) {
+ return pluginObjects.get(logicalPluginName);
+ }
+
+ public final void putPluginObject(String logicalPluginName, Object plugin) {
+ if (getStateInstance() != State.STOPPED) {
+ throw new IllegalStateException(
+ "putPluginObject can only be called while in the not-created or destroyed states: state="
+ + getState());
+ }
+ pluginObjects.put(logicalPluginName, plugin);
+ }
+}
1.3 +349 -164 incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/AbstractStateManageable.java
Index: AbstractStateManageable.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/AbstractStateManageable.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- AbstractStateManageable.java 15 Aug 2003 14:11:26 -0000 1.2
+++ AbstractStateManageable.java 16 Aug 2003 23:16:18 -0000 1.3
@@ -55,216 +55,401 @@
*/
package org.apache.geronimo.common;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerNotification;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationFilterSupport;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.relation.InvalidRelationIdException;
+import javax.management.relation.InvalidRoleValueException;
+import javax.management.relation.RelationNotFoundException;
+import javax.management.relation.RelationServiceMBean;
+import javax.management.relation.RelationServiceNotRegisteredException;
+import javax.management.relation.RelationTypeNotFoundException;
+import javax.management.relation.Role;
+import javax.management.relation.RoleInfo;
+import javax.management.relation.RoleList;
+import javax.management.relation.RoleNotFoundException;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.geronimo.deployment.dependency.DependencyServiceMBean;
+import org.apache.geronimo.deployment.service.MBeanRelationship;
+import org.apache.geronimo.jmx.JMXUtil;
/**
* Abstract implementation of JSR77 StateManageable.
- * Implementors of StateManageable may use this class and simply provide
+ * Implementors of StateManageable may use this class and simply provide
* doStart, doStop and doNotification methods.
*
* @version $Revision$ $Date$
*/
-public abstract class AbstractStateManageable implements StateManageable
-{
- protected Log log= LogFactory.getLog(getClass());
-
- private State state= State.STOPPED;
+public abstract class AbstractStateManageable extends NotificationBroadcasterSupport implements StateManageable, NotificationListener, MBeanRegistration {
+ protected Log log = LogFactory.getLog(getClass());
+ protected MBeanServer server;
+ protected ObjectName objectName;
+
+ private DependencyServiceMBean dependencyService;
+ private RelationServiceMBean relationService;
+ private long sequenceNumber;
+ private State state = State.STOPPED;
private long startTime;
/**
- * Do the start tasks for the component. Called in the STARTING state by
- * the start() and startRecursive() methods to perform the tasks required to
+ * Do the start tasks for the component. Called in the STARTING state by
+ * the start() and startRecursive() methods to perform the tasks required to
* start the component.
* @throws Exception
*/
- public abstract void doStart() throws Exception;
-
+ protected abstract void doStart() throws Exception;
+
/**
* Do the stop tasks for the component. Called in the STOPPING state by the stop()
* method to perform the tasks required to stop the component.
* @throws Exception
*/
- public abstract void doStop() throws Exception;
-
- /**
- * Do the notification of a state change.
- * @param eventTypeValue Event to notify
- */
- public abstract void doNotification(String eventTypeValue);
+ protected abstract void doStop() throws Exception;
+ public MBeanNotificationInfo[] getNotificationInfo() {
+ return new MBeanNotificationInfo[]{
+ new MBeanNotificationInfo(J2EENotification.TYPES,
+ "javax.management.Notification",
+ "J2EE Notifications")
+ };
+ }
+ public ObjectName preRegister(MBeanServer server, ObjectName objectName) throws Exception {
+ this.server = server;
+ this.objectName = objectName;
+ dependencyService = JMXUtil.getDependencyService(server);
+ relationService = JMXUtil.getRelationService(server);
+
+ NotificationFilterSupport filter = new NotificationFilterSupport();
+ filter.enableType(MBeanServerNotification.REGISTRATION_NOTIFICATION);
+ filter.enableType(MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
+ server.addNotificationListener(JMXUtil.DELEGATE_NAME, this, filter, null);
- /* (non-Javadoc)
- * @see org.apache.geronimo.common.StateManageable#getStateInstance()
- */
- public State getStateInstance()
- {
- return state;
- }
-
- /* (non-Javadoc)
- * @see org.apache.geronimo.common.StateManageable#getState()
- */
- public int getState()
- {
- return state.toInt();
+ return objectName;
}
- /**
- * Set the Component state.
- * @param newState
- * @throws IllegalStateException Thrown if the transition is not supported by the JSR77 lifecycle.
- */
- protected void setState(State newState) throws IllegalStateException
- {
- State oldState = state;
-
- switch (state.toInt())
- {
- case State.STOPPED_INDEX :
- {
- switch (newState.toInt())
- {
- case State.STARTING_INDEX :
- break;
- case State.STOPPED_INDEX :
- case State.RUNNING_INDEX :
- case State.STOPPING_INDEX :
- case State.FAILED_INDEX :
- throw new IllegalStateException(
- "Can not transition to " + newState + " state from " + state);
- }
- break;
- }
+ public void postRegister(Boolean aBoolean) {
+ }
- case State.STARTING_INDEX :
- {
- switch (newState.toInt())
- {
- case State.RUNNING_INDEX :
- case State.FAILED_INDEX :
- case State.STOPPING_INDEX :
- break;
- case State.STOPPED_INDEX :
- case State.STARTING_INDEX :
- throw new IllegalStateException(
- "Can not transition to " + newState + " state from " + state);
- }
- break;
- }
+ public void preDeregister() throws Exception {
+ }
- case State.RUNNING_INDEX :
- {
- switch (state.toInt())
- {
- case State.STOPPING_INDEX :
- case State.FAILED_INDEX :
- break;
- case State.STOPPED_INDEX :
- case State.STARTING_INDEX :
- case State.RUNNING_INDEX :
- throw new IllegalStateException(
- "Can not transition to " + newState + " state from " + state);
+ public void postDeregister() {
+ }
- }
- break;
- }
+ public void handleNotification(Notification n, Object o) {
+ String type = n.getType();
+ ObjectName source = null;
+ if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(type)) {
+ MBeanServerNotification notification = (MBeanServerNotification) n;
+ source = notification.getMBeanName();
+ try {
+ server.addNotificationListener(source, this, J2EENotification.NOTIFICATION_FILTER, null);
+ } catch (InstanceNotFoundException e) {
+ // the instance died before we could get going... not a big deal
+ return;
+ }
+ } else if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(type)) {
+ MBeanServerNotification notification = (MBeanServerNotification) n;
+ source = notification.getMBeanName();
+ } else {
+ source = (ObjectName) n.getSource();
+ }
+ Set dependencies = dependencyService.getStartParents(objectName);
+ if (dependencies.contains(source)) {
+ checkState();
+ }
+ }
- case State.STOPPING_INDEX :
- {
- switch (newState.toInt())
- {
- case State.STOPPED_INDEX :
- case State.FAILED_INDEX :
- break;
- case State.STARTING_INDEX :
- case State.RUNNING_INDEX :
- case State.STOPPING_INDEX :
- throw new IllegalStateException(
- "Can not transition to " + newState + " state from " + state);
- }
- break;
- }
+ public final State getStateInstance() {
+ return state;
+ }
- case State.FAILED_INDEX :
- {
- switch (newState.toInt())
- {
- case State.STARTING_INDEX :
- case State.STOPPING_INDEX :
- break;
- case State.STOPPED_INDEX :
- case State.RUNNING_INDEX :
- case State.FAILED_INDEX :
- throw new IllegalStateException(
- "Can not transition to " + newState + " state from " + state);
- }
- break;
- }
- }
- log.debug("State changed from " + state + " to " + newState);
- if (newState==State.RUNNING)
- startTime= System.currentTimeMillis();
- state= newState;
-
- doNotification(state.getEventTypeValue());
+ public final int getState() {
+ return state.toInt();
}
- /* (non-Javadoc)
- * @see org.apache.geronimo.common.StateManageable#getStartTime()
- */
- public long getStartTime()
- {
+ public final long getStartTime() {
return startTime;
}
-
- /* (non-Javadoc)
- * @see org.apache.geronimo.common.StateManageable#start()
- */
- public void start() throws Exception
- {
- try
- {
+ public final void start() throws Exception {
+ State state = getStateInstance();
+ if (state == State.STARTING || state == State.RUNNING) {
+ return;
+ }
+ try {
setState(State.STARTING);
- doStart();
- setState(State.RUNNING);
+ if (dependencyService.canStart(objectName)) {
+ enrollInRelationships();
+ doStart();
+ setState(State.RUNNING);
+ }
+ } catch (Exception e) {
+ setState(State.FAILED);
+ throw e;
+ } catch (Error e) {
+ setState(State.FAILED);
+ throw e;
+ }
+ }
+
+ public final void stop() throws Exception {
+ State state = getStateInstance();
+ if (state == State.STOPPED || state == State.STOPPING) {
+ return;
+ } else if (state == State.STARTING) {
+ setState(State.STOPPED);
+ return;
}
- finally
- {
- if (state != State.RUNNING)
- setState(State.FAILED);
+ try {
+ setState(State.STOPPING);
+
+ // stop all of my dependent objects
+ Set dependents = dependencyService.getStartChildren(objectName);
+ for (Iterator iterator = dependents.iterator(); iterator.hasNext();) {
+ ObjectName name = (ObjectName) iterator.next();
+ server.invoke(name, "stop", null, null);
+ }
+
+ // stop myself
+ if (dependencyService.canStop(objectName)) {
+ doStop();
+ setState(State.STOPPED);
+ }
+ } catch (Exception e) {
+ setState(State.FAILED);
+ throw e;
+ } catch (Error e) {
+ setState(State.FAILED);
+ throw e;
}
}
- /* (non-Javadoc)
- * @see org.apache.geronimo.common.StateManageable#startRecursive()
- */
- public void startRecursive() throws Exception
- {
+ public final void startRecursive() throws Exception {
+ State state = getStateInstance();
+ if (state == State.STOPPING) {
+ throw new IllegalArgumentException("Cannot startRecursive while in the stopping state");
+ }
+
+ // get myself starting
start();
+
+ // startRecursive all of objects that depend on me
+ Set dependents = dependencyService.getStartChildren(objectName);
+ for (Iterator iterator = dependents.iterator(); iterator.hasNext();) {
+ ObjectName dependent = (ObjectName) iterator.next();
+ server.invoke(dependent, "startRecursive", null, null);
+ }
}
+ private final void doNotification(String s) {
+ sendNotification(new Notification(s, this, sequenceNumber++));
+ }
- /* (non-Javadoc)
- * @see org.apache.geronimo.common.StateManageable#stop()
- */
- public void stop()
- {
- // Do the actual stop tasks
- try
- {
- setState(State.STOPPING);
- doStop();
- setState(State.STOPPED);
+ private final void enrollInRelationships() throws StartException {
+ String relationshipType = null;
+ String relationshipRole = null;
+ String targetRoleName = null;
+ try {
+ Set relationships = dependencyService.getRelationships(objectName);
+ for (Iterator i = relationships.iterator(); i.hasNext();) {
+ MBeanRelationship relationship = (MBeanRelationship) i.next();
+
+ // if we don't have a relationship instance create one
+ String relationshipName = relationship.getName();
+ relationshipRole = relationship.getRole();
+ if (!relationService.hasRelation(relationshipName).booleanValue()) {
+ relationshipType = relationship.getType();
+ RoleList roleList = new RoleList();
+ roleList.add(new Role(relationshipRole, Collections.singletonList(objectName)));
+
+ // if we have a target we need to add it to the role list
+ ObjectName target = relationship.getTarget();
+ if (target != null) {
+ targetRoleName = relationship.getTargetRole();
+ if (targetRoleName == null || targetRoleName.length() == 0) {
+ List roles = relationService.getRoleInfos(relationshipType);
+ if (roles.size() < 2) {
+ throw new StartException("Relationship has less than two roles. You cannot specify a target");
+ }
+ if (roles.size() > 2) {
+ throw new StartException("Relationship has more than two roles. You must use targetRoleName");
+ }
+ if (((RoleInfo) roles.get(0)).getName().equals(relationshipRole)) {
+ targetRoleName = ((RoleInfo) roles.get(1)).getName();
+ } else {
+ targetRoleName = ((RoleInfo) roles.get(0)).getName();
+ }
+ }
+
+ roleList.add(new Role(targetRoleName, Collections.singletonList(target)));
+ }
+ relationService.createRelation(relationshipName, relationshipType, roleList);
+ } else {
+ // We have an exiting relationship -- just add to the existing role
+ List members = relationService.getRole(relationshipName, relationshipRole);
+ if(!members.contains(objectName)) {
+ members.add(objectName);
+ relationService.setRole(relationshipName, new Role(relationshipRole, members));
+ }
+ }
+ }
+ } catch (RelationTypeNotFoundException e) {
+ throw new StartException("Relationship type is not registered: relationType=" + relationshipType);
+ } catch (RelationServiceNotRegisteredException e) {
+ throw new StartException("RelationshipService is not registered", e);
+ } catch (RoleNotFoundException e) {
+ throw new StartException("RelationshipService is not registered", e);
+ } catch (InvalidRelationIdException e) {
+ throw new StartException("Relationship type does not contain role:" +
+ " relationType=" + relationshipType +
+ " sourceRole=" + relationshipRole +
+ " targetRole=" + targetRoleName, e);
+ } catch (InvalidRoleValueException e) {
+ throw new StartException("Relationship role state is invalid", e);
+ } catch (RelationNotFoundException e) {
+ throw new StartException("Relation was unregistered while executing", e);
}
- catch (Exception e)
- {
- log.warn("Stop failed", e);
- setState(State.FAILED);
+ }
+
+ private void checkState() {
+ State state = getStateInstance();
+ if (state == State.STARTING) {
+ if (dependencyService.canStart(objectName)) {
+ try {
+ doStart();
+ setState(State.RUNNING);
+ } catch (Exception e) {
+ setState(State.FAILED);
+ } catch (Error e) {
+ setState(State.FAILED);
+ }
+ }
+ } else if (state == State.RUNNING) {
+ if (dependencyService.shouldStop(objectName)) {
+ // we were running and someone stopped or unregisted without informing us
+ // try to stop immedately, or just fail
+ if (dependencyService.canStop(objectName)) {
+ try {
+ setState(State.STOPPING);
+ doStop();
+ setState(State.STOPPED);
+ } catch (Exception e) {
+ setState(State.FAILED);
+ } catch (Error e) {
+ setState(State.FAILED);
+ }
+ } else {
+ setState(State.FAILED);
+ }
+ }
+ } else if (state == State.STOPPING) {
+ if (dependencyService.canStop(objectName)) {
+ try {
+ doStop();
+ setState(State.STOPPED);
+ } catch (Exception e) {
+ setState(State.FAILED);
+ } catch (Error e) {
+ setState(State.FAILED);
+ }
+ }
}
}
+ /**
+ * Set the Component state.
+ * @param newState
+ * @throws IllegalStateException Thrown if the transition is not supported by the JSR77 lifecycle.
+ */
+ private void setState(State newState) throws IllegalStateException {
+ switch (state.toInt()) {
+ case State.STOPPED_INDEX:
+ switch (newState.toInt()) {
+ case State.STARTING_INDEX:
+ break;
+ case State.STOPPED_INDEX:
+ case State.RUNNING_INDEX:
+ case State.STOPPING_INDEX:
+ case State.FAILED_INDEX:
+ throw new IllegalStateException(
+ "Can not transition to " + newState + " state from " + state);
+ }
+ break;
+
+ case State.STARTING_INDEX:
+ switch (newState.toInt()) {
+ case State.RUNNING_INDEX:
+ case State.FAILED_INDEX:
+ case State.STOPPING_INDEX:
+ break;
+ case State.STOPPED_INDEX:
+ case State.STARTING_INDEX:
+ throw new IllegalStateException(
+ "Can not transition to " + newState + " state from " + state);
+ }
+ break;
+
+ case State.RUNNING_INDEX:
+ switch (newState.toInt()) {
+ case State.STOPPING_INDEX:
+ case State.FAILED_INDEX:
+ break;
+ case State.STOPPED_INDEX:
+ case State.STARTING_INDEX:
+ case State.RUNNING_INDEX:
+ throw new IllegalStateException(
+ "Can not transition to " + newState + " state from " + state);
+
+ }
+ break;
+
+ case State.STOPPING_INDEX:
+ switch (newState.toInt()) {
+ case State.STOPPED_INDEX:
+ case State.FAILED_INDEX:
+ break;
+ case State.STARTING_INDEX:
+ case State.RUNNING_INDEX:
+ case State.STOPPING_INDEX:
+ throw new IllegalStateException(
+ "Can not transition to " + newState + " state from " + state);
+ }
+ break;
+
+ case State.FAILED_INDEX:
+ switch (newState.toInt()) {
+ case State.STARTING_INDEX:
+ case State.STOPPING_INDEX:
+ break;
+ case State.RUNNING_INDEX:
+ case State.STOPPED_INDEX:
+ case State.FAILED_INDEX:
+ throw new IllegalStateException(
+ "Can not transition to " + newState + " state from " + state);
+ }
+ break;
+ }
+ log.debug("State changed from " + state + " to " + newState);
+ if (newState == State.RUNNING) {
+ startTime = System.currentTimeMillis();
+ }
+ state = newState;
+ doNotification(state.getEventTypeValue());
+ }
}
1.3 +49 -85 incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/AbstractContainer.java
Index: AbstractContainer.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/AbstractContainer.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- AbstractContainer.java 15 Aug 2003 14:11:26 -0000 1.2
+++ AbstractContainer.java 16 Aug 2003 23:16:18 -0000 1.3
@@ -57,41 +57,55 @@
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Iterator;
import java.util.List;
-import java.util.ListIterator;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.apache.geronimo.deployment.dependency.DependencyServiceMBean;
+import org.apache.geronimo.jmx.JMXUtil;
/**
* Abstract implementation of Container interface.
- *
- * @version $Revision$ $Date$
- *
-*/
-public abstract class AbstractContainer
- extends AbstractComponent
- implements Container
-{
+ *
+ * @version $Revision$ $Date$
+ *
+ */
+public abstract class AbstractContainer extends AbstractComponent implements Container {
+ /**
+ * The Dependency Service manager. We register our components with the is service because
+ * we need to stop if any of our services fail or stop.
+ */
+ private DependencyServiceMBean dependency;
+
+ /**
+ * The components owned by this container
+ * @todo all accss to this must be synchronized
+ */
private ArrayList components = new ArrayList();
+ public ObjectName preRegister(MBeanServer server, ObjectName objectName) throws Exception {
+ dependency = JMXUtil.getDependencyService(server);
+ return super.preRegister(server, objectName);
+ }
+
/**
- * A Container cannot be itself contained in a Container.
+ * A Container cannot be itself contained in a Container.
*
* NB. Do we agree this is the model?
* @return always null
*/
- public Container getContainer()
- {
+ public Container getContainer() {
return null;
}
/**
* A Container cannot be itself contained in a Container.
- *
+ *
* NB. Do we agree this is the model?
* @throws java.lang.UnsupportedOperationException
*/
- public void setContainer()
- {
+ public void setContainer() {
throw new UnsupportedOperationException("Cannot call setContainer on a Container");
}
@@ -100,13 +114,17 @@
* Subclasses might like to override this in order
* to check their state before allowing the addition.
*
- * @param component
+ * @param component
*/
- public void addComponent(Component component)
- {
- if (component == null)
- return;
-
+ public void addComponent(Component component) {
+ if (component == null) {
+ throw new NullArgumentException("component");
+ }
+ try {
+ dependency.addStartDependency(objectName, new ObjectName(component.getObjectName()));
+ } catch (MalformedObjectNameException e) {
+ throw new IllegalArgumentException("Component does not have a valid object name: objectName=" + component.getObjectName());
+ }
components.add(component);
}
@@ -115,8 +133,7 @@
*
* @return an immutable List of Components
*/
- public List getComponents()
- {
+ public List getComponents() {
return Collections.unmodifiableList(components);
}
@@ -131,68 +148,15 @@
*
* @param component the Component to remove
*/
- public void removeComponent(Component component) throws Exception
- {
- if (component == null)
- return;
-
- components.remove(component);
- }
-
- /**
- * Start the Container, and all of its Components.
- *
- * @exception Exception if an error occurs
- */
- public void startRecursive() throws Exception
- {
- //start the container itself
- start();
-
- //start the Components
- Iterator itor = components.iterator();
- while (itor.hasNext())
- {
- //only start stopped or failed Components as per JSR77
- Component c = (Component) itor.next();
- if ((c.getStateInstance() == State.STOPPED)
- ||
- (c.getStateInstance() == State.FAILED))
- c.startRecursive();
+ public void removeComponent(Component component) throws Exception {
+ if (component == null) {
+ throw new NullArgumentException("component");
}
-
- //NOTE: it is perfectly possible that some Components will be
- //in the RUNNING state and some of them in the STOPPED or FAILED state
- }
-
-
- /* -------------------------------------------------------------------------------------- */
- /** Do a recursive stop.
- *
- * @see org.apache.geronimo.common.StateManageable#stop()
- */
- public void stop()
- {
- // Stop all the Components in reverse insertion order
- try
- {
- setState(State.STOPPING);
-
- for (ListIterator iterator =
- components.listIterator(components.size());
- iterator.hasPrevious();
- )
- {
- Interceptor interceptor = (Interceptor) iterator.previous();
- interceptor.stop();
- }
- setState(State.STOPPED);
- }
- finally
- {
- if (getStateInstance() != State.STOPPED)
- setState(State.FAILED);
+ try {
+ dependency.removeStartDependency(objectName, new ObjectName(component.getObjectName()));
+ } catch (MalformedObjectNameException e) {
+ throw new IllegalArgumentException("Component does not have a valid object name: objectName=" + component.getObjectName());
}
+ components.remove(component);
}
-
}
1.5 +23 -24 incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/State.java
Index: State.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/State.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- State.java 14 Aug 2003 07:14:34 -0000 1.4
+++ State.java 16 Aug 2003 23:16:18 -0000 1.5
@@ -62,39 +62,38 @@
* @version $Revision$ $Date$
*/
public final class State {
-
- public static final int STARTING_INDEX=0;
- public static final int RUNNING_INDEX=1;
- public static final int STOPPING_INDEX=2;
- public static final int STOPPED_INDEX=3;
- public static final int FAILED_INDEX=4;
-
+
+ public static final int STARTING_INDEX = 0;
+ public static final int RUNNING_INDEX = 1;
+ public static final int STOPPING_INDEX = 2;
+ public static final int STOPPED_INDEX = 3;
+ public static final int FAILED_INDEX = 4;
+
public static final State STARTING =
- new State("starting",STARTING_INDEX,"j2ee.state.starting");
+ new State("starting", STARTING_INDEX, J2EENotification.STATE_STARTING);
public static final State RUNNING =
- new State("running",RUNNING_INDEX,"j2ee.state.running");
+ new State("running", RUNNING_INDEX, J2EENotification.STATE_RUNNING);
public static final State STOPPING =
- new State("stopping",STOPPING_INDEX,"j2ee.state.stopping");
+ new State("stopping", STOPPING_INDEX, J2EENotification.STATE_STOPPING);
public static final State STOPPED =
- new State("stopped",STOPPED_INDEX,"j2ee.state.stopped");
+ new State("stopped", STOPPED_INDEX, J2EENotification.STATE_STOPPED);
public static final State FAILED =
- new State("failed",FAILED_INDEX,"j2ee.state.failed");
+ new State("failed", FAILED_INDEX, J2EENotification.STATE_FAILED);
+
+ private static final State[] fromInt =
+ {STARTING, RUNNING, STOPPING, STOPPED, FAILED};
- private static final State[] fromInt=
- {STARTING,RUNNING,STOPPING,STOPPED,FAILED};
-
/**
* Get a State from an int index
* @param index int index of the state
* @return The State instance or null if no such State.
*/
- public static State fromInt(int index)
- {
- if (index<0 || index>=fromInt.length)
+ public static State fromInt(int index) {
+ if (index < 0 || index >= fromInt.length)
return null;
return fromInt[index];
}
-
+
private final String name;
private final int index;
@@ -103,21 +102,21 @@
*/
private final String eventTypeValue;
-
+
private State(String name, int index, String anEventTypeValue) {
this.name = name;
this.index = index;
eventTypeValue = anEventTypeValue;
}
- public int toInt() {
+ public int toInt() {
return index;
}
-
+
public String getEventTypeValue() {
return eventTypeValue;
}
-
+
public String toString() {
return name;
}
1.6 +31 -39 incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/AbstractComponent.java
Index: AbstractComponent.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/AbstractComponent.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- AbstractComponent.java 15 Aug 2003 14:11:26 -0000 1.5
+++ AbstractComponent.java 16 Aug 2003 23:16:18 -0000 1.6
@@ -56,19 +56,22 @@
package org.apache.geronimo.common;
/**
- * A helper implementation of the Component interface that should
+ * A helper implementation of the Component interface that should
* be used as a base class for Component implementations.
*
+ * @todo this is broken because name is required but there is no way to set it
+ *
* @version $Revision$ $Date$
*/
-public class AbstractComponent
- extends AbstractStateManageable
- implements Component
-{
- //the Container this Component belongs to
+public class AbstractComponent extends AbstractStateManageable implements Component {
+ /**
+ * the Container this Component belongs to
+ */
private Container container;
- //the identity of this Component
+ /**
+ * the identity of this Component
+ */
private String name;
@@ -77,8 +80,7 @@
*
* @return a <code>Container</code> value
*/
- public Container getContainer()
- {
+ public Container getContainer() {
return container;
}
@@ -92,46 +94,40 @@
* parameter is null, or the component has been destroyed and the container parameter is NOT null
*/
public void setContainer(Container container)
- throws IllegalStateException, IllegalArgumentException
- {
- if (getStateInstance() != State.STOPPED)
- {
+ throws IllegalStateException, IllegalArgumentException {
+ if (getStateInstance() != State.STOPPED) {
throw new IllegalStateException(
- "Set container can only be called while in the stopped state: state=" + getStateInstance());
+ "Set container can only be called while in the stopped state: state=" + getStateInstance());
}
- this.container= container;
+ this.container = container;
}
/* Start the Component
* @see org.apache.geronimo.common.AbstractStateManageable#doStart()
*/
- public void doStart() throws Exception
- {
+ protected void doStart() throws Exception {
}
/* Stop the Component
* @see org.apache.geronimo.common.AbstractStateManageable#doStop()
*/
- public void doStop() throws Exception
- {
+ protected void doStop() throws Exception {
}
- /*
+ /*
* @see org.apache.geronimo.common.AbstractStateManageable#doNotification(java.lang.String)
*/
- public void doNotification(String eventTypeValue)
- {
- log.debug("notification: "+eventTypeValue+" from "+this);
+ public void doNotification(String eventTypeValue) {
+ log.debug("notification: " + eventTypeValue + " from " + this);
}
-
+
/**
* Get the unique identity of this Component
*
* @return the name (formatted according to JSR 77)
*/
- public String getObjectName ()
- {
+ public String getObjectName() {
return name;
}
@@ -141,14 +137,11 @@
* @param component to test
* @return true if the names are the same, false otherwise
*/
- public boolean equals (Component component)
- {
- if (component == null)
- return false;
-
- if (component.getObjectName().equals(name))
- return true;
-
+ public boolean equals(Object o) {
+ if (o instanceof Component) {
+ Component component = (Component)o;
+ return component.getObjectName().equals(name);
+ }
return false;
}
@@ -160,11 +153,10 @@
*
* @return hash of Component name
*/
- public int hashCode ()
- {
- if (name == null)
+ public int hashCode() {
+ if (name == null) {
return 0;
-
+ }
return name.hashCode();
}
}
1.2 +11 -10 incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/StateManageable.java
Index: StateManageable.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/StateManageable.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- StateManageable.java 14 Aug 2003 07:14:34 -0000 1.1
+++ StateManageable.java 16 Aug 2003 23:16:18 -0000 1.2
@@ -62,19 +62,17 @@
*
* @version $Revision$ $Date$
*/
-public interface StateManageable
-{
+public interface StateManageable {
/**
* Gets the state of this component as an int.
* The int return is required by the JSR77 specification.
- * @see getStateInstance to obtain the State instance
+ * @see #getStateInstance to obtain the State instance
* @return the current state of this component
*/
int getState();
/**
* Gets the state of this component as a State instance.
- * @see getStateInstance to obtain the real state
* @return the current state of this component
*/
State getStateInstance();
@@ -84,7 +82,7 @@
* @return time in milliseonds since epoch that this component was started.
*/
long getStartTime();
-
+
/**
* Transitions the component to the starting state. This method has access to the
@@ -102,7 +100,7 @@
/**
* Transitions the component to the starting state. This method has access to the
* container.
- *
+ *
* If this Component is a Container, then startRecursive is called on all child Components
* that are in the STOPPED or FAILED state.
* Normally a component uses this to cache data from other components. The other components will
@@ -118,13 +116,16 @@
* Transitions the component to the stopping state. This method has access to the
* container.
*
- * If this is Component is a Container, then all its child components must be in the
+ * If this is Component is a Container, then all its child components must be in the
* STOPPED or FAILED State.
- *
+ *
* Normally a component uses this to drop references to data cached in the start method.
* The other components will not necessairly have been stopped at this stage and may not be ready
* to have methods invoked on them.
+ *
+ * @throws java.lang.Exception if a problem occurs during the transition
+ * @throws java.lang.IllegalStateException if this interceptor is not in the STOPPED or FAILED state
*/
- void stop() throws IllegalStateException;
+ void stop() throws Exception, IllegalStateException;
}
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/StartException.java
Index: StartException.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.common;
/**
*
*
* @version $Revision: 1.1 $ $Date: 2003/08/16 23:16:18 $
*/
public class StartException extends Exception {
public StartException() {
}
public StartException(String message) {
super(message);
}
public StartException(String message, Throwable cause) {
super(message, cause);
}
public StartException(Throwable cause) {
super(cause);
}
}
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/common/J2EENotification.java
Index: J2EENotification.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.common;
import javax.management.Notification;
import javax.management.NotificationFilterSupport;
import javax.management.MBeanServerNotification;
import javax.management.NotificationFilter;
/**
*
*
* @version $Revision: 1.1 $ $Date: 2003/08/16 23:16:18 $
*/
public interface J2EENotification {
/**
* A new managed object was created.
*/
String OBJECT_CREATED = "j2ee.object.created";
/**
* A managed object was deleted
*/
String OBJECT_DELETED = "j2ee.object.deleted";
/**
* A state manageable object entered the starting state
*/
String STATE_STARTING = "j2ee.state.starting";
/**
* A state manageable object entered the running state
*/
String STATE_RUNNING = "j2ee.state.running";
/**
* A state manageable object entered the stopping state
*/
String STATE_STOPPING = "j2ee.state.stopping";
/**
* A state manageable object entered the stopped state.
*/
String STATE_STOPPED = "j2ee.state.stopped";
/**
* A state manageable object entered the failed state
*/
String STATE_FAILED = "j2ee.state.failed";
/**
* An attribute has change value
*/
String ATTRIBUTE_CHANGED = "j2ee.attribute.changed";
/**
* An array containg all of the know J2EE notification types
*/
String[] TYPES = new String[]{
OBJECT_CREATED, OBJECT_DELETED,
STATE_STARTING, STATE_RUNNING, STATE_STOPPING, STATE_STOPPED, STATE_FAILED,
ATTRIBUTE_CHANGED
};
/**
* A notification filter which lets all J2EE notifications pass
*/
NotificationFilter NOTIFICATION_FILTER = new NotificationFilter() {
public boolean isNotificationEnabled(Notification notification) {
String type = notification.getType();
for (int i = 0; i < TYPES.length; i++) {
if(TYPES[i].equals(type)) {
return true;
}
}
return false;
}
};
}