KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > deployapi > ProgressObjectImpl


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.deployapi;
25
26 import com.sun.appserv.management.client.ConnectionSource;
27 import com.sun.enterprise.admin.util.HostAndPort;
28 import com.sun.enterprise.deployapi.SunDeploymentManager;
29 import com.sun.enterprise.deployapi.SunTarget;
30 import com.sun.enterprise.deployapi.SunTargetModuleID;
31 import com.sun.enterprise.deployment.client.DeploymentClientUtils;
32 import com.sun.enterprise.deployment.client.JESProgressObject;
33 import com.sun.enterprise.deployment.client.RollBackAction;
34 import com.sun.enterprise.util.i18n.StringManager;
35 import com.sun.enterprise.util.io.FileUtils;
36 import com.sun.enterprise.util.Print;
37
38 import java.io.ByteArrayOutputStream JavaDoc;
39 import java.io.File JavaDoc;
40 import java.io.PrintStream JavaDoc;
41 import java.io.PrintWriter JavaDoc;
42 import java.net.URL JavaDoc;
43 import java.rmi.RemoteException JavaDoc;
44 import java.util.Iterator JavaDoc;
45 import java.util.Vector JavaDoc;
46
47 import javax.enterprise.deploy.shared.CommandType JavaDoc;
48 import javax.enterprise.deploy.shared.ModuleType JavaDoc;
49 import javax.enterprise.deploy.shared.StateType JavaDoc;
50 import javax.enterprise.deploy.spi.exceptions.OperationUnsupportedException JavaDoc;
51 import javax.enterprise.deploy.spi.status.ClientConfiguration JavaDoc;
52 import javax.enterprise.deploy.spi.status.DeploymentStatus JavaDoc;
53 import javax.enterprise.deploy.spi.status.ProgressEvent JavaDoc;
54 import javax.enterprise.deploy.spi.status.ProgressListener JavaDoc;
55 import javax.enterprise.deploy.spi.TargetModuleID JavaDoc;
56 import javax.management.MBeanServerConnection JavaDoc;
57 import javax.management.ObjectName JavaDoc;
58
59 /**
60  * Implementation of the Progress Object
61  * @author dochez
62  */

