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/14 02:02:39 UTC
cvs commit: incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan InitializeMBeanInstance.java CreateMBeanInstance.java DeploymentPlan.java DeploymentTask.java DestroyMBeanInstance.java InvokeMBeanOperation.java RegisterMBeanInstance.java UnregisterMBeanInstance.java CreateClassSpace.java StartMBeanInstance.java
dain 2003/08/13 17:02:39
Modified: modules/core/src/java/org/apache/geronimo/deployment/plan
CreateMBeanInstance.java DeploymentPlan.java
DeploymentTask.java DestroyMBeanInstance.java
InvokeMBeanOperation.java
RegisterMBeanInstance.java
UnregisterMBeanInstance.java CreateClassSpace.java
StartMBeanInstance.java
Added: modules/core/src/java/org/apache/geronimo/deployment/plan
InitializeMBeanInstance.java
Log:
Deployment system now will wait for relationship type to be registered and for related MBeans to be created before attempting to enroll a MBean in a relationship. This also delays the create callback until all related MBeans have been registered with the MBeanServer and have been enrolled in the relationship.
Revision Changes Path
1.5 +10 -122 incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/CreateMBeanInstance.java
Index: CreateMBeanInstance.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/CreateMBeanInstance.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- CreateMBeanInstance.java 13 Aug 2003 21:17:20 -0000 1.4
+++ CreateMBeanInstance.java 14 Aug 2003 00:02:38 -0000 1.5
@@ -62,7 +62,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.Collections;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.InstanceAlreadyExistsException;
@@ -76,35 +75,26 @@
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
-import javax.management.relation.RelationServiceMBean;
-import javax.management.relation.Role;
-import javax.management.relation.RoleList;
-import javax.management.relation.RoleInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.core.util.ClassUtil;
import org.apache.geronimo.deployment.DeploymentException;
import org.apache.geronimo.deployment.service.MBeanMetadata;
-import org.apache.geronimo.deployment.service.MBeanRelationship;
-import org.apache.geronimo.deployment.service.MBeanOperation;
-import org.apache.geronimo.jmx.JMXUtil;
/**
* Creates an new MBean instance and intializes it according to the specified MBeanMetadata metadata
*
* @version $Revision$ $Date$
*/
-public class CreateMBeanInstance extends DeploymentTask {
+public class CreateMBeanInstance implements DeploymentTask {
private final Log log = LogFactory.getLog(this.getClass());
private final Set plans;
private final MBeanServer server;
- private final RelationServiceMBean relationService;
private final ObjectName parent;
private final ObjectName loaderName;
private final MBeanMetadata metadata;
private ObjectName actualName;
- private boolean createCalled;
public CreateMBeanInstance(Set plans, MBeanServer server, ObjectName parent, MBeanMetadata metadata, ObjectName loaderName) {
this.plans = plans;
@@ -112,7 +102,10 @@
this.parent = parent;
this.metadata = metadata;
this.loaderName = loaderName;
- relationService = JMXUtil.getRelationService(server);
+ }
+
+ public boolean canRun() throws DeploymentException {
+ return true;
}
public void perform() throws DeploymentException {
@@ -165,60 +158,6 @@
throw new DeploymentException(e);
}
- // Resolve and enroll in all relationships
- Set relationships = metadata.getRelationships();
- try {
- 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();
- String relationshipRole = relationship.getRole();
- if (!relationService.hasRelation(relationshipName).booleanValue()) {
- // if we don't have a relationship of the
- String relationshipType = relationship.getType();
- if (!relationService.getAllRelationTypeNames().contains(relationshipType)) {
- throw new DeploymentException("Relationship type is not registered: relationType=" + relationshipType);
- }
-
- RoleList roleList = new RoleList();
- roleList.add(new Role(relationshipRole, Collections.singletonList(actualName)));
-
- // if we have a target we need to add it to the role list
- String target = relationship.getTarget();
- if (target != null && target.length() > 0) {
- String targetRoleName = relationship.getTargetRole();
- if (targetRoleName == null || targetRoleName.length() == 0) {
- List roles = relationService.getRoleInfos(relationshipType);
- if(roles.size() < 2) {
- throw new DeploymentException("Relationship has less than two roles. You cannot specify a target");
- }
- if(roles.size() > 2) {
- throw new DeploymentException("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(new ObjectName(target))));
- }
- relationService.createRelation(relationshipName, relationshipType, roleList);
- } else {
- // We have an exiting relationship -- just add to the existing role
- List members = relationService.getRole(relationshipName, relationshipRole);
- members.add(actualName);
- relationService.setRole(relationshipName, new Role(relationshipRole, members));
- }
- }
- } catch (DeploymentException e) {
- throw e;
- } catch (Exception e) {
- throw new DeploymentException(e);
- }
-
// Set the MBean attributes
MBeanInfo mbInfo;
try {
@@ -264,44 +203,9 @@
throw new DeploymentException(e);
}
- // Invoke the create callback method
- try {
- server.invoke(actualName, "create", null, null);
- createCalled = true;
- } catch (RuntimeException e) {
- throw new DeploymentException(e);
- } catch (InstanceNotFoundException e) {
- throw new DeploymentException(e);
- } catch (MBeanException e) {
- throw new DeploymentException(e);
- } catch (ReflectionException e) {
- if (e.getTargetException() instanceof NoSuchMethodException) {
- // did not have a create method - ok
- } else {
- throw new DeploymentException(e);
- }
- }
-
- // Add a deployment plan to start the MBean
- DeploymentPlan startPlan = new DeploymentPlan();
- startPlan.addTask(new StartMBeanInstance(server, actualName));
- List operations = metadata.getOperations();
- for (Iterator i = operations.iterator(); i.hasNext();) {
- MBeanOperation operation = (MBeanOperation) i.next();
- int argCount = operation.getTypes().size();
- String[] argTypes = (String[]) operation.getTypes().toArray(new String[argCount]);
- List values = operation.getArgs();
- Object[] args = new Object[argCount];
- for (int j = 0; j < argCount; j++) {
- Object value = values.get(j);
- if (value instanceof String) {
- value = getValue(newCL, argTypes[j], (String) value);
- }
- args[j] = value;
- }
- startPlan.addTask(new InvokeMBeanOperation(server, actualName, operation.getOperation(), argTypes, args));
- }
- plans.add(startPlan);
+ // Add a deployment plan to initialize the MBeans
+ DeploymentTask initTask = new InitializeMBeanInstance(plans, server, actualName, parent, metadata, loaderName);
+ plans.add(new DeploymentPlan(initTask));
} catch (DeploymentException e) {
undo();
throw e;
@@ -316,23 +220,6 @@
}
try {
- if (createCalled) {
- server.invoke(actualName, "destroy", null, null);
- }
- } catch (InstanceNotFoundException e) {
- log.warn("MBean was already removed " + actualName, e);
- return;
- } catch (MBeanException e) {
- log.error("Error while destroying MBean " + actualName, e);
- } catch (ReflectionException e) {
- if (e.getTargetException() instanceof NoSuchMethodException) {
- // did not have a destroy method - ok
- } else {
- log.error("Error while destroying MBean " + actualName, e);
- }
- }
-
- try {
server.invoke(parent, "removeChild", new Object[]{actualName}, new String[]{"javax.management.ObjectName"});
} catch (InstanceNotFoundException e) {
log.warn("Could not remove from parent", e);
@@ -341,6 +228,7 @@
} catch (ReflectionException e) {
log.error("Error while removing MBean " + actualName + " from parent", e);
}
+
try {
server.unregisterMBean(actualName);
} catch (InstanceNotFoundException e) {
1.2 +17 -1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/DeploymentPlan.java
Index: DeploymentPlan.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/DeploymentPlan.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DeploymentPlan.java 11 Aug 2003 17:59:10 -0000 1.1
+++ DeploymentPlan.java 14 Aug 2003 00:02:38 -0000 1.2
@@ -75,8 +75,24 @@
public DeploymentPlan() {
}
+ public DeploymentPlan(DeploymentTask task) {
+ tasks.add(task);
+ }
+
public void addTask(DeploymentTask task) {
tasks.add(task);
+ }
+
+ public boolean canRun() throws DeploymentException {
+ boolean canRun = true;
+ for (Iterator i = tasks.iterator(); i.hasNext();) {
+ DeploymentTask task = (DeploymentTask) i.next();
+ log.trace("Checking if task can run " + task);
+
+ // always check each task, so the task can throw an exception if the task can never run
+ canRun = canRun && task.canRun();
+ }
+ return canRun;
}
public void execute() throws DeploymentException {
1.2 +26 -5 incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/DeploymentTask.java
Index: DeploymentTask.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/DeploymentTask.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DeploymentTask.java 11 Aug 2003 17:59:10 -0000 1.1
+++ DeploymentTask.java 14 Aug 2003 00:02:38 -0000 1.2
@@ -58,12 +58,33 @@
import org.apache.geronimo.deployment.DeploymentException;
/**
- *
+ * DeploymenTask is a single unit of work in a plan. The plan checks is all tasks canRun() before
+ * executing the plan and performing all the tasks. I this task throws an exception during perform,
+ * it must clean up after itself before throwing the exception as undo will not be called. If this
+ * task completes successfully but a subsequent task throws an exception the undo method will be
+ * called so the task can rollback any changes.
*
* @version $Revision$ $Date$
*/
-public abstract class DeploymentTask {
- public abstract void perform() throws DeploymentException;
+public interface DeploymentTask {
+ /**
+ * Can this task complete now?
+ * @return true if the can can complete now; otherwise false and the plan should wait
+ * @throws DeploymentException if a problem occurs while checking the task, if the can check
+ * throws an exception the plan should be discarded
+ */
+ boolean canRun() throws DeploymentException;
+
+ /**
+ * Executes the task. If a DeploymentException is throw undo will not be called, so task
+ * should clean up after itself before throwing the exception
+ * @throws DeploymentException if an unrecoverable problem occurs in the task, plan should
+ * be rolled back
+ */
+ void perform() throws DeploymentException;
- public abstract void undo();
+ /**
+ * Undo all operations performed during the perform method.
+ */
+ void undo();
}
1.2 +7 -2 incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/DestroyMBeanInstance.java
Index: DestroyMBeanInstance.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/DestroyMBeanInstance.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DestroyMBeanInstance.java 11 Aug 2003 17:59:10 -0000 1.1
+++ DestroyMBeanInstance.java 14 Aug 2003 00:02:38 -0000 1.2
@@ -64,13 +64,14 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.geronimo.deployment.DeploymentException;
/**
*
*
* @version $Revision$ $Date$
*/
-public class DestroyMBeanInstance extends DeploymentTask {
+public class DestroyMBeanInstance implements DeploymentTask {
private final Log log = LogFactory.getLog(this.getClass());
private final MBeanServer server;
private final ObjectName name;
@@ -78,6 +79,10 @@
public DestroyMBeanInstance(MBeanServer server, ObjectName name) {
this.server = server;
this.name = name;
+ }
+
+ public boolean canRun() throws DeploymentException {
+ return true;
}
public void perform() {
1.2 +8 -4 incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/InvokeMBeanOperation.java
Index: InvokeMBeanOperation.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/InvokeMBeanOperation.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- InvokeMBeanOperation.java 11 Aug 2003 19:46:28 -0000 1.1
+++ InvokeMBeanOperation.java 14 Aug 2003 00:02:38 -0000 1.2
@@ -64,11 +64,11 @@
import org.apache.geronimo.deployment.DeploymentException;
/**
- *
- *
+ *
+ *
* @version $Revision$ $Date$
*/
-public class InvokeMBeanOperation extends DeploymentTask {
+public class InvokeMBeanOperation implements DeploymentTask {
private final MBeanServer server;
private final ObjectName name;
private final String operation;
@@ -81,6 +81,10 @@
this.operation = operation;
this.argTypes = argTypes;
this.args = args;
+ }
+
+ public boolean canRun() throws DeploymentException {
+ return true;
}
public void perform() throws DeploymentException {
1.2 +6 -2 incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/RegisterMBeanInstance.java
Index: RegisterMBeanInstance.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/RegisterMBeanInstance.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- RegisterMBeanInstance.java 11 Aug 2003 17:59:10 -0000 1.1
+++ RegisterMBeanInstance.java 14 Aug 2003 00:02:38 -0000 1.2
@@ -69,7 +69,7 @@
*
* @version $Revision$ $Date$
*/
-public class RegisterMBeanInstance extends DeploymentTask {
+public class RegisterMBeanInstance implements DeploymentTask {
private final MBeanServer server;
private final ObjectName name;
private final Object instance;
@@ -79,6 +79,10 @@
this.server = server;
this.name = name;
this.instance = instance;
+ }
+
+ public boolean canRun() throws DeploymentException {
+ return true;
}
public void perform() throws DeploymentException {
1.2 +6 -2 incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/UnregisterMBeanInstance.java
Index: UnregisterMBeanInstance.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/UnregisterMBeanInstance.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- UnregisterMBeanInstance.java 11 Aug 2003 17:59:10 -0000 1.1
+++ UnregisterMBeanInstance.java 14 Aug 2003 00:02:38 -0000 1.2
@@ -67,13 +67,17 @@
*
* @version $Revision$ $Date$
*/
-public class UnregisterMBeanInstance extends DeploymentTask {
+public class UnregisterMBeanInstance implements DeploymentTask {
private final MBeanServer server;
private final ObjectName name;
public UnregisterMBeanInstance(MBeanServer server, ObjectName name) {
this.server = server;
this.name = name;
+ }
+
+ public boolean canRun() throws DeploymentException {
+ return true;
}
public void perform() throws DeploymentException {
1.2 +6 -2 incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/CreateClassSpace.java
Index: CreateClassSpace.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/CreateClassSpace.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- CreateClassSpace.java 11 Aug 2003 17:59:10 -0000 1.1
+++ CreateClassSpace.java 14 Aug 2003 00:02:38 -0000 1.2
@@ -77,7 +77,7 @@
*
* @version $Revision$ $Date$
*/
-public class CreateClassSpace extends DeploymentTask {
+public class CreateClassSpace implements DeploymentTask {
private final Log log = LogFactory.getLog(this.getClass());
private final MBeanServer server;
private final ClassSpaceMetadata metadata;
@@ -86,6 +86,10 @@
public CreateClassSpace(MBeanServer server, ClassSpaceMetadata metadata) {
this.server = server;
this.metadata = metadata;
+ }
+
+ public boolean canRun() throws DeploymentException {
+ return true;
}
public void perform() throws DeploymentException {
1.2 +6 -2 incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/StartMBeanInstance.java
Index: StartMBeanInstance.java
===================================================================
RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/StartMBeanInstance.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- StartMBeanInstance.java 11 Aug 2003 17:59:10 -0000 1.1
+++ StartMBeanInstance.java 14 Aug 2003 00:02:38 -0000 1.2
@@ -68,13 +68,17 @@
*
* @version $Revision$ $Date$
*/
-public class StartMBeanInstance extends DeploymentTask {
+public class StartMBeanInstance implements DeploymentTask {
private final MBeanServer server;
private final ObjectName name;
public StartMBeanInstance(MBeanServer server, ObjectName name) {
this.server = server;
this.name = name;
+ }
+
+ public boolean canRun() throws DeploymentException {
+ return true;
}
public void perform() throws DeploymentException {
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/plan/InitializeMBeanInstance.java
Index: InitializeMBeanInstance.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.deployment.plan;
import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.relation.RelationServiceMBean;
import javax.management.relation.Role;
import javax.management.relation.RoleInfo;
import javax.management.relation.RoleList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.core.util.ClassUtil;
import org.apache.geronimo.deployment.DeploymentException;
import org.apache.geronimo.deployment.service.MBeanMetadata;
import org.apache.geronimo.deployment.service.MBeanOperation;
import org.apache.geronimo.deployment.service.MBeanRelationship;
import org.apache.geronimo.jmx.JMXUtil;
/**
*
*
* @version $Revision: 1.1 $ $Date: 2003/08/14 00:02:38 $
*/
public class InitializeMBeanInstance implements DeploymentTask {
private final Log log = LogFactory.getLog(this.getClass());
private final Set plans;
private final MBeanServer server;
private final RelationServiceMBean relationService;
private final ObjectName parent;
private final ObjectName loaderName;
private final MBeanMetadata metadata;
private ObjectName objectName;
private boolean createCalled;
public InitializeMBeanInstance(Set plans, MBeanServer server, ObjectName objectName, ObjectName parent, MBeanMetadata metadata, ObjectName loaderName) {
this.plans = plans;
this.server = server;
this.objectName = objectName;
this.parent = parent;
this.metadata = metadata;
this.loaderName = loaderName;
relationService = JMXUtil.getRelationService(server);
}
public boolean canRun() throws DeploymentException {
boolean canRun = true;
if (!server.isRegistered(objectName)) {
log.trace("Plan can run because MBean has been unregistered. Plan will execute but will do nothing");
return true;
}
Set relationships = metadata.getRelationships();
for (Iterator i = relationships.iterator(); i.hasNext();) {
MBeanRelationship relationship = (MBeanRelationship) i.next();
// if there is no existing relationship...
String relationshipName = relationship.getName();
if (!relationService.hasRelation(relationshipName).booleanValue()) {
// check if the relationship type has been registered
String relationshipType = relationship.getType();
if (!relationService.getAllRelationTypeNames().contains(relationshipType)) {
log.trace("Cannot run because relationship type is not registered: relationType=" + relationshipType);
canRun = false;
}
// if we have a target, check that is is registered
String target = relationship.getTarget();
if (target != null && target.length() > 0) {
try {
if (!server.isRegistered(new ObjectName(target))) {
log.trace("Cannot run because relationship target object is not registered: target=" + target);
canRun = false;
}
} catch (MalformedObjectNameException e) {
throw new DeploymentException("Target is not a valid ObjectName: target=" + target);
}
}
}
}
return canRun;
}
public void perform() throws DeploymentException {
if (!server.isRegistered(objectName)) {
return;
}
ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
ClassLoader newCL;
// create an MBean instance
try {
// Get the class loader
try {
newCL = server.getClassLoader(loaderName);
Thread.currentThread().setContextClassLoader(newCL);
} catch (InstanceNotFoundException e) {
throw new DeploymentException(e);
}
// Resolve and enroll in all relationships
Set relationships = metadata.getRelationships();
try {
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();
String relationshipRole = relationship.getRole();
if (!relationService.hasRelation(relationshipName).booleanValue()) {
// if we don't have a relationship of the
String relationshipType = relationship.getType();
if (!relationService.getAllRelationTypeNames().contains(relationshipType)) {
throw new DeploymentException("Relationship type is not registered: relationType=" + relationshipType);
}
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
String target = relationship.getTarget();
if (target != null && target.length() > 0) {
String targetRoleName = relationship.getTargetRole();
if (targetRoleName == null || targetRoleName.length() == 0) {
List roles = relationService.getRoleInfos(relationshipType);
if (roles.size() < 2) {
throw new DeploymentException("Relationship has less than two roles. You cannot specify a target");
}
if (roles.size() > 2) {
throw new DeploymentException("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(new ObjectName(target))));
}
relationService.createRelation(relationshipName, relationshipType, roleList);
} else {
// We have an exiting relationship -- just add to the existing role
List members = relationService.getRole(relationshipName, relationshipRole);
members.add(objectName);
relationService.setRole(relationshipName, new Role(relationshipRole, members));
}
}
} catch (DeploymentException e) {
throw e;
} catch (Exception e) {
throw new DeploymentException(e);
}
// Invoke the create callback method
try {
server.invoke(objectName, "create", null, null);
createCalled = true;
} catch (RuntimeException e) {
throw new DeploymentException(e);
} catch (InstanceNotFoundException e) {
throw new DeploymentException(e);
} catch (MBeanException e) {
throw new DeploymentException(e);
} catch (ReflectionException e) {
if (e.getTargetException() instanceof NoSuchMethodException) {
// did not have a create method - ok
} else {
throw new DeploymentException(e);
}
}
// Add a deployment plan to start the MBean
DeploymentPlan startPlan = new DeploymentPlan();
startPlan.addTask(new StartMBeanInstance(server, objectName));
List operations = metadata.getOperations();
for (Iterator i = operations.iterator(); i.hasNext();) {
MBeanOperation operation = (MBeanOperation) i.next();
int argCount = operation.getTypes().size();
String[] argTypes = (String[]) operation.getTypes().toArray(new String[argCount]);
List values = operation.getArgs();
Object[] args = new Object[argCount];
for (int j = 0; j < argCount; j++) {
Object value = values.get(j);
if (value instanceof String) {
value = getValue(newCL, argTypes[j], (String) value);
}
args[j] = value;
}
startPlan.addTask(new InvokeMBeanOperation(server, objectName, operation.getOperation(), argTypes, args));
}
plans.add(startPlan);
} catch (DeploymentException e) {
undo();
throw e;
} finally {
Thread.currentThread().setContextClassLoader(oldCL);
}
}
public void undo() {
if (objectName == null) {
return;
}
try {
if (createCalled) {
server.invoke(objectName, "destroy", null, null);
}
} catch (InstanceNotFoundException e) {
log.warn("MBean was already removed " + objectName, e);
return;
} catch (MBeanException e) {
log.error("Error while destroying MBean " + objectName, e);
} catch (ReflectionException e) {
if (e.getTargetException() instanceof NoSuchMethodException) {
// did not have a destroy method - ok
} else {
log.error("Error while destroying MBean " + objectName, e);
}
}
try {
server.invoke(parent, "removeChild", new Object[]{objectName}, new String[]{"javax.management.ObjectName"});
} catch (InstanceNotFoundException e) {
log.warn("Could not remove from parent", e);
} catch (MBeanException e) {
log.error("Error while removing MBean " + objectName + " from parent", e);
} catch (ReflectionException e) {
log.error("Error while removing MBean " + objectName + " from parent", e);
}
try {
server.unregisterMBean(objectName);
} catch (InstanceNotFoundException e) {
log.warn("MBean was already removed " + objectName, e);
return;
} catch (MBeanRegistrationException e) {
log.error("Error while unregistering MBean " + objectName, e);
}
}
private static final Class[] stringArg = new Class[]{String.class};
private Object getValue(ClassLoader cl, String typeName, String value) throws DeploymentException {
Class attrType = null;
try {
attrType = ClassUtil.getClassForName(cl, typeName);
} catch (ClassNotFoundException e) {
throw new DeploymentException(e);
}
// try a property editor
PropertyEditor editor = PropertyEditorManager.findEditor(attrType);
if (editor != null) {
editor.setAsText(value);
return editor.getValue();
}
// try a String constructor
try {
Constructor cons = attrType.getConstructor(stringArg);
return cons.newInstance(new Object[]{value});
} catch (Exception e) {
throw new DeploymentException("Could not create value of type " + typeName);
}
}
public String toString() {
return "InitailizeMBeanInstance " + metadata.getName();
}
}