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: * @(#)UpgradableComponent.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package deploytest;
030:
031: import java.io.InputStream;
032: import java.io.FileOutputStream;
033: import java.io.File;
034: import java.io.FileWriter;
035: import java.text.SimpleDateFormat;
036: import java.util.List;
037: import java.util.logging.Logger;
038: import java.util.Date;
039: import java.util.Properties;
040:
041: import javax.jbi.JBIException;
042: import javax.jbi.component.Bootstrap;
043: import javax.jbi.component.Component;
044: import javax.jbi.component.ComponentContext;
045: import javax.jbi.component.ComponentLifeCycle;
046: import javax.jbi.component.ServiceUnitManager;
047:
048: import javax.management.StandardMBean;
049: import javax.management.ObjectName;
050:
051: /**
052: * Dummy binding component used to test deployment.
053: *
054: * @author Sun Microsystems, Inc.
055: */
056: public class UpgradableComponent implements Component,
057: ComponentLifeCycle, ServiceUnitManager, Bootstrap {
058: /** Optional config file used to change behavior of component. */
059: private static final String CONFIG_FILE_NAME = "config.properties";
060:
061: /**
062: * Config property indicating that the component should throw an exception
063: * on upgrade.
064: */
065: private static final String THROW_ON_COMP_UPGRADE = "throw.on.comp.upgrade";
066:
067: /**
068: * Config property indicating that the component should throw an exception
069: * on start.
070: */
071: private static final String THROW_ON_COMP_START = "throw.on.comp.start";
072:
073: /** Config property indicating that the component should throw an exception
074: * on SU init.
075: */
076: private static final String THROW_ON_SU_INIT = "throw.on.su.init";
077:
078: /** Config property indicating that the component should throw an exception
079: * on shutdown.
080: */
081: private static final String THROW_ON_COMP_SHUTDOWN = "throw.on.comp.shutdown";
082:
083: /** Config property indicating that the component should throw an exception
084: * on service unit shutdown.
085: */
086: private static final String THROW_ON_SU_SHUTDOWN = "throw.on.su.shutdown";
087:
088: /** Config property indicating that the component should throw an exception
089: * on service unit start.
090: */
091: private static final String THROW_ON_SU_START = "throw.on.su.start";
092:
093: /** Config property indicating that the component should throw an exception
094: * on service unit undeploy.
095: */
096: private static final String THROW_ON_SU_UNDEPLOY = "throw.on.su.undeploy";
097:
098: /** Config property indicating that the component should throw an exception
099: * on service unit deploy.
100: */
101: private static final String THROW_ON_SU_DEPLOY = "throw.on.su.deploy";
102:
103: /** Config property indicating that the component should throw a plan-text exception
104: */
105: private static final String THROW_TEXT_EXCEPTION = "throw.text.exception";
106:
107: /** Config property indicating that the component should throw an exception
108: * on service unit undeploy.
109: */
110: private static final String REGISTER_CUSTOM_MBEAN = "register.custom.mbean";
111:
112: /**
113: * Local copy of the component name.
114: */
115: protected String mComponentName;
116:
117: /**
118: * Type of component.
119: */
120: protected String mComponentType = "Binding";
121:
122: /**
123: * Local handle to the ComponentContext.
124: */
125: protected ComponentContext mContext;
126:
127: /**
128: * Logger instance.
129: */
130: protected Logger mLog = Logger.getLogger("com.sun.jbi.management");
131:
132: /**
133: * Component configuration
134: */
135: private Properties mConfig = new Properties();
136:
137: //
138: // Component methods
139: //
140:
141: /**
142: * Get the ComponentLifeCycle implementation instance for this Binding
143: * Component.
144: * @return the life cycle implementation instance.
145: */
146: public ComponentLifeCycle getLifeCycle() {
147: mLog.info(mComponentType + " getLifeCycle called");
148: return this ;
149: }
150:
151: /**
152: * Get the ServiceUnitManager implementation instance for this Binding
153: * Component.
154: * @return the Service Unit manager implementation instance.
155: */
156: public ServiceUnitManager getServiceUnitManager() {
157: mLog.info(mComponentType + " " + mComponentName
158: + " getServiceUnitManager called");
159: return this ;
160: }
161:
162: /**
163: * Resolve descriptor details for the specified reference, which is for a
164: * service provided by this component.
165: * @param ref the endpoint reference to be resolved.
166: * @return the description for the specified reference.
167: */
168: public org.w3c.dom.Document getServiceDescription(
169: javax.jbi.servicedesc.ServiceEndpoint ref) {
170: mLog.info(mComponentType + " " + mComponentName
171: + " getServiceDescription called");
172: return null;
173: }
174:
175: /**
176: * This method is called by JBI to check if this component, in the role of
177: * provider of the service indicated by the given exchange, can actually
178: * perform the operation desired.
179: */
180: public boolean isExchangeWithConsumerOkay(
181: javax.jbi.servicedesc.ServiceEndpoint endpoint,
182: javax.jbi.messaging.MessageExchange exchange) {
183: mLog.info(mComponentType + " " + mComponentName
184: + " isExchangeWithConsumerOkay called");
185: return true;
186: }
187:
188: /**
189: * This method is called by JBI to check if this component, in the role of
190: * consumer of the service indicated by the given exchange, can actually
191: * interact with the the provider completely.
192: */
193: public boolean isExchangeWithProviderOkay(
194: javax.jbi.servicedesc.ServiceEndpoint endpoint,
195: javax.jbi.messaging.MessageExchange exchange) {
196: mLog.info(mComponentType + " " + mComponentName
197: + " isExchangeWithProviderOkay called");
198: return true;
199: }
200:
201: /**
202: * Resolve the given endpoint reference, given the capabilities of the
203: * given consumer. This is called by JBI when it is attempting to resolve
204: * the given endpoint reference on behalf of a component.
205: * @param epr the endpoint reference, in some XML dialect understood by the
206: * appropriate component (usually a Binding Component).
207: * @return the service endpoint for the endpoint reference;
208: * <code>null</code> if the endpoint reference cannot be resolved.
209: */
210: public javax.jbi.servicedesc.ServiceEndpoint resolveEndpointReference(
211: org.w3c.dom.DocumentFragment epr) {
212: mLog.info(mComponentType + " " + mComponentName
213: + " resolveEndpointReference called");
214: return null;
215: }
216:
217: //
218: // ComponentLifeCycle methods
219: //
220:
221: /**
222: * Initialize the Binding Component.
223: * @param context the JBI component context created by the JBI framework.
224: * @throws javax.jbi.JBIException if an error occurs.
225: */
226: public void init(ComponentContext context)
227: throws javax.jbi.JBIException {
228: mComponentName = context.getComponentName();
229: mContext = context;
230: File configFile;
231: InputStream inputStream;
232: try {
233: configFile = new File(context.getInstallRoot(),
234: CONFIG_FILE_NAME);
235: if (configFile.exists()) {
236: inputStream = new java.io.FileInputStream(configFile);
237: mConfig.load(inputStream);
238: inputStream.close();
239: }
240:
241: //write the timestamp in a properties file in workspace dir
242: try {
243: File settingsFile = new File(
244: context.getWorkspaceRoot(), "settings.txt");
245: FileWriter writer = new FileWriter(settingsFile);
246: SimpleDateFormat format = new SimpleDateFormat(
247: "yyyyMMddHHmm");
248: writer.write(format.format(new Date()));
249: writer.close();
250: } catch (Exception ex) {
251: }
252:
253: } catch (Exception ex) {
254: throw new javax.jbi.JBIException(ex.toString());
255: }
256: }
257:
258: /**
259: * Get the JMX ObjectName for any additional MBean for this BC. This
260: * implementation always returns null.
261: * @return javax.management.ObjectName is always null.
262: */
263: public javax.management.ObjectName getExtensionMBeanName() {
264: mLog.info(mComponentType + " "
265: + " getExtensionMBeanName called");
266: return null;
267: }
268:
269: /**
270: * Start the Binding Component.
271: * @throws javax.jbi.JBIException if an error occurs.
272: */
273: public void start() throws javax.jbi.JBIException {
274: mLog.info(mComponentType + " " + mComponentName
275: + " start called");
276:
277: if (mConfig.containsKey(THROW_ON_COMP_START)) {
278: throw new javax.jbi.JBIException(createErrorResult("start",
279: "Component start failed"));
280: }
281: if (mConfig.containsKey(REGISTER_CUSTOM_MBEAN)) {
282: registerCustomMBeans();
283: registerLoggerMBean();
284: }
285: }
286:
287: /**
288: * Stop the Binding Component.
289: * @throws javax.jbi.JBIException if an error occurs.
290: */
291: public void stop() throws javax.jbi.JBIException {
292: mLog.info(mComponentType + " " + mComponentName
293: + " stop called");
294: }
295:
296: /**
297: * Shut down the Binding Component.
298: * @throws javax.jbi.JBIException if an error occurs.
299: */
300: public void shutDown() throws javax.jbi.JBIException {
301: mLog.info(mComponentType + " " + mComponentName
302: + " shutDown called");
303:
304: if (mConfig.containsKey(THROW_ON_COMP_SHUTDOWN)) {
305: throw new javax.jbi.JBIException(createErrorResult(
306: "shutDown", "Component shutDown failed"));
307: }
308:
309: if (mConfig.containsKey(REGISTER_CUSTOM_MBEAN)) {
310: unregisterCustomMBeans();
311: }
312: }
313:
314: //
315: // ServiceUnitManager methods
316: //
317:
318: /**
319: * Deploy a Service Unit.
320: * @param serviceUnitName the name of the Service Unit being deployed.
321: * @param serviceUnitRootPath the full path to the Service Unit artifact
322: * root directory.
323: * @return a deployment status message.
324: * @throws javax.jbi.management.DeploymentException if the deployment
325: * operation is unsuccessful.
326: */
327: public String deploy(String serviceUnitName,
328: String serviceUnitRootPath)
329: throws javax.jbi.management.DeploymentException {
330: if (mConfig.containsKey(THROW_ON_SU_DEPLOY)) {
331: if (mConfig.containsKey(THROW_TEXT_EXCEPTION)) {
332: throw new javax.jbi.management.DeploymentException(
333: "Deployment of service unit " + serviceUnitName
334: + " FAILED.");
335: } else {
336: throw new javax.jbi.management.DeploymentException(
337: createErrorResult("init", "SU deploy failed"));
338: }
339: }
340:
341: mLog.info(mComponentType + " " + mComponentName
342: + " deployed Service Unit " + serviceUnitName
343: + " with serviceUnitRootPath " + serviceUnitRootPath);
344:
345: if (serviceUnitName.equals("esbadmin00089-su-3")
346: || serviceUnitName.equals("esbadmin00089-su-6")) {
347: return createDeployResult("deploy", false);
348: } else {
349: return createDeployResult("deploy", true);
350: }
351: }
352:
353: /**
354: * Initialize the deployment.
355: * @param serviceUnitName the name of the Service Unit being initialized.
356: * @param serviceUnitRootPath the full path to the Service Unit artifact
357: * root directory.
358: * @throws javax.jbi.management.DeploymentException if the Service Unit is
359: * not deployed, or is in an incorrect state.
360: */
361: public void init(String serviceUnitName, String serviceUnitRootPath)
362: throws javax.jbi.management.DeploymentException {
363: mLog.info(mComponentType + " " + mComponentName
364: + " initialized Service Unit " + serviceUnitName
365: + " with serviceUnitRootPath " + serviceUnitRootPath);
366:
367: if (mConfig.containsKey(THROW_ON_SU_INIT)) {
368: throw new javax.jbi.management.DeploymentException(
369: createErrorResult("init",
370: "SU initialization failed"));
371: }
372:
373: java.io.File suRoot = new java.io.File(serviceUnitRootPath);
374:
375: if (!suRoot.exists()) {
376: throw new javax.jbi.management.DeploymentException(
377: "Invalid service unit root " + serviceUnitRootPath
378: + " for service unit " + serviceUnitName);
379: }
380: }
381:
382: /**
383: * Shut down the deployment.
384: * @param serviceUnitName the name of the Service Unit being shut down.
385: * @throws javax.jbi.management.DeploymentException if the Service Unit
386: * is not deployed, or is in an incorrect state.
387: */
388: public void shutDown(String serviceUnitName)
389: throws javax.jbi.management.DeploymentException {
390: if (mConfig.containsKey(THROW_ON_SU_SHUTDOWN)) {
391: throw new javax.jbi.management.DeploymentException(
392: createErrorResult("shutDown", "Service unit "
393: + serviceUnitName + " shutDown failed"));
394: }
395:
396: mLog.info(mComponentType + " " + mComponentName
397: + " shut down Service Unit " + serviceUnitName);
398: }
399:
400: /**
401: * Start the deployment.
402: * @param serviceUnitName the name of the Service Unit being started.
403: * @throws javax.jbi.management.DeploymentException if the Service Unit
404: * is not deployed, or is in an incorrect state.
405: */
406: public void start(String serviceUnitName)
407: throws javax.jbi.management.DeploymentException {
408:
409: if (mConfig.containsKey(THROW_ON_SU_START)) {
410: throw new javax.jbi.management.DeploymentException(
411: createErrorResult("start", "Service unit "
412: + serviceUnitName + " start failed"));
413: }
414:
415: mLog.info(mComponentType + " " + mComponentName
416: + " started Service Unit " + serviceUnitName);
417: }
418:
419: /**
420: * Stop the deployment.
421: * @param serviceUnitName the name of the Service Unit being stopped.
422: * @throws javax.jbi.management.DeploymentException if the Service Unit
423: * is not deployed, or is in an incorrect state.
424: */
425: public void stop(String serviceUnitName)
426: throws javax.jbi.management.DeploymentException {
427: mLog.info(mComponentType + " " + mComponentName
428: + " stopped Service Unit " + serviceUnitName);
429: }
430:
431: /**
432: * Undeploy a Service Unit from the component.
433: * @param serviceUnitName the name of the Service Unit being undeployed.
434: * @param serviceUnitRootPath the full path to the Service Unit artifact
435: * root directory.
436: * @return an undeployment status message.
437: * @throws javax.jbi.management.DeploymentException if the undeployment
438: * operation is unsuccessful.
439: */
440: public String undeploy(String serviceUnitName,
441: String serviceUnitRootPath)
442: throws javax.jbi.management.DeploymentException {
443: mLog.info(mComponentType + " " + mComponentName
444: + " undeployed Service Unit " + serviceUnitName);
445:
446: if (mConfig.containsKey(THROW_ON_SU_UNDEPLOY)) {
447: throw new javax.jbi.management.DeploymentException(
448: createErrorResult("undeploy", "Service unit "
449: + serviceUnitName + " undeploy failed"));
450: } else if (serviceUnitName.equals("esbadmin00089-su-3")
451: || serviceUnitName.equals("esbadmin00089-su-6")) {
452: return createDeployResult("undeploy", false);
453: } else {
454: return createDeployResult("undeploy", true);
455: }
456: }
457:
458: public void onUninstall() throws javax.jbi.JBIException {
459: }
460:
461: public void onInstall() throws javax.jbi.JBIException {
462:
463: }
464:
465: public void init(
466: javax.jbi.component.InstallationContext installationContext)
467: throws javax.jbi.JBIException {
468:
469: }
470:
471: public void cleanUp() throws javax.jbi.JBIException {
472:
473: }
474:
475: /** Creates a (un)deployment result string.
476: * @param task 'deploy' or 'undeploy'
477: */
478: private String createDeployResult(String task, boolean isSuccess) {
479: return "<component-task-result xmlns=\"http://java.sun.com/xml/ns/jbi/management-message\">"
480: + "<component-name>"
481: + mComponentName
482: + "</component-name>"
483: + "<component-task-result-details>"
484: + "<task-result-details>"
485: + "<task-id>"
486: + task
487: + "</task-id>"
488: + "<task-result>"
489: + (isSuccess ? "SUCCESS" : "FAILED")
490: + "</task-result>"
491: + "</task-result-details>"
492: + "</component-task-result-details>"
493: + "</component-task-result>";
494: }
495:
496: /** Creates a component failure response with a configurable message.
497: * @param task 'deploy' or 'undeploy'
498: */
499: protected String createErrorResult(String task, String msg) {
500: return "<component-task-result xmlns=\"http://java.sun.com/xml/ns/jbi/management-message\">"
501: + "<component-name>"
502: + mComponentName
503: + "</component-name>"
504: + "<component-task-result-details>"
505: + "<task-result-details>"
506: + "<task-id>"
507: + task
508: + "</task-id>"
509: + "<task-result>"
510: + "FAILED"
511: + "</task-result>"
512: + "<message-type>ERROR</message-type>"
513: + "<task-status-msg>"
514: + "<msg-loc-info>"
515: + "<loc-token>JBIWHOOPS</loc-token>"
516: + "<loc-message>"
517: + msg
518: + "</loc-message>"
519: + "</msg-loc-info>"
520: + "</task-status-msg>"
521: + "</task-result-details>"
522: + "</component-task-result-details>"
523: + "</component-task-result>";
524: }
525:
526: /**
527: * Register custom MBeans
528: */
529: protected void registerCustomMBeans() throws javax.jbi.JBIException {
530: try {
531: CustomConfigMBean mbean = new CustomConfig(mComponentName
532: + " custom config MBean", mContext);
533:
534: StandardMBean compMBean = new StandardMBean(mbean,
535: CustomConfigMBean.class);
536:
537: ObjectName compMBeanName = mContext.getMBeanNames()
538: .createCustomComponentMBeanName(
539: mComponentName + "Config");
540:
541: mContext.getMBeanServer().registerMBean(compMBean,
542: compMBeanName);
543: } catch (Exception exp) {
544: throw new javax.jbi.JBIException(exp.getMessage());
545: }
546: }
547:
548: /**
549: * Unregister custom MBeans
550: */
551: protected void unregisterCustomMBeans()
552: throws javax.jbi.JBIException {
553: try {
554: ObjectName compMBeanName = mContext.getMBeanNames()
555: .createCustomComponentMBeanName(
556: mComponentName + "Config");
557:
558: mContext.getMBeanServer().unregisterMBean(compMBeanName);
559: } catch (Exception exp) {
560: throw new javax.jbi.JBIException(exp.getMessage());
561: }
562: }
563:
564: /**
565: * ComponentContext.getLogger() registers a Logger MBean for the component.
566: * When the component is uninstalled the Logger MBean is unregistered.
567: */
568: protected void registerLoggerMBean() throws javax.jbi.JBIException {
569: mContext.getLogger("com.sun.jbi.test.binding.logger", null);
570: }
571:
572: /**
573: * Perform an upgrade of the component.
574: * @param workspaceRoot the workspace root for the new version of the
575: * component that will replace the currently installed version. This is
576: * populated with the contents of the original workspace root and the
577: * component must update it to match the new version of the component.
578: * @param serviceUnitRoots a list of directory paths to all of the Service
579: * Units currently deployed to the component. The component must update all
580: * of these to match the new version of the component.
581: * @throws javax.jbi.JBIException when there is an error requiring that the
582: * upgrade be terminated.
583: */
584: public void upgrade(String workspaceRoot,
585: List<String> serviceUnitRoots)
586: throws javax.jbi.JBIException {
587: mLog.info("upgrade started");
588:
589: //read the properties file again as init is not called between
590: //shutdown and upgrade
591: try {
592: File configFile = new File(new File(workspaceRoot)
593: .getParent(), CONFIG_FILE_NAME);
594:
595: if (configFile.exists()) {
596: InputStream inputStream = new java.io.FileInputStream(
597: configFile);
598: mConfig.load(inputStream);
599: inputStream.close();
600: }
601: } catch (Exception ex) {
602: mLog.info("Could not read config file");
603: }
604: if (mConfig.containsKey(THROW_ON_COMP_UPGRADE)) {
605: //This is a bad component that deletes the SU roots upon upgrade
606: //and throws an exception. Upgrade would fail, but the SU roots
607: //would have been restored from backup
608:
609: for (String suRoot : serviceUnitRoots) {
610: File suDescriptor = new File(suRoot, "META-INF/jbi.xml");
611: if (suDescriptor.delete()) {
612: mLog.info("Upgrade-Component deleted jbi.xml in "
613: + suRoot);
614: } else {
615: mLog
616: .info("Upgrade-Component could not delete jbi.xml in "
617: + suRoot);
618: }
619:
620: }
621: mLog.info("upgrade failed");
622: throw new javax.jbi.JBIException(createErrorResult(
623: "upgrade", "Component Upgrade failed"));
624: }
625:
626: try {
627: FileOutputStream fos = new FileOutputStream(new File(
628: workspaceRoot, "upgrade.txt"));
629: String content = "new file created in workspace by upgrade\n";
630: fos.write(content.getBytes());
631: fos.flush();
632: fos.close();
633: mLog.info("workspace root " + workspaceRoot + " upgraded");
634:
635: } catch (Exception ex) {
636: mLog.warning("Could not upgrade the component"
637: + ex.getMessage());
638: throw new JBIException(ex);
639: }
640:
641: try {
642: for (String suRoot : serviceUnitRoots) {
643: FileOutputStream fos = new FileOutputStream(new File(
644: suRoot, "upgrade.txt"));
645: String content = "new file created in workspace by upgrade";
646: fos.write(content.getBytes());
647: fos.flush();
648: fos.close();
649: mLog.info("SU root " + suRoot + " upgraded");
650: }
651: } catch (Exception ex) {
652: mLog.warning("Could not upgrade the component"
653: + ex.getMessage());
654: throw new JBIException(ex);
655:
656: }
657: mLog.info("upgrade complete");
658: }
659: }
|