63 public abstract class ProgressObjectImpl implements Runnable JavaDoc, JESProgressObject {
64     
65     protected CommandType JavaDoc commandType;
66     protected Object JavaDoc[] args;
67     private Vector JavaDoc listeners = new Vector JavaDoc(); // <-- needs to be synchronized
68
protected SunTarget target;
69     protected SunTarget[] targetsList;
70     protected String JavaDoc moduleID;
71     protected ModuleType JavaDoc moduleType;
72     protected DeploymentStatusImpl deploymentStatus =null;
73     protected TargetModuleID[] targetModuleIDs = null;
74     protected Vector JavaDoc deliveredEvents = new Vector JavaDoc();
75     protected com.sun.enterprise.deployment.backend.DeploymentStatus finalDeploymentStatus = null;
76     protected boolean deployActionCompleted;
77     protected String JavaDoc warningMessages;
78     private static StringManager localStrings = StringManager.getManager(ProgressObjectImpl.class);
79     
80     private final static String JavaDoc MODULE_ID =
81         com.sun.enterprise.deployment.backend.DeploymentStatus.MODULE_ID;
82     private final static String JavaDoc MODULE_TYPE =
83         com.sun.enterprise.deployment.backend.DeploymentStatus.MODULE_TYPE;
84     private final static String JavaDoc KEY_SEPARATOR =
85         com.sun.enterprise.deployment.backend.DeploymentStatus.KEY_SEPARATOR;
86     private final static String JavaDoc SUBMODULE_COUNT =
87         com.sun.enterprise.deployment.backend.DeploymentStatus.SUBMODULE_COUNT;
88     private final static String JavaDoc CONTEXT_ROOT =
89         com.sun.enterprise.deployment.backend.DeploymentStatus.CONTEXT_ROOT;
90     private final static String JavaDoc WARNING_PREFIX = "WARNING: ";
91
92     /** Creates a new instance of ProgressObjectImpl */
93     public ProgressObjectImpl(SunTarget target) {
94         this.target = target;
95         deploymentStatus = new DeploymentStatusImpl(this);
96         deploymentStatus.setState(StateType.RELEASED);
97         finalDeploymentStatus = new com.sun.enterprise.deployment.backend.DeploymentStatus();
98         deployActionCompleted = false;
99     }
100
101     public ProgressObjectImpl(SunTarget[] targets) {
102         this.targetsList = targets;
103         deploymentStatus = new DeploymentStatusImpl(this);
104         deploymentStatus.setState(StateType.RELEASED);
105         finalDeploymentStatus = new com.sun.enterprise.deployment.backend.DeploymentStatus();
106         deployActionCompleted = false;
107     }
108     
109     /** Add a listener to receive Progress events on deployment
110      * actions.
111      *
112      * @param The listener to receive events
113      * @see ProgressEvent
114      */

115     public void addProgressListener(ProgressListener JavaDoc pol) {
116     synchronized (listeners) {
117             listeners.add(pol);
118         if (deliveredEvents.size() > 0) {
119         Print.dprintln("Delivering undelivered messages...");
120             for (Iterator JavaDoc i = deliveredEvents.iterator(); i.hasNext();) {
121             pol.handleProgressEvent((ProgressEvent JavaDoc)i.next());
122             }
123         }
124     }
125     }
126     
127     /** (optional)
128      * A cancel request on an in-process operation
129      * stops all further processing of the operation and returns
130      * the environment to it original state before the operation
131      * was executed. An operation that has run to completion
132      * cannot be cancelled.
133      *
134      * @throws OperationUnsupportedException this optional command
135      * is not supported by this implementation.
136      */

137     public void cancel() throws OperationUnsupportedException JavaDoc {
138         throw new OperationUnsupportedException JavaDoc("cancel not supported");
139     }
140     
141     /** Return the ClientConfiguration object associated with the
142      * TargetModuleID.
143      *
144      * @return ClientConfiguration for a given TargetModuleID or
145      * null if none exists.
146      */

147     public ClientConfiguration JavaDoc getClientConfiguration(TargetModuleID id) {
148         return null;
149     }
150     
151     /** Retrieve the status of this activity.
152      *
153      * @return An object containing the status
154      * information.
155      */

156     public DeploymentStatus JavaDoc getDeploymentStatus() {
157         DeploymentStatusImpl result = new DeploymentStatusImpl(this);
158         result.setState(deploymentStatus.getState());
159         result.setMessage(deploymentStatus.getMessage());
160         
161         return result;
162     }
163
164     /**
165      * Retrieve the final deployment status which has complete details for each stage
166      */

167     public com.sun.enterprise.deployment.backend.DeploymentStatus getCompletedStatus() {
168         if(deployActionCompleted) {
169             return finalDeploymentStatus;
170         }
171         return null;
172     }
173     
174     /** Retrieve the list of TargetModuleIDs successfully
175      * processed or created by the associated DeploymentManager
176      * operation.
177      *
178      * @return a list of TargetModuleIDs.
179      */

180     public TargetModuleID[] getResultTargetModuleIDs() {
181
182         /**
183          * this should go once CTS has fixed their bugs...
184          */

185         if (targetModuleIDs==null) {
186             if(target != null) {
187                 initializeTargetModuleIDs(moduleID);
188             } else if(targetsList != null) {
189                 initializeTargetModuleIDForAllServers(null, null);
190             }
191         }
192         // will return null until the operation is completed
193
return targetModuleIDs;
194     }
195     
196     /**
197      * initialize the target module IDs with the passed application moduleID
198      * and the descriptors
199      */

200     protected void initializeTargetModuleIDs(String JavaDoc moduleID) {
201         SunTargetModuleID parentTargetModuleID = new SunTargetModuleID(moduleID, target);
202         parentTargetModuleID.setModuleType(getModuleType());
203         
204         targetModuleIDs = new SunTargetModuleID[1];
205         targetModuleIDs[0] = parentTargetModuleID;
206     }
207
208     /**
209      * Initialize the target module IDs with the application information stored
210      * in the DeploymentStatus for all the server in the target list.
211      */

212     protected void initializeTargetModuleIDForAllServers(
213         com.sun.enterprise.deployment.backend.DeploymentStatus status,
214         MBeanServerConnection JavaDoc mbsc) {
215
216         if(targetsList == null) {
217             return;
218         }
219
220         targetModuleIDs = new SunTargetModuleID[targetsList.length];
221         String JavaDoc moduleID = status == null
222                         ? this.moduleID : status.getProperty(MODULE_ID);
223         String JavaDoc key = moduleID + KEY_SEPARATOR + MODULE_TYPE;
224         ModuleType JavaDoc type = status == null
225                         ? getModuleType()
226                         : ModuleType.getModuleType((new Integer JavaDoc(status.getProperty(key))).intValue());
227
228         for(int i=0; i<targetsList.length; i++) {
229             SunTargetModuleID parentTargetModuleID = new SunTargetModuleID(moduleID, targetsList[i]);
230             parentTargetModuleID.setModuleType(type);
231             targetModuleIDs[i] = parentTargetModuleID;
232
233             if (status != null) {
234                 // let's get the host name and port where the application was deployed
235
HostAndPort webHost=null;
236                 try {
237                     Object JavaDoc[] params = new Object JavaDoc[]{ moduleID, Boolean.FALSE };
238                     String JavaDoc[] signature = new String JavaDoc[]{ "java.lang.String", "boolean"};
239                     ObjectName JavaDoc applicationsMBean = new ObjectName JavaDoc(APPS_CONFIGMBEAN_OBJNAME);
240                     webHost = (HostAndPort) mbsc.invoke(applicationsMBean, "getHostAndPort", params, signature);
241                 } catch(Exception JavaDoc e) {
242                     Print.dprintStackTrace(e.getLocalizedMessage(), e);
243                 }
244
245                 key = moduleID + KEY_SEPARATOR + SUBMODULE_COUNT;
246                 if (status.getProperty(key) == null) { //standalone module
247
if (ModuleType.WAR.equals(type)) {
248                         key = moduleID + KEY_SEPARATOR + CONTEXT_ROOT;
249                         String JavaDoc contextRoot = status.getProperty(key);
250                         initTargetModuleIDWebURL(parentTargetModuleID, webHost, contextRoot);
251                      }
252                 } else {
253                     int counter = (Integer.valueOf(status.getProperty(key))).intValue();
254                     // now for each sub module
255
for (int j = 0; j < counter; j++) {
256                         //subModuleID
257
key = moduleID + KEY_SEPARATOR + MODULE_ID + KEY_SEPARATOR + String.valueOf(j);
258                         String JavaDoc subModuleID = status.getProperty(key);
259                         SunTargetModuleID subModule = new SunTargetModuleID(subModuleID, targetsList[i]);
260
261                         //subModuleType
262
key = subModuleID + KEY_SEPARATOR + MODULE_TYPE;
263                         type = ModuleType.getModuleType((new Integer JavaDoc(status.getProperty(key))).intValue());
264                         subModule.setModuleType(type);
265                         if (ModuleType.WAR.equals(type) && webHost!=null) {
266                             key = subModuleID + KEY_SEPARATOR + CONTEXT_ROOT;
267                             String JavaDoc contextRoot = status.getProperty(key);
268                             initTargetModuleIDWebURL(subModule, webHost, contextRoot);
269                         }
270                         parentTargetModuleID.addChildTargetModuleID(subModule);
271                     }
272                 }
273             }
274         }
275     }
276
277     /**
278      * private method to initialize the web url for the associated deployed web
279      * module
280      */

281     private void initTargetModuleIDWebURL(
282         SunTargetModuleID tm, HostAndPort webHost, String JavaDoc contextRoot) {
283         
284         if (webHost==null)
285             return;
286         
287         try {
288             // Patchup code for fixing netbeans issue 6221411; Need to find a
289
// good solution for this and WSDL publishing
290
String JavaDoc host;
291             SunDeploymentManager sdm = new SunDeploymentManager(tm.getConnectionInfo());
292             if(sdm.isPE()) {
293                 host = tm.getConnectionInfo().getHostName();
294             } else {
295                 host = webHost.getHost();
296             }
297             
298             URL JavaDoc webURL = new URL JavaDoc("http", host, webHost.getPort(), contextRoot);
299             tm.setWebURL(webURL.toExternalForm());
300         } catch(Exception JavaDoc e) {
301             Print.dprintStackTrace(e.getLocalizedMessage(),e);
302         }
303     }
304     
305     /** Tests whether the vendor supports a cancel
306      * opertation for deployment activities.
307      *
308      * @return <code>true</code> if canceling an
309      * activity is supported by this platform.
310      */

311     public boolean isCancelSupported() {
312         return false;
313     }
314     
315     /** Tests whether the vendor supports a stop
316      * opertation for deployment activities.
317      *
318      * @return <code>true</code> if canceling an
319      * activity is supported by this platform.
320      */

321     public boolean isStopSupported() {
322         return false;
323     }
324     
325     /** Remove a ProgressObject listener.
326      *
327      * @param The listener being removed
328      * @see ProgressEvent
329      */

330     public void removeProgressListener(ProgressListener JavaDoc pol) {
331     synchronized (listeners) {
332             listeners.remove(pol);
333     }
334     }
335     
336     /** (optional)
337      * A stop request on an in-process operation allows the
338      * operation on the current TargetModuleID to run to completion but
339      * does not process any of the remaining unprocessed TargetModuleID
340      * objects. The processed TargetModuleIDs must be returned by the
341      * method getResultTargetModuleIDs.
342      *
343      * @throws OperationUnsupportedException this optional command
344      * is not supported by this implementation.
345      */

346     public void stop() throws OperationUnsupportedException JavaDoc {
347         throw new OperationUnsupportedException JavaDoc("stop not supported");
348     }
349
350     
351     public void setCommand(CommandType JavaDoc commandType, Object JavaDoc[] args) {
352         this.commandType = commandType;
353         this.args = args;
354     }
355     
356
357     /**
358      * implement this method to do the actual processing
359      */

360     public abstract void run();
361
362
363     /**
364      * Notifies all listeners that have registered interest for ProgressEvent notification.
365      */

366     protected void fireProgressEvent(ProgressEvent JavaDoc progressEvent) {
367         /*
368          *Bug 4977764
369          *Iteration failed due to concurrent modification of the vector. Even though the add, remove, and fire
370          *methods synchronize on the listeners vector, a listener could conceivably invoke add or remove
371          *recursively, thereby triggering the concurrent modification exception.
372          *
373          *Fix: clone the listeners vector and iterate through the clone.
374          */

375     Vector JavaDoc currentListeners = null;
376         synchronized (listeners) {
377             currentListeners = (Vector JavaDoc) listeners.clone();
378             /*
379              *The following add must remain inside the synchronized block. Otherwise, there will be a small window
380              *in which a new listener's registration could interleave with fireProgressEvent, registering itself
381              *after the listeners vector had been cloned (thus excluding the new listener from the iteration a
382              *few lines below) but before the list of previously-delivered events had been updated.
383              *This would cause the new listener to miss the event that was firing.
384              *Keeping the following add inside the synchronized block ensures that updates to the listeners
385              *vector by addProgressListener and to deliveredEvents by fireProgressEvent do not interleave and therefore
386              *all listeners will receive all events.
387              */

388             
389             deliveredEvents.add(progressEvent);
390         }
391
392         for (Iterator JavaDoc listenersItr = currentListeners.iterator(); listenersItr.hasNext();) {
393             ((ProgressListener JavaDoc)listenersItr.next()).handleProgressEvent(progressEvent);
394         }
395         currentListeners = null;
396     }
397
398
399     /**
400      * Notifies all listeners that have registered interest for ProgressEvent notification.
401      */

402     protected void fireProgressEvent(StateType JavaDoc state, String JavaDoc message) {
403         fireProgressEvent(state, message, target);
404     }
405
406     /**
407      * Notifies all listeners that have registered interest for ProgressEvent notification.
408      */

409     protected void fireProgressEvent(StateType JavaDoc state, String JavaDoc message, SunTarget aTarget) {
410         
411         StateType JavaDoc stateToBroadcast = (state != null) ? state : deploymentStatus.getState();
412
413         /* new copy of DeploymentStatus */
414     DeploymentStatusImpl depStatus = new DeploymentStatusImpl(this);
415     depStatus.setState(stateToBroadcast);
416         depStatus.setMessage(message);
417
418         /*
419          *Update this progress object's status before notifying listeners.
420          */

421         if (state != null) {
422             deploymentStatus.setMessage(message);
423             deploymentStatus.setState(state); // retain current state
424
}
425         
426         /* send notification */
427     SunTargetModuleID tmi = new SunTargetModuleID(moduleID, aTarget);
428         tmi.setModuleType(getModuleType());
429     fireProgressEvent(new ProgressEvent JavaDoc(this, tmi, depStatus));
430     }
431
432     CommandType JavaDoc getCommandType() {
433         return commandType;
434     }
435     
436     /**
437      * Sets the module type for this deployed module
438      * @param the module type
439      */

440     public void setModuleType(ModuleType JavaDoc moduleType) {
441         this.moduleType = moduleType;
442     }
443     
444     /**
445      * @return the module type of this deployed module
446      */

447     public ModuleType JavaDoc getModuleType() {
448         return moduleType;
449     }
450
451     /**
452      * Since DeploymentStatus only provides the ability to pass a String to the
453      * ProgressListener, the following is a convenience method for allowing the
454      * stack-trace from a Throwable to be converted to a String to send to the
455      * ProgressListeners.
456      */

457     protected String JavaDoc getThrowableString(Throwable JavaDoc t) {
458     ByteArrayOutputStream JavaDoc bos = new ByteArrayOutputStream JavaDoc();
459     PrintStream JavaDoc ps = new PrintStream JavaDoc(bos);
460     t.printStackTrace(ps);
461     ps.close(); // may not be necessary
462
return bos.toString();
463     }
464     
465     protected static final String JavaDoc APPS_CONFIGMBEAN_OBJNAME =
466                                   "com.sun.appserv:type=applications,category=config";
467
468     protected String JavaDoc getDeploymentStatusMessage(com.sun.enterprise.deployment.backend.DeploymentStatus status) {
469         return getDeploymentStatusMessage(status, false);
470     }
471     /**
472      * Parse the DeploymentStatus to get the status message within
473      */

474     protected String JavaDoc getDeploymentStatusMessage(com.sun.enterprise.deployment.backend.DeploymentStatus status, boolean isStartPhase) {
475         if(status == null) {
476             return null;
477         }
478         // if stage status is success, return as it is
479
if (status!=null && status.getStatus() >= com.sun.enterprise.deployment.backend.DeploymentStatus.SUCCESS) {
480             return null;
481         }
482         ByteArrayOutputStream JavaDoc bos = new ByteArrayOutputStream JavaDoc();
483         PrintWriter JavaDoc pw = new PrintWriter JavaDoc(bos);
484         com.sun.enterprise.deployment.backend.DeploymentStatus.parseDeploymentStatus(status, pw);
485         byte[] statusBytes = bos.toByteArray();
486         String JavaDoc statusString = new String JavaDoc(statusBytes);
487         // if stage status is WARNING, collect the warning messages
488
if(status.getStatus() == com.sun.enterprise.deployment.backend.DeploymentStatus.WARNING) {
489             if(warningMessages==null) {
490                 warningMessages = WARNING_PREFIX + statusString;
491             } else {
492                 warningMessages += statusString;
493             }
494
495             // add additional messages if it failed at loading.
496
if (isStartPhase) {
497                 warningMessages = localStrings.getString("enterprise.deployment.client.start_failed_msg") + warningMessages;
498             }
499
500             return null;
501         }
502         // Failed stage; return the failure message
503
return statusString;
504     }
505
506     protected void setupForNormalExit(String JavaDoc message, SunTarget aTarget) {
507         String JavaDoc i18nmsg;
508         // If we ever got some warning during any of the stages, the the final status is warning; else status=success
509
if(warningMessages == null) {
510             i18nmsg = localStrings.getString("enterprise.deployment.client.action_completed", message);
511             finalDeploymentStatus.setStageStatus(com.sun.enterprise.deployment.backend.DeploymentStatus.SUCCESS);
512         } else {
513             i18nmsg = localStrings.getString("enterprise.deployment.client.action_completed_with_warning", warningMessages);
514             finalDeploymentStatus.setStageStatus(com.sun.enterprise.deployment.backend.DeploymentStatus.WARNING);
515         }
516         finalDeploymentStatus.setStageStatusMessage(i18nmsg);
517         deployActionCompleted = true;
518         fireProgressEvent(StateType.COMPLETED, i18nmsg, aTarget);
519         return;
520     }
521     
522     protected void setupForAbnormalExit(String JavaDoc errorMsg, SunTarget aTarget) {
523         String JavaDoc i18nmsg = localStrings.getString("enterprise.deployment.client.action_failed", errorMsg);
524         finalDeploymentStatus.setStageStatus(com.sun.enterprise.deployment.backend.DeploymentStatus.FAILURE);
525         finalDeploymentStatus.setStageStatusMessage(i18nmsg);
526         deployActionCompleted = true;
527         fireProgressEvent(StateType.FAILED, i18nmsg, aTarget);
528         return;
529     }
530
531     protected boolean checkStatusAndAddStage(SunTarget aTarget, RollBackAction rollback, String JavaDoc action, ConnectionSource dasConnection, com.sun.enterprise.deployment.backend.DeploymentStatus currentStatus) {
532         return checkStatusAndAddStage(aTarget, rollback, action, dasConnection,
533             currentStatus, false);
534     }
535
536     /**
537      * Given a Deployment status, this checks if the status is success
538      * If the status is failed, it tries roll back operations (if rollback is specified) and then sets up
539      * for an abnormal exit
540      */

541     protected boolean checkStatusAndAddStage(SunTarget aTarget, RollBackAction rollback, String JavaDoc action, ConnectionSource dasConnection, com.sun.enterprise.deployment.backend.DeploymentStatus currentStatus, boolean isStartPhase) {
542         String JavaDoc statusMsg = getDeploymentStatusMessage(currentStatus,
543             isStartPhase);
544         finalDeploymentStatus.addSubStage(currentStatus);
545         if(statusMsg == null) {
546             fireProgressEvent(StateType.RUNNING,
547                                 localStrings.getString("enterprise.deployment.client.action_completed", action),
548                                 aTarget);
549             return true;
550         }
551         if(rollback != null) {
552             com.sun.enterprise.deployment.backend.DeploymentStatus tmp = new
553                         com.sun.enterprise.deployment.backend.DeploymentStatus();
554             if(!rollback.rollback(dasConnection, tmp)) {
555                 fireProgressEvent(StateType.RUNNING,
556                                 localStrings.getString("enterprise.deployment.client.action_failed", "Rollback failed"),
557                                         aTarget);
558                 tmp.setStageStatus(com.sun.enterprise.deployment.backend.DeploymentStatus.FAILURE);
559                 tmp.setStageStatusMessage(localStrings.getString("enterprise.deployment.client.action_failed", "Rollback failed"));
560             } else {
561                 fireProgressEvent(StateType.RUNNING,
562                                 localStrings.getString("enterprise.deployment.client.action_completed", "Rollback"),
563                                         aTarget);
564                 tmp.setStageStatus(com.sun.enterprise.deployment.backend.DeploymentStatus.SUCCESS);
565                 tmp.setStageStatusMessage(localStrings.getString("enterprise.deployment.client.action_completed", "Rollback"));
566             }
567             finalDeploymentStatus.addSubStage(tmp);
568         }
569         setupForAbnormalExit(localStrings.getString("enterprise.deployment.client.action_failed_with_message", action, statusMsg), aTarget);
570         return false;
571     }
572 }
573
Popular Tags