001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)Deployer.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package com.sun.jbi.framework;
030:
031: import com.sun.jbi.ServiceUnitState;
032: import com.sun.jbi.StringTranslator;
033: import com.sun.jbi.management.registry.Registry;
034:
035: import java.util.List;
036: import java.util.logging.Level;
037: import java.util.logging.Logger;
038:
039: import javax.jbi.component.ServiceUnitManager;
040:
041: /**
042: * This class implements the DeployerMBean for a component (BC or SE). This
043: * MBean acts as an agent between the Deployment Service, the Component
044: * Registry, and the component's Service Unit Manager to coordinate the
045: * registration and unregistration of Service Units, the maintenance of the
046: * states of Service Units, and the control of the Service Unit life cycle.
047: * Methods in this class interact directly with the Component Registry and
048: * the component's Service Unit Manager implementation.
049: *
050: * Direct calls to the component's Service Unit Manager are protected by a
051: * timeout, so that ill-behaved components cannot hang the system. The
052: * <CODE>deploy</CODE>, <CODE>undeploy</CODE>, <CODE>init</CODE>,
053: * <CODE>start</CODE>, <CODE>stop</CODE>, and <CODE>shutDown</CODE> methods
054: * are all called under timeout protection.
055: *
056: * @author Sun Microsystems, Inc.
057: */
058: public class Deployer implements DeployerMBean {
059: /**
060: * The Component instance representing this component.
061: */
062: private Component mComponent;
063:
064: /**
065: * The ComponentRegistry handle.
066: */
067: private ComponentRegistry mComponentRegistry;
068:
069: /**
070: * The ComponentStatistics instance representing this component.
071: */
072: private ComponentStatistics mComponentStatistics;
073:
074: /**
075: * The EnvironmentContext handle.
076: */
077: private EnvironmentContext mEnv;
078:
079: /**
080: * The Logger instance for logging.
081: */
082: private Logger mLog;
083:
084: /**
085: * The ServiceUnitManager instance for this component.
086: */
087: private ServiceUnitManager mSuMgr;
088:
089: /**
090: * The StringTranslator for constructing messages.
091: */
092: private StringTranslator mTranslator;
093:
094: /**
095: * Constructor.
096: * @param component is the instance representing the component with which
097: * this deployer is associated.
098: */
099: Deployer(Component component) {
100: mComponent = component;
101: mComponentStatistics = component.getStatisticsInstance();
102: mEnv = EnvironmentContext.getInstance();
103: mComponentRegistry = mEnv.getComponentRegistry();
104: mLog = mEnv.getLogger();
105: mSuMgr = null;
106: mTranslator = mEnv.getStringTranslatorFor(this );
107:
108: }
109:
110: //
111: // Public methods from the com.sun.jbi.framework.DeployerMBean interface
112: //
113:
114: /**
115: * Deploy a Service Unit to the component.
116: *
117: * @param serviceUnitName the unique name of the Service Unit being
118: * deployed.
119: * @param serviceUnitRootPath the full path to the deployment descriptor
120: * for this Service Unit.
121: * @throws javax.jbi.management.DeploymentException if the Service Unit is
122: * not successfully deployed.
123: * @return A status message.
124: */
125: public String deploy(String serviceUnitName,
126: String serviceUnitRootPath)
127: throws javax.jbi.management.DeploymentException {
128: if (null == serviceUnitName) {
129: String msg = mTranslator.getString(
130: LocalStringKeys.NULL_ARGUMENT, "serviceUnitName");
131: mLog.severe(msg);
132: throw new java.lang.IllegalArgumentException(buildMessage(
133: "deploy", msg));
134: }
135:
136: if (null == serviceUnitRootPath) {
137: String msg = mTranslator.getString(
138: LocalStringKeys.NULL_ARGUMENT,
139: "serviceUnitRootPath");
140: mLog.severe(msg);
141: throw new java.lang.IllegalArgumentException(buildMessage(
142: "deploy", msg));
143: }
144:
145: if (mComponent.isServiceUnitRegistered(serviceUnitName)) {
146: String msg = mTranslator.getString(
147: LocalStringKeys.DMB_SU_ALREADY_DEPLOYED,
148: serviceUnitName);
149: mLog.warning(msg);
150: throw new javax.jbi.management.DeploymentException(
151: buildMessage("deploy", msg));
152: }
153:
154: // Disallow operation if component is not started
155: checkComponentState(serviceUnitName, "deploy");
156:
157: if (statisticsEnabled()) {
158: mComponentStatistics.incrementDeploySURequests();
159: }
160: mLog.finer("Calling deploy() for Service Unit "
161: + serviceUnitName + " on "
162: + mComponent.getComponentTypeAsString() + " "
163: + mComponent.getName());
164: String status = performOperation(ServiceUnitOperation.DEPLOY,
165: mEnv.getDeploymentTimeout(), "deploy", serviceUnitName,
166: serviceUnitRootPath);
167: if (statisticsEnabled()) {
168: mComponentStatistics.incrementDeployedSUs();
169: }
170: return status;
171: }
172:
173: /**
174: * Returns a list of the names all Service Units currently deployed to
175: * this component.
176: *
177: * @return An array of Strings containing the names of the Service Units.
178: * The array is empty if no Service Units are deployed.
179: */
180: public String[] getDeployments() {
181: List sus = mComponent.getServiceUnitList();
182: int suCount = sus.size();
183: String[] names = new String[suCount];
184: if (0 < suCount) {
185: for (int i = 0; i < suCount; i++) {
186: names[i] = ((ServiceUnit) sus.get(i)).getName();
187: }
188: }
189: return names;
190: }
191:
192: /**
193: * Returns the current state of a Service Unit.
194: * @param serviceUnitName the unique name of the Service Unit.
195: * @return the current state of the Service Unit as one of the values in
196: * ServiceUnitState, or ServiceUnitState.UNKNOWN if the Service Unit is
197: * not found.
198: */
199: public ServiceUnitState getServiceUnitState(String serviceUnitName) {
200: if (null == serviceUnitName) {
201: String msg = mTranslator.getString(
202: LocalStringKeys.NULL_ARGUMENT, "serviceUnitName");
203: mLog.severe(msg);
204: throw new java.lang.IllegalArgumentException(buildMessage(
205: "getServiceUnitState", msg));
206: }
207: ServiceUnit su = mComponent.getServiceUnit(serviceUnitName);
208: if (null != su) {
209: return su.getState();
210: } else {
211: return ServiceUnitState.UNKNOWN;
212: }
213: }
214:
215: /**
216: * Returns a boolean value indicating whether the specified Service Unit
217: * is currently deployed.
218: * @param serviceUnitName the unique name of the Service Unit.
219: * @return true if the Service Unit is deployed, false if not.
220: */
221: public boolean isDeployed(String serviceUnitName) {
222: if (null == serviceUnitName) {
223: String msg = mTranslator.getString(
224: LocalStringKeys.NULL_ARGUMENT, "serviceUnitName");
225: mLog.severe(msg);
226: throw new java.lang.IllegalArgumentException(buildMessage(
227: "isDeployed", msg));
228: }
229:
230: return mComponent.isServiceUnitRegistered(serviceUnitName);
231: }
232:
233: /**
234: * Initialize a Service Unit. This is the first phase of a two-phase
235: * start, where the component must prepare to receive service requests
236: * related to the Service Unit.
237: * @param serviceUnitName the name of the Service Unit being initialized.
238: * @param serviceUnitRootPath the absolute path to the directory, which
239: * has the extracted service unit contents.
240: * @throws javax.jbi.management.DeploymentException if the Service Unit is
241: * not deployed, or is in an incorrect state, or if the component is not
242: * started.
243: */
244: public void init(String serviceUnitName, String serviceUnitRootPath)
245: throws javax.jbi.management.DeploymentException {
246: if (null == serviceUnitName) {
247: String msg = mTranslator.getString(
248: LocalStringKeys.NULL_ARGUMENT, "serviceUnitName");
249: mLog.severe(msg);
250: throw new java.lang.IllegalArgumentException(buildMessage(
251: "init", msg));
252: }
253:
254: if (null == serviceUnitRootPath) {
255: String msg = mTranslator.getString(
256: LocalStringKeys.NULL_ARGUMENT,
257: "serviceUnitRootPath");
258: mLog.severe(msg);
259: throw new java.lang.IllegalArgumentException(buildMessage(
260: "init", msg));
261: }
262:
263: ServiceUnit su = mComponent.getServiceUnit(serviceUnitName);
264: if (null == su) {
265: String msg = mTranslator.getString(
266: LocalStringKeys.DMB_SU_NOT_FOUND, serviceUnitName);
267: mLog.warning(msg);
268: throw new javax.jbi.management.DeploymentException(
269: buildMessage("init", msg));
270: }
271:
272: // Disallow operation if component is not started
273: checkComponentState(serviceUnitName, "init");
274:
275: if (su.isStarted()) {
276: String msg = mTranslator.getString(
277: LocalStringKeys.DMB_SU_CANNOT_INIT_STARTED,
278: serviceUnitName);
279: mLog.warning(msg);
280: throw new javax.jbi.management.DeploymentException(
281: buildMessage("init", msg));
282: }
283:
284: try {
285: su.setDesiredState(ServiceUnitState.STOPPED);
286: if (su.isShutdown()) {
287: if (statisticsEnabled()) {
288: mComponentStatistics.incrementInitSURequests();
289: }
290: mLog.finer("Calling init() for Service Unit "
291: + serviceUnitName + " on "
292: + mComponent.getComponentTypeAsString() + " "
293: + mComponent.getName());
294: performOperation(ServiceUnitOperation.INIT, mEnv
295: .getServiceUnitTimeout(), "init",
296: serviceUnitName, serviceUnitRootPath);
297: su.setStopped();
298: }
299: } finally {
300: persistState(su, "init");
301: }
302: }
303:
304: /**
305: * Shut down a Service Unit. This causes the Service Unit to return to the
306: * state it was in after <code>deploy()</code> and before <code>init()</code>.
307: * @param serviceUnitName the name of the Service Unit being shut down.
308: * @throws javax.jbi.management.DeploymentException if the Service Unit
309: * is not deployed, or is in an incorrect state, or if the component is
310: * not started.
311: */
312: public void shutDown(String serviceUnitName)
313: throws javax.jbi.management.DeploymentException {
314: shutDown(serviceUnitName, false);
315: }
316:
317: /**
318: * Shut down a Service Unit. This causes the Service Unit to return to the
319: * state it was in after <code>deploy()</code> and before <code>init()</code>.
320: * @param serviceUnitName the name of the Service Unit being shut down.
321: * @param force set to true to force the shutdown regardless of state.
322: * @throws javax.jbi.management.DeploymentException if the Service Unit
323: * is not deployed, or is in an incorrect state, or if the component is
324: * not started.
325: */
326: public void shutDown(String serviceUnitName, boolean force)
327: throws javax.jbi.management.DeploymentException {
328: if (null == serviceUnitName) {
329: String msg = mTranslator.getString(
330: LocalStringKeys.NULL_ARGUMENT, "serviceUnitName");
331: mLog.severe(msg);
332: throw new java.lang.IllegalArgumentException(buildMessage(
333: "shutDown", msg));
334: }
335:
336: ServiceUnit su = mComponent.getServiceUnit(serviceUnitName);
337: if (null == su) {
338: String msg = mTranslator.getString(
339: LocalStringKeys.DMB_SU_NOT_FOUND, serviceUnitName);
340: mLog.warning(msg);
341: throw new javax.jbi.management.DeploymentException(
342: buildMessage("shutDown", msg));
343: }
344:
345: // Disallow operation if component is not started
346: checkComponentState(serviceUnitName, "shutDown");
347:
348: if (su.isStarted() && !force) {
349: String msg = mTranslator
350: .getString(
351: LocalStringKeys.DMB_SU_CANNOT_SHUT_DOWN_NOT_STOPPED,
352: serviceUnitName);
353: mLog.warning(msg);
354: throw new javax.jbi.management.DeploymentException(
355: buildMessage("shutDown", msg));
356: }
357:
358: su.setDesiredState(ServiceUnitState.SHUTDOWN);
359:
360: // If the SU is started, this must be a forced shutdown. Attempt
361: // to stop the SU just for completeness. Set the SU to stopped
362: // state regardless of the outcome.
363:
364: if (su.isStarted()) {
365: if (statisticsEnabled()) {
366: mComponentStatistics.incrementStopSURequests();
367: }
368: try {
369: mLog.finer("Calling stop() for Service Unit "
370: + serviceUnitName + " on "
371: + mComponent.getComponentTypeAsString() + " "
372: + mComponent.getName());
373: performOperation(ServiceUnitOperation.STOP, mEnv
374: .getServiceUnitTimeout(), "stop",
375: serviceUnitName, null);
376: } catch (javax.jbi.management.DeploymentException dEx) {
377: // ignore this exception
378: } finally {
379: su.setStopped();
380: }
381: }
382:
383: if (su.isStopped()) {
384: if (statisticsEnabled()) {
385: mComponentStatistics.incrementShutDownSURequests();
386: }
387: try {
388: mLog.finer("Calling shutDown() for Service Unit "
389: + serviceUnitName + " on "
390: + mComponent.getComponentTypeAsString() + " "
391: + mComponent.getName());
392: performOperation(ServiceUnitOperation.SHUTDOWN, mEnv
393: .getServiceUnitTimeout(), "shutDown",
394: serviceUnitName, null);
395: su.setShutdown();
396: mEnv.getNotifier().emitServiceUnitNotification(
397: EventNotifier.EventType.ShutDown,
398: serviceUnitName,
399: mComponent.getName(),
400: su.getServiceAssemblyName(),
401: mTranslator.getString(
402: LocalStringKeys.SUF_SHUT_DOWN,
403: serviceUnitName, mComponent.getName(),
404: su.getServiceAssemblyName()));
405: } catch (javax.jbi.management.DeploymentException dEx) {
406: if (!force) {
407: throw dEx;
408: } else {
409: su.setShutdown();
410: }
411: } finally {
412: persistState(su, "shutDown");
413: }
414: }
415: }
416:
417: /**
418: * Start a Service Unit. This is the second phase of a two-phase start,
419: * where the component can now initiate service requests related to the
420: * Service Unit.
421: * @param serviceUnitName the name of the Service Unit being started.
422: * @throws javax.jbi.management.DeploymentException if the Service Unit
423: * is not deployed, or is in an incorrect state, or if the component is
424: * not started.
425: */
426: public void start(String serviceUnitName)
427: throws javax.jbi.management.DeploymentException {
428: if (null == serviceUnitName) {
429: String msg = mTranslator.getString(
430: LocalStringKeys.NULL_ARGUMENT, "serviceUnitName");
431: mLog.severe(msg);
432: throw new java.lang.IllegalArgumentException(buildMessage(
433: "start", msg));
434: }
435:
436: ServiceUnit su = mComponent.getServiceUnit(serviceUnitName);
437: if (null == su) {
438: String msg = mTranslator.getString(
439: LocalStringKeys.DMB_SU_NOT_FOUND, serviceUnitName);
440: mLog.warning(msg);
441: throw new javax.jbi.management.DeploymentException(
442: buildMessage("start", msg));
443: }
444:
445: // Disallow operation if component is not started
446: checkComponentState(serviceUnitName, "start");
447:
448: if (su.isShutdown()) {
449: String msg = mTranslator
450: .getString(
451: LocalStringKeys.DMB_SU_CANNOT_START_NOT_INITIALIZED,
452: serviceUnitName);
453: mLog.warning(msg);
454: throw new javax.jbi.management.DeploymentException(
455: buildMessage("start", msg));
456: }
457:
458: try {
459: su.setDesiredState(ServiceUnitState.STARTED);
460: if (su.isStopped()) {
461: if (statisticsEnabled()) {
462: mComponentStatistics.incrementStartSURequests();
463: }
464: mLog.finer("Calling start() for Service Unit "
465: + serviceUnitName + " on "
466: + mComponent.getComponentTypeAsString() + " "
467: + mComponent.getName());
468: performOperation(ServiceUnitOperation.START, mEnv
469: .getServiceUnitTimeout(), "start",
470: serviceUnitName, null);
471: su.setStarted();
472: mEnv.getNotifier().emitServiceUnitNotification(
473: EventNotifier.EventType.Started,
474: serviceUnitName,
475: mComponent.getName(),
476: su.getServiceAssemblyName(),
477: mTranslator.getString(
478: LocalStringKeys.SUF_STARTED,
479: serviceUnitName, mComponent.getName(),
480: su.getServiceAssemblyName()));
481: }
482: } finally {
483: persistState(su, "start");
484: }
485: }
486:
487: /**
488: * Stop a Service Unit. This causes the component to cease generating
489: * service requests related to the Service Unit. It returns the Service Unit
490: * to a state equivalent to after <code>init()</code> was called.
491: * @param serviceUnitName the name of the Service Unit being stopped.
492: * @throws javax.jbi.management.DeploymentException if the Service Unit
493: * is not deployed, or is in an incorrect state, or if the component is
494: * not started.
495: */
496: public void stop(String serviceUnitName)
497: throws javax.jbi.management.DeploymentException {
498: if (null == serviceUnitName) {
499: String msg = mTranslator.getString(
500: LocalStringKeys.NULL_ARGUMENT, "serviceUnitName");
501: mLog.severe(msg);
502: throw new java.lang.IllegalArgumentException(buildMessage(
503: "stop", msg));
504: }
505:
506: ServiceUnit su = mComponent.getServiceUnit(serviceUnitName);
507: if (null == su) {
508: String msg = mTranslator.getString(
509: LocalStringKeys.DMB_SU_NOT_FOUND, serviceUnitName);
510: mLog.warning(msg);
511: throw new javax.jbi.management.DeploymentException(
512: buildMessage("stop", msg));
513: }
514:
515: // Disallow operation if component is not started
516: checkComponentState(serviceUnitName, "stop");
517:
518: if (su.isShutdown()) {
519: String msg = mTranslator.getString(
520: LocalStringKeys.DMB_SU_CANNOT_STOP_SHUT_DOWN,
521: serviceUnitName);
522: mLog.warning(msg);
523: throw new javax.jbi.management.DeploymentException(
524: buildMessage("stop", msg));
525: }
526:
527: try {
528: su.setDesiredState(ServiceUnitState.STOPPED);
529: if (su.isStarted()) {
530: if (statisticsEnabled()) {
531: mComponentStatistics.incrementStopSURequests();
532: }
533: mLog.finer("Calling stop() for Service Unit "
534: + serviceUnitName + " on "
535: + mComponent.getComponentTypeAsString() + " "
536: + mComponent.getName());
537: performOperation(ServiceUnitOperation.STOP, mEnv
538: .getServiceUnitTimeout(), "stop",
539: serviceUnitName, null);
540: su.setStopped();
541: mEnv.getNotifier().emitServiceUnitNotification(
542: EventNotifier.EventType.Stopped,
543: serviceUnitName,
544: mComponent.getName(),
545: su.getServiceAssemblyName(),
546: mTranslator.getString(
547: LocalStringKeys.SUF_STOPPED,
548: serviceUnitName, mComponent.getName(),
549: su.getServiceAssemblyName()));
550: }
551: } finally {
552: persistState(su, "stop");
553: }
554: }
555:
556: /**
557: * Undeploy a Service Unit from the component.
558: * @param serviceUnitName the unique name of the Service Unit being
559: * undeployed.
560: * @param serviceUnitRootPath the full path to the deployment descriptor
561: * for this Service Unit.
562: * @throws javax.jbi.management.DeploymentException if the Service Unit is
563: * not successfully undeployed.
564: * @return A status message.
565: */
566: public String undeploy(String serviceUnitName,
567: String serviceUnitRootPath)
568: throws javax.jbi.management.DeploymentException {
569: return undeploy(serviceUnitName, serviceUnitRootPath, false);
570: }
571:
572: /**
573: * Undeploy a Service Unit from the component.
574: * @param serviceUnitName the unique name of the Service Unit being
575: * undeployed.
576: * @param serviceUnitRootPath the full path to the deployment descriptor
577: * for this Service Unit.
578: * @param force set to true to force the undeploy regardless of any
579: * conditions.
580: * @throws javax.jbi.management.DeploymentException if the Service Unit is
581: * not successfully undeployed.
582: * @return A status message.
583: */
584: public String undeploy(String serviceUnitName,
585: String serviceUnitRootPath, boolean force)
586: throws javax.jbi.management.DeploymentException {
587: if (null == serviceUnitName) {
588: String msg = mTranslator.getString(
589: LocalStringKeys.NULL_ARGUMENT, "serviceUnitName");
590: mLog.severe(msg);
591: throw new java.lang.IllegalArgumentException(buildMessage(
592: "undeploy", msg));
593: }
594:
595: if (null == serviceUnitRootPath) {
596: String msg = mTranslator.getString(
597: LocalStringKeys.NULL_ARGUMENT,
598: "serviceUnitRootPath");
599: mLog.severe(msg);
600: throw new java.lang.IllegalArgumentException(buildMessage(
601: "undeploy", msg));
602: }
603:
604: // Disallow operation if component is not started and force is not
605: // specified
606: if (!force) {
607: checkComponentState(serviceUnitName, "undeploy");
608: }
609:
610: ServiceUnit su = mComponent.getServiceUnit(serviceUnitName);
611: if (null == su) {
612: String msg = mTranslator.getString(
613: LocalStringKeys.DMB_SU_NOT_FOUND, serviceUnitName);
614: mLog.warning(msg);
615: throw new javax.jbi.management.DeploymentException(
616: buildMessage("undeploy", msg));
617: }
618:
619: if (!su.isShutdown()) {
620: String msg = mTranslator
621: .getString(
622: LocalStringKeys.DMB_SU_CANNOT_UNDEPLOY_NOT_SHUT_DOWN,
623: serviceUnitName, su.getStateAsString());
624: mLog.warning(msg);
625: throw new javax.jbi.management.DeploymentException(
626: buildMessage("undeploy", msg));
627: }
628:
629: String status = "";
630:
631: if (!force) {
632: // Normal undeploy
633: if (statisticsEnabled()) {
634: mComponentStatistics.incrementUndeploySURequests();
635: }
636: mLog.finer("Calling undeploy() for Service Unit "
637: + serviceUnitName + " on "
638: + mComponent.getComponentTypeAsString() + " "
639: + mComponent.getName());
640: status = performOperation(ServiceUnitOperation.UNDEPLOY,
641: mEnv.getDeploymentTimeout(), "undeploy",
642: serviceUnitName, serviceUnitRootPath);
643: if (statisticsEnabled()) {
644: mComponentStatistics.decrementDeployedSUs();
645: }
646: } else {
647: // Forced undeploy - must complete even if component is not started
648: if (mComponent.isStarted()) {
649: if (statisticsEnabled()) {
650: mComponentStatistics.incrementUndeploySURequests();
651: }
652: try {
653: mLog.finer("Calling undeploy() for Service Unit "
654: + su.getName() + " on "
655: + mComponent.getComponentTypeAsString()
656: + " " + mComponent.getName());
657: performOperation(ServiceUnitOperation.UNDEPLOY,
658: mEnv.getDeploymentTimeout(), "undeploy",
659: serviceUnitName, serviceUnitRootPath);
660: } catch (javax.jbi.management.DeploymentException dEx) {
661: // Ignore the exception
662: }
663: }
664:
665: // Always decrement the number of deployed SUs and return a SUCCESS
666: // message
667:
668: status = buildSuccessMessage("undeploy");
669: if (statisticsEnabled()) {
670: mComponentStatistics.decrementDeployedSUs();
671: }
672: }
673: return status;
674: }
675:
676: //
677: // Package-only methods
678: //
679:
680: /**
681: * Set the ServiceUnitManager reference for this instance.
682: * @param suManager the instance of javax.jbi.component.ServiceUnitManager
683: * returned by the by the component's javax.jbi.component.Component.
684: * getServiceUnitManager() method.
685: */
686: void setServiceUnitManager(ServiceUnitManager suManager)
687: throws javax.jbi.management.DeploymentException {
688: mSuMgr = suManager;
689: }
690:
691: //
692: // Private methods
693: //
694:
695: /**
696: * Construct a message compliant with the defined schema for messages.
697: * The assumption is that any message in the exception is a JBI message
698: * with a 9-character message ID, with or without a colon separator. The
699: * message ID is extracted and provided in the loc-token element, and
700: * the message text is extracted and provided in the loc-message element.
701: * @param task the failing task.
702: * @param msg the message text.
703: * @return an XML string containing the message in the correct format.
704: */
705: private String buildMessage(String task, String msg) {
706: int end = msg.indexOf(":");
707: if (0 < end) {
708: end = msg.indexOf(" ");
709: }
710: StringBuffer returnMsg = new StringBuffer();
711: returnMsg
712: .append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
713: returnMsg.append("<component-task-result>");
714: returnMsg.append("<component-name>");
715: returnMsg.append(mComponent.getName());
716: returnMsg.append("</component-name>");
717: returnMsg.append("<component-task-result-details>");
718: returnMsg.append("<task-result-details>");
719: returnMsg.append("<task-id>");
720: returnMsg.append(task);
721: returnMsg.append("</task-id>");
722: returnMsg.append("<task-result>FAILED</task-result>");
723: returnMsg.append("<message-type>ERROR</message-type>");
724: returnMsg.append("<task-status-msg>");
725: returnMsg.append("<msg-loc-info>");
726: returnMsg.append("<loc-token>");
727: returnMsg.append(msg.substring(0, end - 1).trim());
728: returnMsg.append("</loc-token>");
729: returnMsg.append("<loc-message>");
730: returnMsg.append(msg.substring(end + 1).trim());
731: returnMsg.append("</loc-message>");
732: returnMsg.append("</msg-loc-info>");
733: returnMsg.append("</task-status-msg>");
734: returnMsg.append("</task-result-details>");
735: returnMsg.append("</component-task-result-details>");
736: returnMsg.append("</component-task-result>");
737:
738: return returnMsg.toString();
739: }
740:
741: /**
742: * Construct a success message compliant with the defined schema for
743: * messages.
744: * @param task the successful task.
745: * @return an XML string containing the message in the correct format.
746: */
747: private String buildSuccessMessage(String task) {
748: StringBuffer returnMsg = new StringBuffer();
749: returnMsg
750: .append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
751: returnMsg.append("<component-task-result>");
752: returnMsg.append("<component-name>");
753: returnMsg.append(mComponent.getName());
754: returnMsg.append("</component-name>");
755: returnMsg.append("<component-task-result-details>");
756: returnMsg.append("<task-result-details>");
757: returnMsg.append("<task-id>");
758: returnMsg.append(task);
759: returnMsg.append("</task-id>");
760: returnMsg.append("<task-result>SUCCESS</task-result>");
761: returnMsg.append("</task-result-details>");
762: returnMsg.append("</component-task-result-details>");
763: returnMsg.append("</component-task-result>");
764:
765: return returnMsg.toString();
766: }
767:
768: /**
769: * Check to make sure the component is in started state.
770: * @param suName the name of the SU being operated upon.
771: * @param oper the name of the operation being requested.
772: * @throws javax.jbi.management.DeploymentException if the component is
773: * not in started state.
774: */
775: private void checkComponentState(String suName, String oper)
776: throws javax.jbi.management.DeploymentException {
777: if (!mComponent.isStarted()) {
778: String msg = mTranslator.getString(
779: LocalStringKeys.DMB_SU_COMP_NOT_STARTED, oper,
780: suName);
781: mLog.warning(msg);
782: throw new javax.jbi.management.DeploymentException(
783: buildMessage(oper, msg));
784: }
785: }
786:
787: /**
788: * Perform the specified operation on the Service Unit and wait for it to
789: * complete or time out.
790: * @param operation the operation to be performed.
791: * @param timeout the timeout interval for the operation.
792: * @param task the task being executed.
793: * @param suName the name of the Service Unit.
794: * @param suRoot the root directory path of the Service Unit or null if
795: * not required for the operation.
796: * @return the result string from the operation or null if none present.
797: * @throws javax.jbi.management.DeploymentException if any runtime error
798: * or timeout occurs.
799: */
800: private String performOperation(int operation, long timeout,
801: String task, String suName, String suRoot)
802: throws javax.jbi.management.DeploymentException {
803: String msg;
804: Object args[] = { suName, suRoot };
805: OperationCounter oc = new OperationCounter();
806:
807: if (null == mSuMgr) {
808: msg = mTranslator.getString(
809: LocalStringKeys.DMB_SU_OPERATION_NOT_AVAILABLE,
810: task, suName);
811: throw new javax.jbi.management.DeploymentException(
812: buildMessage(task, msg));
813: }
814:
815: ServiceUnitOperation suOper = new ServiceUnitOperation(oc,
816: mComponent.getName(), mSuMgr, operation, args);
817:
818: new Thread(suOper, suName).start();
819: synchronized (oc) {
820: try {
821: if (0 < oc.getValue()) {
822: oc.wait(timeout);
823: }
824: } catch (java.lang.InterruptedException iEx) {
825: suOper.getThread().interrupt();
826: msg = mTranslator.getString(
827: LocalStringKeys.DMB_SU_OPERATION_INTERRUPTED,
828: task, suName);
829: mLog.warning(msg);
830: throw new javax.jbi.management.DeploymentException(
831: buildMessage(task, msg));
832: }
833: }
834: if (suOper.completed()) {
835: Throwable ex = suOper.getException();
836: if (null != ex) {
837: if (statisticsEnabled()) {
838: mComponentStatistics.incrementFailedSURequests();
839: }
840: if (ex instanceof javax.jbi.management.DeploymentException) {
841: throw (javax.jbi.management.DeploymentException) ex;
842: } else {
843: String exMsg = ex.getMessage();
844: if (null == exMsg) {
845: msg = mTranslator
846: .getString(
847: LocalStringKeys.DMB_SU_OPERATION_EXCEPTION_NO_MSG,
848: ex.getClass().getName(), task,
849: suName);
850: } else {
851: msg = mTranslator
852: .getString(
853: LocalStringKeys.DMB_SU_OPERATION_EXCEPTION,
854: ex.getClass().getName(), task,
855: suName, exMsg);
856: }
857: mLog.log(Level.WARNING, msg, ex);
858: throw new javax.jbi.management.DeploymentException(
859: buildMessage(task, msg));
860: }
861: }
862: } else {
863: suOper.getThread().interrupt();
864: if (statisticsEnabled()) {
865: mComponentStatistics.incrementTimedOutSURequests();
866: }
867: msg = mTranslator.getString(
868: LocalStringKeys.DMB_SU_OPERATION_TIMEOUT, task,
869: suName, new Long(timeout));
870: mLog.warning(msg);
871: throw new javax.jbi.management.DeploymentException(
872: buildMessage(task, msg));
873: }
874: return (String) suOper.getReturnValue();
875: }
876:
877: /**
878: * Force the state of an SU to be persisted after a change.
879: * @param su the Service Unit being processed.
880: * @param task the task being executed.
881: * @deprecated
882: */
883: private void persistState(ServiceUnit su, String task) {
884: try {
885: com.sun.jbi.management.registry.Updater updater = ((Registry) mEnv
886: .getRegistry()).getUpdater();
887: updater.setServiceUnitState(su.getDesiredState(),
888: mComponent.getName(), su.getName());
889: } catch (com.sun.jbi.management.registry.RegistryException rex) {
890: String msg = mTranslator.getString(
891: LocalStringKeys.DMB_SU_STATE_PERSIST_FAILURE, su
892: .getName(), task, rex.getMessage());
893: mLog.warning(msg);
894: }
895: }
896:
897: /**
898: * Return true if statistics are enabled for the component, false if not.
899: * @return true if statistics enabled, false if not.
900: */
901: private boolean statisticsEnabled() {
902: if (null != mComponentStatistics) {
903: if (mComponentStatistics.isEnabled()) {
904: return true;
905: }
906: } else {
907: mComponentStatistics = mComponent.getStatisticsInstance();
908: if (null != mComponentStatistics) {
909: if (mComponentStatistics.isEnabled()) {
910: return true;
911: }
912: }
913: }
914: return false;
915: }
916: }
|