001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ha.singleton;
023:
024: import java.security.InvalidParameterException;
025:
026: import javax.management.InstanceNotFoundException;
027: import javax.management.JMException;
028: import javax.management.MBeanException;
029: import javax.management.ObjectName;
030: import javax.management.ReflectionException;
031:
032: /**
033: * A clustered singleton service that calls a configurable
034: * method on a target mbean, whenever the current node becomes
035: * the master. Correspondigly, it calls a configurable method
036: * on the target mbean, whenever the current node resigns from
037: * being the master.
038: *
039: * Optional string arguments may be passed to those methods.
040: *
041: * The prevailing usage of this MBean is to deploy on the
042: * master node the content of the deploy-hasingleton directory.
043: *
044: * @author <a href="mailto:ivelin@apache.org">Ivelin Ivanov</a>
045: * @author <a href="mailto:scott.stark@jboss.org">Scott Stark</a>
046: * @author <a href="mailto:mr@gedoplan.de">Marcus Redeker</a>
047: * @author <a href="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
048: * @version $Revision: 57188 $
049: */
050: public class HASingletonController extends HASingletonSupport implements
051: HASingletonControllerMBean {
052: // Private Data --------------------------------------------------
053:
054: private ObjectName mSingletonMBean;
055: private String mSingletonMBeanStartMethod = "startSingleton";
056: private String mSingletonMBeanStopMethod = "stopSingleton";
057: private String mSingletonMBeanStartMethodArgument;
058: private String mSingletonMBeanStopMethodArgument;
059:
060: private static final Object[] NO_ARGS = new Object[0];
061: private static final String[] NO_TYPES = new String[0];
062:
063: // Constructors --------------------------------------------------
064:
065: /**
066: * Default CTOR
067: */
068: public HASingletonController() {
069: // empty
070: }
071:
072: // Attributes ----------------------------------------------------
073:
074: public ObjectName getTargetName() {
075: return mSingletonMBean;
076: }
077:
078: public void setTargetName(ObjectName targetObjectName) {
079: this .mSingletonMBean = targetObjectName;
080: }
081:
082: public String getTargetStartMethod() {
083: return mSingletonMBeanStartMethod;
084: }
085:
086: public void setTargetStartMethod(String targetStartMethod)
087: throws InvalidParameterException {
088: if (targetStartMethod != null)
089: mSingletonMBeanStartMethod = targetStartMethod;
090: }
091:
092: public String getTargetStopMethod() {
093: return mSingletonMBeanStopMethod;
094: }
095:
096: public void setTargetStopMethod(String targetStopMethod)
097: throws InvalidParameterException {
098: if (targetStopMethod != null)
099: mSingletonMBeanStopMethod = targetStopMethod;
100: }
101:
102: public String getTargetStartMethodArgument() {
103: return mSingletonMBeanStartMethodArgument;
104: }
105:
106: public void setTargetStartMethodArgument(
107: String targetStartMethodArgument) {
108: mSingletonMBeanStartMethodArgument = targetStartMethodArgument;
109: }
110:
111: public String getTargetStopMethodArgument() {
112: return mSingletonMBeanStopMethodArgument;
113: }
114:
115: public void setTargetStopMethodArgument(
116: String targetStopMethodArgument) {
117: mSingletonMBeanStopMethodArgument = targetStopMethodArgument;
118: }
119:
120: // HASingleton implementation ------------------------------------
121:
122: /**
123: * Call the target start method
124: *
125: * @see org.jboss.ha.singleton.HASingletonSupport#startSingleton()
126: */
127: public void startSingleton() {
128: super .startSingleton();
129:
130: try {
131: invokeSingletonMBeanMethod(mSingletonMBean,
132: mSingletonMBeanStartMethod,
133: mSingletonMBeanStartMethodArgument);
134: } catch (JMException jme) {
135: log
136: .error(
137: "Controlled Singleton MBean failed to become master",
138: jme);
139: }
140: }
141:
142: /**
143: * Call the target stop method
144: *
145: * @see org.jboss.ha.singleton.HASingletonSupport#stopSingleton()
146: */
147: public void stopSingleton() {
148: super .stopSingleton();
149:
150: try {
151: invokeSingletonMBeanMethod(mSingletonMBean,
152: mSingletonMBeanStopMethod,
153: mSingletonMBeanStopMethodArgument);
154: } catch (JMException jme) {
155: log
156: .error(
157: "Controlled Singleton MBean failed to resign from master position",
158: jme);
159: }
160: }
161:
162: // Protected -----------------------------------------------------
163:
164: protected Object invokeSingletonMBeanMethod(ObjectName target,
165: String operationName, Object param)
166: throws InstanceNotFoundException, MBeanException,
167: ReflectionException {
168: if (target != null && operationName != null) {
169: Object[] params;
170: String[] signature;
171:
172: if (param != null) {
173: params = new Object[] { param };
174: signature = new String[] { param.getClass().getName() };
175:
176: log.debug("Calling operation: " + operationName + "("
177: + param + "), on target: '" + target + "'");
178: } else {
179: params = NO_ARGS;
180: signature = NO_TYPES;
181:
182: log.debug("Calling operation: " + operationName
183: + "(), on target: '" + target + "'");
184: }
185:
186: return server.invoke(target, operationName, params,
187: signature);
188: } else {
189: log
190: .debug("No configured target mbean or operation to call");
191:
192: return null;
193: }
194: }
195: }
|