KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > deployment > autodeploy > AutoDeployer


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 /*
25  * AutoDeployer.java
26  *
27  *
28  * Created on February 19, 2003, 10:21 AM
29  */

30
31 package com.sun.enterprise.deployment.autodeploy;
32
33 import com.sun.enterprise.deployment.deploy.shared.AbstractArchive;
34 import com.sun.enterprise.deployment.deploy.shared.AbstractArchiveFactory;
35 import com.sun.enterprise.deployment.deploy.shared.ArchiveFactory;
36 import java.io.File JavaDoc;
37 import java.io.PrintWriter JavaDoc;
38 import java.io.ByteArrayOutputStream JavaDoc;
39
40 import java.util.logging.Logger JavaDoc;
41 import java.util.logging.Level JavaDoc;
42 import java.util.Properties JavaDoc;
43 import javax.management.ObjectName JavaDoc;
44 import javax.management.MBeanServer JavaDoc;
45 import javax.management.MBeanException JavaDoc;
46 import com.sun.enterprise.admin.server.core.jmx.InitException;
47 import com.sun.enterprise.admin.common.ObjectNames;
48 import com.sun.enterprise.admin.common.constant.DeploymentConstants;
49 import com.sun.enterprise.config.serverbeans.HttpService;
50 import com.sun.enterprise.config.serverbeans.HttpListener;
51 import com.sun.enterprise.config.serverbeans.Server;
52 import com.sun.enterprise.config.serverbeans.Domain;
53 import com.sun.enterprise.config.serverbeans.Configs;
54 import com.sun.enterprise.config.serverbeans.Servers;
55 import com.sun.enterprise.config.serverbeans.ServerBeansFactory;
56 import com.sun.enterprise.config.serverbeans.Config;
57 import com.sun.enterprise.config.ConfigContext;
58 import com.sun.enterprise.config.ConfigException;
59 import com.sun.enterprise.config.ConfigFactory;
60 import com.sun.enterprise.instance.InstanceEnvironment;
61 import com.sun.enterprise.util.i18n.StringManager;
62 import com.sun.enterprise.instance.ServerManager;
63 import com.sun.enterprise.server.ServerContext;
64 import com.sun.enterprise.admin.server.core.AdminService;
65 import com.sun.enterprise.admin.common.MBeanServerFactory;
66 import com.sun.enterprise.config.ConfigContext;
67 import com.sun.enterprise.deployment.util.DeploymentProperties;
68 import com.sun.enterprise.deployment.backend.DeploymentStatus;
69 import java.util.Properties JavaDoc;
70 import java.util.HashMap JavaDoc;
71 import java.util.Date JavaDoc;
72 import java.io.IOException JavaDoc;
73 /**
74  * Handles the logic of deploying the module/app to the required destination.</br>
75  * The destination can be modified by calling setTarget(), default is first non-admin instance entry from domain.xml</br>
76  * The specific directory scanner can be set using setDirectoryScanner, default is AutoDeployDirectoryScanner</br>
77  * Present logic is using MBean ManagedServerInstance as actual deployment service.
78  * @author vikas
79  */

80 public class AutoDeployer {
81     
82     private ObjectName JavaDoc mbeanName = null;
83     private MBeanServer JavaDoc mbs=null;
84     
85     private Boolean JavaDoc verify=null;
86     private Boolean JavaDoc forceDeploy=null;
87     private Boolean JavaDoc enabled=null;
88     private Boolean JavaDoc jspPreCompilation=null;
89     private boolean renameOnSuccess = true;
90     
91     private String JavaDoc targetInstance=null;
92     private static final Logger JavaDoc sLogger=AutoDeployControllerImpl.sLogger;
93     private static StringManager localStrings =
94             StringManager.getManager( AutoDeployer.class );
95     private DirectoryScanner directoryScanner=null;
96     
97     private boolean cancelDeployment =false;
98     
99     /*
100      *Represent the result of attempting autodeployment of a single file.
101      *PENDING indicates the file could not be opened as an archive,
102      *perhaps because the file was still in the process of being copied when
103      *the autodeployer tried to work with it. PENDING could also mean
104      *that the file has changed size since the last time the autodeployer
105      *checked it. It's then reasonable to think it might grow further,
106      *so autodeployer waits until the next time through to check it again.
107      */

108     protected static final int DEPLOY_SUCCESS = 1;
109     protected static final int DEPLOY_FAILURE = 2;
110     protected static final int DEPLOY_PENDING = 3;
111     
112     /**
113      * archive factory used to create an archive for each file to be deployed -
114      *the archive is needed by Depl. Facility
115      */

116     private final AbstractArchiveFactory archiveFactory = new ArchiveFactory();
117     
118     private AutodeployRetryManager retryManager = new AutodeployRetryManager();
119     /**
120      * Creates a new instance of AutoDeployer */

121     public AutoDeployer() {
122         
123         ///initialize other attributes
124
verify= new Boolean JavaDoc(false);
125         jspPreCompilation=new Boolean JavaDoc(false);
126         forceDeploy=new Boolean JavaDoc(true);
127         enabled=new Boolean JavaDoc(true);
128     }
129     
130     /**
131      * Creates a new instance of AutoDeployer */

132     public AutoDeployer(boolean verify, boolean jspPreCompilation) {
133         
134         ///initialize other attributes
135
this.verify= new Boolean JavaDoc(verify);
136         this.jspPreCompilation=new Boolean JavaDoc(jspPreCompilation);
137         forceDeploy=new Boolean JavaDoc(true);
138         enabled=new Boolean JavaDoc(true);
139     }
140     
141     /**
142      * set DirectoryScanner which will be used for filtering out deployeble component
143      * @return
144      */

145     public void setDirectoryScanner(DirectoryScanner ds) {
146         directoryScanner=ds;
147     }
148     
149     /**
150      * set target server where the autual deployment will be done
151      * @return
152      */

153     public void setTarget(String JavaDoc target) {
154         this.targetInstance = target;
155         mbeanName = getMBean(targetInstance);
156     }
157     
158     /**
159      * If an archive is successfully autodeployed, file will not be
160      * renamed to archive_deployed
161      */

162     public void disableRenameOnSuccess() {
163         renameOnSuccess = false;
164     }
165     
166     /**
167      * If an archive is successfully autodeployed will be renamed
168      * to archive_deployed
169      */

170     public void enableRenameOnSuccess() {
171         // FIXME - Mahesh
172
renameOnSuccess = true;
173     }
174     
175     /**
176      *Set whether this AutoDeployer should verify or not.
177      *@param boolean verify setting
178      */

179     public void setVerify(boolean verify) {
180         this.verify = new Boolean JavaDoc(verify);
181     }
182     
183     /**
184      *Set whether this AutoDeployer should precompile JSPs or not.
185      *@param boolean precompilation setting
186      */

187     public void setJspPreCompilation(boolean jspPreCompilation) {
188         this.jspPreCompilation = new Boolean JavaDoc(jspPreCompilation);
189     }
190     
191     /**
192      * do deployment for all the deployable components in autoDeployDir dir.
193      * @return
194      */

195     public void deployAll(File JavaDoc autoDeployDir , boolean verify, boolean jspPreCompilation) throws AutoDeploymentException {
196         this.verify= new Boolean JavaDoc(verify);
197         this.jspPreCompilation=new Boolean JavaDoc(jspPreCompilation);
198         deployAll(autoDeployDir);
199     }
200
201     /**
202      * do deployment for all the deployable components in autoDeployDir dir.
203      * @return
204      */

205     public void deployAll(File JavaDoc autoDeployDir) throws AutoDeploymentException {
206         deployAll(autoDeployDir, false);
207     }
208     
209     /**
210      * do deployment for all the deployable components in autoDeployDir dir.
211      * @return
212      */

213     public void deployAll(File JavaDoc autoDeployDir, boolean includeSubDir) throws AutoDeploymentException {
214         
215         
216         //create with default scanner
217
if(directoryScanner==null) {
218             directoryScanner=new AutoDeployDirectoryScanner();
219         }
220         
221         //set target to default
222
if(this.targetInstance == null) {
223             setTarget(getDefaultTarget());
224         }
225         
226         File JavaDoc [] files= null;
227         
228         //get me all deployable entities
229
files= directoryScanner.getAllDeployableModules(autoDeployDir, includeSubDir);
230         
231         /*
232          *The following pattern appears in each of the sections below, even though
233          *it is described in detail only once here. This can be improved
234          *once autodeploy is converted to use the DeploymentFacility.
235          *
236          *To support slowly-copied files, the deployApplication (and deployWarmodule, and
237          *deployRarModule and deployEjbModule) methods return
238          * DEPLOY_SUCCESS if the file was successfully autodeployed
239          * DEPLOY_FAILURE if the file failed to be autodeployed
240          * DEPLOY_PENDING if the file needs to be tried again later
241          *
242          *The marker files should be updated only if the result is success or
243          *failure. So for each file of each type, make a separate decision
244          *about whether to record the result or not based on the result of
245          *the deploy* method. Note that the boolean is initialized to true
246          *so that if an exception is thrown, the file's marker files will be
247          *updated.
248          */

249         if(files != null) {
250             for (int i=0; ((i < files.length) && !cancelDeployment);i++) {
251                 boolean okToRecordResult = true;
252                 try {
253                     okToRecordResult = (deploy(files[i], getNameFromFilePath(autoDeployDir, files[i])) != DEPLOY_PENDING);
254                 } catch (AutoDeploymentException ae) {
255                     //ignore and move to next file
256
} finally {
257                     if(renameOnSuccess && okToRecordResult)
258                         directoryScanner.deployedEntity(autoDeployDir, files[i]);
259                 }
260             }
261         }
262     }
263     
264     
265     
266     /**
267      * do undeployment for all deleted applications in autoDeployDir dir.
268      * @return
269      */

270     public void undeployAll(File JavaDoc autoDeployDir) throws AutoDeploymentException {
271         
272         
273         //create with default scanner
274
if(directoryScanner==null) {
275             directoryScanner=new AutoDeployDirectoryScanner();
276         }
277         
278         if(mbs == null) {
279             mbs = getMBeanServer();
280         }
281         //set target to default
282
if(this.targetInstance == null) {
283             setTarget(getDefaultTarget());
284         }
285         
286         File JavaDoc[] apps= null;
287         
288         //get me all apps
289
apps= directoryScanner.getAllFilesForUndeployment(autoDeployDir);
290         
291         //deploying all applications
292
if(apps !=null) {
293             for (int i=0; i< apps.length && !cancelDeployment;i++) {
294                 try {
295                     
296                     boolean stat = this.undeployApplication(apps[i], getNameFromFilePath(autoDeployDir, apps[i]));
297                     if (stat)
298                         markUndeployed(apps[i]);
299                     else
300                         markUndeployFailed(apps[i]);
301                     
302                     
303                 } catch (AutoDeploymentException ae) {
304                     //ignore and move to next file
305
markUndeployFailed(apps[i]);
306                 } finally {
307                     // Mark the application as undeployed both in the case of success & failure.
308
directoryScanner.undeployedEntity(autoDeployDir, apps[i]);
309                 }
310             }
311         }
312         /////////end for apps
313
}
314     private boolean undeployApplication(File JavaDoc applicationFile, String JavaDoc name) throws AutoDeploymentException {
315         boolean status = false;
316         
317         Properties JavaDoc props = getUndeployActionProperties(name);
318         
319         String JavaDoc[] signature = new String JavaDoc[]{"java.util.Properties"};
320         
321         Object JavaDoc[] params = new Object JavaDoc[]{props};
322         sLogger.log(Level.INFO, "Autoundeploying application :" + name);
323         status = invokeUndeploymentService(applicationFile.getAbsolutePath(), AutoDeployConstants.UNDEPLOY_METHOD,params,signature);;
324         String JavaDoc msg = localStrings.getString("enterprise.deployment.autodeploy.autoundeploying_application",applicationFile);
325         sLogger.log(Level.INFO, msg);
326         return status;
327         
328     }
329     
330     /**
331      * set cancel flag, which will ensure that only if there is any current deployment is in process,</br>
332      * it will be completed but the deployer will not do any more deployment.
333      * @return
334      */

335     public void setCancel(boolean value){
336         cancelDeployment=value;
337     }
338     
339     /**
340      * get cancel flag value
341      * @return
342      */

343     public boolean isCancelled(){
344         return cancelDeployment;
345     }
346     
347     /**
348      * setup the required internal variables
349      */

350     
351     void init() throws AutoDeploymentException{
352         // this sets 'mbs'
353
getMBeanServer();
354         
355         if(targetInstance == null) {
356             // side effect -- this also sets mbeanName...
357
setTarget(getDefaultTarget());
358         }
359     }
360         
361     /**
362      *Deploy any type of module.
363      *@param file Absolute path of the file to be deployed
364      *@param name the module ID of the applications
365      *@return status of the deployment attempt: DEPLOY_SUCCESS, DEPLOY_FAILURE, or DEPLOY_PENDING
366      *@throws AutoDeploymentException if any invoked method throws an exception
367      */

368     protected int deploy(File JavaDoc deployablefile, String JavaDoc name) throws AutoDeploymentException {
369         
370         int status=DEPLOY_FAILURE;
371         if(cancelDeployment) {
372             return status;
373         }
374         String JavaDoc file=deployablefile.getAbsolutePath();
375         status = retryManager.testFileAsArchive(file);
376         if (status != DEPLOY_SUCCESS) {
377             return status;
378         }
379
380         // if it's redeploy, first undeploy, then deploy
381
if (isModuleDeployed(name)) {
382             boolean result = undeployApplication(deployablefile, name);
383             if (!result) {
384                 return DEPLOY_FAILURE;
385             }
386         }
387
388         Properties JavaDoc props = getDeployActionProperties(deployablefile,name);
389         String JavaDoc[] signature = new String JavaDoc[]{"java.util.Properties"};
390         
391         Object JavaDoc[] params = new Object JavaDoc[]{props};
392         
393         //invoke
394
if (invokeDeploymentService(deployablefile, AutoDeployConstants.DEPLOY_METHOD,params,signature)) {
395             status = DEPLOY_SUCCESS;
396         } else {
397             status = DEPLOY_FAILURE;
398         }
399         return status;
400     }
401     
402     boolean invokeDeploymentService(File JavaDoc deployablefile, String JavaDoc action,
403             Object JavaDoc[] params,String JavaDoc[] signature) throws AutoDeploymentException {
404         
405         String JavaDoc file=deployablefile.getAbsolutePath();
406         boolean status=false;
407         
408         String JavaDoc msg = localStrings.getString("enterprise.deployment.autodeploy.selecting_file",deployablefile.getAbsolutePath());
409         sLogger.log(Level.INFO, msg);
410         
411         //invoke
412
try {
413             Object JavaDoc result=getMBeanServer().invoke(getMBeanName(),action, params,signature);
414             status =parseResult(result);
415         } catch (Exception JavaDoc e) {
416             while (e instanceof MBeanException JavaDoc) {
417                 e = ((MBeanException JavaDoc)e).getTargetException();
418             }
419             status = false;
420             msg = localStrings.getString("enterprise.deployment.autodeploy.invocation_exception",file);
421             AutoDeploymentException ae;
422             ae=new AutoDeploymentException(msg, e);
423             sLogger.log(Level.INFO, ae.getMessage());
424             throw ae;
425         } finally {
426             if(status) {
427                 if(renameOnSuccess)
428                     markDeployed(deployablefile);
429                 msg = localStrings.getString("enterprise.deployment.autodeploy.successfully_autodeployed",file);
430                 sLogger.log(Level.INFO, msg);
431             } else {
432                 markDeployFailed(deployablefile);
433                 // FIXME - Use localized message
434
msg = localStrings.getString("enterprise.deployment.autodeploy.autodeploy_failed",file);
435                 sLogger.log(Level.INFO, msg);
436             }
437             
438         }
439         return status;
440         
441     }
442     
443     /**
444      * get the MBean Name.
445      * bnevins 9/16/03
446      */

447     
448     final ObjectName JavaDoc getMBeanName() throws AutoDeploymentException {
449         if(mbeanName == null)
450             throw new AutoDeploymentException("Internal Error: mbeanName is null");
451         
452         return mbeanName;
453     }
454     
455     /**
456      * get the MBeanServer. Initialize it if neccessary.
457      * Note that the 'final' allows the compiler to inline
458      * the method. So this will be just as fast as accessing the variable
459      * directly.
460      * bnevins 9/16/03
461      */

462     
463     final MBeanServer JavaDoc getMBeanServer() throws AutoDeploymentException {
464         if(mbs == null)
465             mbs = MBeanServerFactory.getMBeanServer();
466         
467         return mbs;
468     }
469     
470     
471     private ObjectName JavaDoc getMBean(String JavaDoc instanceName) {
472         ObjectName JavaDoc mbean=null;
473         //mbean=ObjectNames.getServerInstanceObjectName(instanceName); //changing to ApplicationsConfigMBean
474
try {
475             mbean = new ObjectName JavaDoc("com.sun.appserv:type=applications,category=config");
476         } catch(Exception JavaDoc e) {
477             sLogger.log(Level.SEVERE, "enterprise.deployment.backend.autoDeploymentFailure",
478                     new Object JavaDoc[] {e.getMessage()});
479         }
480         return mbean;
481         
482     }
483     
484     private boolean isModuleDeployed (String JavaDoc moduleID) {
485         if (moduleID == null) {
486             return false;
487         }
488
489         try {
490             String JavaDoc[] signature = new String JavaDoc[] {"java.lang.String"};
491             Object JavaDoc[] params = new Object JavaDoc[] {moduleID};
492             Object JavaDoc result = getMBeanServer().invoke(getMBeanName(),
493                 "getModuleType", params, signature);
494
495             if (result != null) {
496                 return true;
497             }
498             return false;
499         } catch (Exception JavaDoc e) {
500             return false;
501         }
502     }
503
504     private String JavaDoc getDefaultVirtualServer(String JavaDoc instanceName) {
505         String JavaDoc virtualServer=null;
506         try {
507             ConfigContext context = getConfigContext();
508             //Domain domain = (Domain)context.getRootConfigBean();
509
//HttpService service = getHttpService(domain,instanceName);
510
HttpService service = ServerBeansFactory.getHttpServiceBean(context);
511             if(service !=null){
512                 HttpListener[] hlArray = service.getHttpListener();
513                 //check not needed since there should always be atleast 1 httplistener
514
//if you don't find one, use first one.
515
HttpListener ls = null;
516                 if(hlArray != null && hlArray.length > 0){
517                     ls=hlArray[0];
518                     //default is the first one that is enabled.
519
for(int i = 0;i<hlArray.length;i++) {
520                         if(hlArray[i].isEnabled()) {
521                             ls = hlArray[i];
522                             break;
523                         }
524                     }
525                 }
526                 if(ls!=null)
527                     virtualServer = ls.getDefaultVirtualServer();
528             }
529         } catch(ConfigException e){
530             String JavaDoc msg = localStrings.getString("enterprise.deployment.autodeploy.unable_to_get_virtualserver");
531             sLogger.log(Level.WARNING, msg+e.getMessage());
532         } catch(Exception JavaDoc e){String JavaDoc msg = localStrings.getString("enterprise.deployment.autodeploy.unable_to_get_virtualserver");
533         sLogger.log(Level.WARNING, msg+e.getMessage());
534         }
535         
536         return virtualServer;
537         
538     }
539
540     private String JavaDoc getDefaultTarget() throws AutoDeploymentException {
541         try{
542             ConfigContext confContext = getConfigContext();
543             Domain domain = (Domain)confContext.getRootConfigBean();
544             Servers svrs = domain.getServers();
545             Server JavaDoc[] svrArr = svrs.getServer();
546             int size = svrArr.length;
547             String JavaDoc targetName = null;
548             /*I am putting this logic specific for TP, as its decided to deploy directly
549              *to instsnce, and not DAS. It need to be changed to next release
550              */

551             for(int i = 0 ; i< size; i++) {
552                 if(!svrArr[i].getName().equals("")) {
553                     targetName = svrArr[i].getName();
554                     break;
555                 }
556             }
557             if(targetName == null) {
558                 sLogger.log(Level.SEVERE, "enterprise.deployment.backend.autoDeploymentFailure",
559                         new Object JavaDoc[] {"Target server not found"});
560                         throw new AutoDeploymentException("Target Server not found");
561             }
562             
563             return targetName;
564         }catch(Exception JavaDoc ex) {
565             return null;
566         }
567     }
568     
569     
570     private ConfigContext getConfigContext() throws ConfigException {
571         /*InstanceEnvironment instanceEnvironment =
572         new InstanceEnvironment(instanceName);
573         String fileUrl = instanceEnvironment.getConfigFilePath();
574          
575         ConfigContext configContext =
576         ConfigFactory.createConfigContext(fileUrl);*/

577         ServerContext serverContext = AdminService.getAdminService().getContext();
578         ConfigContext context = serverContext.getConfigContext();
579         return context;
580     }
581     
582     
583     
584     protected boolean parseResult(Object JavaDoc result) {
585         if(result!=null && result instanceof DeploymentStatus) {
586             DeploymentStatus status = (DeploymentStatus) result;
587             if (status.getStatus()>DeploymentStatus.WARNING) {
588                 return true;
589             } else {
590                 // ok we got either a warning or an error.
591
// parse the deployment status and retrieve failure/warning msg
592
ByteArrayOutputStream JavaDoc bos =
593                         new ByteArrayOutputStream JavaDoc();
594                 PrintWriter JavaDoc pw = new PrintWriter JavaDoc(bos);
595                 DeploymentStatus.parseDeploymentStatus(status, pw);
596                 byte[] statusBytes = bos.toByteArray();
597                 String JavaDoc statusString = new String JavaDoc(statusBytes);
598                 
599                 if (status.getStatus()==DeploymentStatus.WARNING) {
600                     // warning, let's log and continue
601
String JavaDoc msg = localStrings.getString(
602                             "enterprise.deployment.warning_occured", statusString);
603                     sLogger.log(Level.WARNING, msg);
604                     // this is still considered a success
605
return true;
606                 } else if (status.getStatus()==DeploymentStatus.FAILURE) {
607                     sLogger.log(Level.SEVERE, "enterprise.deployment.backend.autoDeploymentFailure",
608                             new Object JavaDoc[] {statusString});
609                             return false;
610                 }
611             }
612         }
613         return false;
614     }
615     
616     static String JavaDoc getNameFromFilePath(File JavaDoc autodeployDir, File JavaDoc filePath) { //creating module name as file name
617

618         File JavaDoc parent = filePath.getParentFile();
619         String JavaDoc moduleName = null;
620         while (!parent.getAbsolutePath().equals(autodeployDir.getAbsolutePath())) {
621             if (moduleName==null) {
622                 moduleName = parent.getName();
623             } else {
624                 moduleName = parent.getName()+"_"+moduleName;
625             }
626             parent = parent.getParentFile();
627         }
628         if (moduleName==null) {
629             moduleName = filePath.getName();
630         } else {
631             moduleName = moduleName + "_" + filePath.getName();
632         }
633         int toIndex = moduleName.lastIndexOf('.');
634         if (toIndex > 0) {
635             moduleName = moduleName.substring(0, toIndex);
636         }
637         return moduleName;
638     }
639     
640     // Methods for creating operation status file(s)
641
protected void markDeployed(File JavaDoc f) {
642         try {
643             deleteAllMarks(f);
644             getDeployedFile(f).createNewFile();
645         } catch (Exception JavaDoc e) {}
646     }
647     
648     protected void markDeployFailed(File JavaDoc f) {
649         try {
650             deleteAllMarks(f);
651             getDeployFailedFile(f).createNewFile();
652         } catch (Exception JavaDoc e) {}
653     }
654     
655     protected void markUndeployed(File JavaDoc f) {
656         try {
657             deleteAllMarks(f);
658             getUndeployedFile(f).createNewFile();
659         } catch (Exception JavaDoc e) {}
660     }
661     
662     protected void markUndeployFailed(File JavaDoc f) {
663         try {
664             deleteAllMarks(f);
665             getUndeployFailedFile(f).createNewFile();
666         } catch (Exception JavaDoc e) {}
667     }
668     
669     protected void deleteAllMarks(File JavaDoc f) {
670         try {
671             getDeployedFile(f).delete();
672             getDeployFailedFile(f).delete();
673             getUndeployedFile(f).delete();
674             getUndeployFailedFile(f).delete();
675         } catch (Exception JavaDoc e) {}
676     }
677     
678     protected File JavaDoc getDeployedFile(File JavaDoc f) {
679         String JavaDoc absPath = f.getAbsolutePath();
680         File JavaDoc ret = new File JavaDoc(absPath + AutoDeployConstants.DEPLOYED);
681         return ret;
682     }
683     
684     protected File JavaDoc getDeployFailedFile(File JavaDoc f) {
685         String JavaDoc absPath = f.getAbsolutePath();
686         File JavaDoc ret = new File JavaDoc(absPath + AutoDeployConstants.DEPLOY_FAILED);
687         return ret;
688     }
689     
690     protected File JavaDoc getUndeployedFile(File JavaDoc f) {
691         String JavaDoc absPath = f.getAbsolutePath();
692         File JavaDoc ret = new File JavaDoc(absPath + AutoDeployConstants.UNDEPLOYED);
693         return ret;
694     }
695     
696     protected File JavaDoc getUndeployFailedFile(File JavaDoc f) {
697         String JavaDoc absPath = f.getAbsolutePath();
698         File JavaDoc ret = new File JavaDoc(absPath + AutoDeployConstants.UNDEPLOY_FAILED);
699         return ret;
700     }
701     
702     private boolean invokeUndeploymentService(String JavaDoc appFile, String JavaDoc action,
703             Object JavaDoc[] params,String JavaDoc[] signature) throws AutoDeploymentException {
704         
705         boolean status=false;
706         //invoke
707
try {
708             Object JavaDoc result=getMBeanServer().invoke(getMBeanName(),action, params,signature);
709             status =parseResult(result);
710         } catch (Exception JavaDoc e) {
711             while (e instanceof MBeanException JavaDoc) {
712                 e = ((MBeanException JavaDoc)e).getTargetException();
713             }
714             status = false;
715             String JavaDoc msg = localStrings.getString("enterprise.deployment.autodeploy.invocation_exception",appFile);
716             AutoDeploymentException ae;
717             ae=new AutoDeploymentException(msg, e);
718             sLogger.log(Level.INFO, ae.getMessage());
719             throw ae;
720         } finally {
721             if(status) {
722                 String JavaDoc msg = localStrings.getString("enterprise.deployment.autodeploy.successfully_autoundeployed",appFile);
723                 sLogger.log(Level.INFO, msg);
724             } else {
725                 String JavaDoc msg = localStrings.getString("enterprise.deployment.autodeploy.autoundeploy_failed",appFile);
726                 sLogger.log(Level.INFO, msg);
727             }
728             
729         }
730         return status;
731         
732     }
733     
734     
735     
736     protected Properties JavaDoc getDeployActionProperties(File JavaDoc deployablefile, String JavaDoc ID){
737         
738         DeploymentProperties dProps = new DeploymentProperties();
739         dProps.setArchiveName(deployablefile.getAbsolutePath());
740         dProps.setName(ID);
741         dProps.setEnable(enabled.booleanValue());
742         dProps.setVirtualServers(getDefaultVirtualServer(targetInstance));
743         dProps.setForce(forceDeploy.booleanValue());
744         dProps.setVerify(verify.booleanValue());
745         dProps.setPrecompileJSP(jspPreCompilation.booleanValue());
746         dProps.setResourceAction(DeploymentProperties.RES_DEPLOYMENT);
747         dProps.setResourceTargetList("server");
748
749         return (Properties JavaDoc)dProps;
750     }
751
752     protected Properties JavaDoc getUndeployActionProperties(String JavaDoc name){
753         DeploymentProperties dProps = new DeploymentProperties();
754         dProps.setName(name);
755         dProps.setResourceAction(DeploymentProperties.RES_UNDEPLOYMENT);
756         dProps.setResourceTargetList("server");
757
758         return (Properties JavaDoc)dProps;
759     }
760
761     /**
762      *Manages retrying of autodeployed files in case a file is copied slowly.
763      *<p>
764      *If a file is copied into the autodeploy directory slowly, it can appear there
765      *before the copy has finished, causing the attempt to autodeploy it to fail.
766      *This class encapsulates logic to retry such files on successive loops through
767      *the autodeployer thread, reporting failure only if the candidate file remains
768      *stable in size and cannot be opened after a period of time which defaults below
769      *and is configurable using the config property name defined below.
770      *<p>
771      *The main public entry point is the openAsArchive method, which accepts a file and
772      *tries to open it as an archive. (The archive returned will be useful when
773      *AutoDeployer is converted to use the DeploymentFacility.) When AutoDeployer tries
774      *and fails to open a file as an archive, it records
775      *that fact internally. The manager adds to or updates
776      *a map that describes all such failed files. If AutoDeployer previously
777      *reported failures to open the file and the file's size has been stable
778      *for a configurable period of time, then the manager concludes that the
779      *file is not simply a slow-copying file but is truly invalid. In that case
780      *it throws an exception. When a file fails to open as an archive the first time,
781      *or if it has failed to open before but its size has changed within the configurable
782      *time, then the manager returns a null to indicate that we need to wait before trying
783      *to process the file. Once a file opens successfully, any record of that file is removed
784      *from the map.
785      */

786     class AutodeployRetryManager {
787         
788         /**
789          *Specifies the config property name and default and actual values for the retry limit.
790          */

791         private final String JavaDoc RETRY_LIMIT_NAME = "com.sun.appserv.autodeploy.retry.limit";
792         private final long RETRY_LIMIT_DEFAULT = 30 * 1000; // 30 seconds
793
private final long RETRY_LIMIT = Long.getLong(RETRY_LIMIT_NAME, RETRY_LIMIT_DEFAULT).longValue();
794         
795         /** Maps an invalid File to its corresponding Info object. */
796         private HashMap JavaDoc invalidFiles = new HashMap JavaDoc();
797         
798         /**
799          *Records pertinent information about a file judged to be invalid - that is,
800          *unrecognizable as a legal archive:
801          *<ul>
802          *<li>the file object,
803          *<li>the length of the file at the most recent check of the file,
804          *<li>the time after which no more retries should be attempted.
805          *</ul>
806          */

807         class Info {
808             /** File recorded in this Info instance */
809             private File JavaDoc file = null;
810             
811             /** File length the previous time this file was reported as
812              * invalid. */

813             private long recordedLength = 0;
814             
815             /** Timestamp after which all retries on this file should stop. */
816             private long retryExpiration = 0;
817             
818             /**
819              *Creates a new instance of the Info object for the specified file.
820              *@param File to be recorded
821              */

822             public Info(File JavaDoc file) {
823                 this.file = file;
824                 update();
825             }
826             
827             /**
828              *Updates the Info object with the file's length and recomputes (if
829              *appropriate) the retry due date and the expiration.
830              */

831             private void update() {
832                 long currentLength = file.length();
833                 if (recordedLength != currentLength) {
834                     /*
835                      *The file's size has changed. Reset the time for this
836                      *file's expiration.
837                      */

838                     long now = new Date JavaDoc().getTime();
839                     retryExpiration = now + RETRY_LIMIT;
840                 }
841                 /*
842                  *In all cases, update the recorded length with the file's
843                  *actual current length.
844                  */

845                 recordedLength = currentLength;
846             }
847             
848             /**
849              *Reports whether the file represented by the Info instance is
850              *eligible for retry.
851              *<p>
852              *A file is eligible for retry if its length has changed since
853              *the last recorded failure or if the length is stable but has not
854              *yet been stable for the expiration period.
855              *@return if the file should remain as a candidate for retry
856              */

857             private boolean isEligibleForRetry() {
858                 long now = new Date JavaDoc().getTime();
859                 boolean result = (now < retryExpiration);
860                 return result;
861             }
862             
863         }
864         
865         /**
866          *Tests to see if the file can be opened as an archive.
867          *<p>
868          *This method will not be needed if the main autodeployer uses
869          *the deployment facility. This is because the deployment facility
870          *method invocations use an archive, so the openFileAsArchive method
871          *will be used instead of this one.
872          *@param file spec to be tested
873          *@return whether the file was opened as an archive (DEPLOY_SUCCESS),
874          * was not but should be tried later (DEPLOY_PENDING), or was
875          * not and should not be tried later (DEPLOY_FAILURE).
876          *@throws AutoDeploymentException if an error occurred closing the archive
877          */

878         int testFileAsArchive(String JavaDoc file) throws AutoDeploymentException {
879             int result;
880             try {
881                 File JavaDoc inFile = new File JavaDoc(file);
882                 if (!inFile.isDirectory()) {
883                     // either a j2ee jar file or a .class file
884
if (file.endsWith(".class")) {
885                         return DEPLOY_SUCCESS;
886                     }
887                 }
888                 AbstractArchive arch = openFileAsArchive(file);
889                 if (arch != null) {
890                     result = DEPLOY_SUCCESS;
891                     arch.close();
892                 } else {
893                     result = DEPLOY_PENDING;
894                 }
895             } catch (AutoDeploymentException ade) {
896                 result = DEPLOY_FAILURE;
897             } catch (IOException JavaDoc ioe) {
898                 String JavaDoc msg = localStrings.getString("enterprise.deployment.autodeploy.error_closing_archive", file);
899                 throw new AutoDeploymentException(msg, ioe);
900             }
901             return result;
902         }
903         
904         /**
905          *Opens the specified file as an archive and tracks files that have
906          *failed to open as archives.
907          *@param String the file to try opening as an archive
908          *@return the AbstractArchive for the file (null if it shoudl be tried later)
909          *@throws AutoDeploymenException if the manager has been unable to open
910          *the file as an archive past the configured expiration time
911          */

912         AbstractArchive openFileAsArchive(String JavaDoc file) throws AutoDeploymentException {
913             AbstractArchive archive = null;
914             File JavaDoc f = new File JavaDoc(file);
915             if (shouldOpen(f)) {
916                 try {
917                     /*
918                      Try to open the file as an archive and then remove the file, if
919                      *it is present, from the map tracking invalid files.
920                      */

921                     archive = archiveFactory.openArchive(file);
922                     
923                     recordSuccessfulOpen(f);
924                     
925                 } catch (IOException JavaDoc ioe) {
926                     String JavaDoc errorMsg = null;
927                     /*
928                      *If the archive variable was not assigned a non-null, then the file
929                      *is not a valid archive.
930                      */

931                     if (archive == null) {
932                         boolean failedPreviously = recordFailedOpen(f);
933                         if ( ! failedPreviously) {
934                             Info info = get(f);
935                             errorMsg = localStrings.getString("enterprise.deployment.autodeploy.error_opening_start_retry", file, new Date JavaDoc(info.retryExpiration).toString());
936                             sLogger.log(Level.INFO, errorMsg);
937                         }
938                     }
939                 }
940             }
941             return archive;
942         }
943         
944         /**
945          *Retrieves the Info object describing the specified file.
946          *@param File for which the Info object is requested
947          *@return Info object for the specified file
948          *null if the file is not recorded as invalid
949          */

950         Info get(File JavaDoc file) {
951             Info info = (Info) invalidFiles.get(file);
952             return info;
953         }
954         
955         /**
956          *Indicates whether the AutoDeployer should try opening the specified
957          *file as an archive.
958          *<p>
959          *The file should be opened if this retry manager has no information
960          *about the file or if information is present and the file size is
961          *unchanged from the previous failure to open.
962          *@return if the file should be opened as an archive
963          */

964         private boolean shouldOpen(File JavaDoc file) {
965             boolean result = true; // default is true in case the file is not being monitored
966
String JavaDoc msg = null;
967             boolean loggable = sLogger.isLoggable(Level.FINE);
968             Info info = (Info) invalidFiles.get(file);
969             if (info != null) {
970                 result = (file.length() == info.recordedLength);
971                 if (loggable) {
972                     if (result) {
973                         msg = localStrings.getString("enterprise.deployment.autodeploy.try_stable_length", file.getAbsolutePath());
974                     } else {
975                         msg = localStrings.getString("enterprise.deployment.autodeploy.no_try_unstable_length", file.getAbsolutePath(), String.valueOf(file.length()));
976                     }
977                 }
978                 info.update();
979             } else {
980                 if (loggable) {
981                     msg = localStrings.getString("enterprise.deployment.autodeploy.try_not_monitored", file.getAbsolutePath());
982                 }
983             }
984             if (loggable) {
985                 sLogger.log(Level.FINE, msg);
986             }
987             return result;
988         }
989         
990         /**
991          *Records the fact that the autodeployer tried but failed to open this file
992          *as an archive.
993          *@param File the file that could not be interpreted as a legal archive
994          *@return true if the file was previously recognized as an invalid one
995          *@throws AutoDeploymentException if the file should no longer be retried
996          */

997         private boolean recordFailedOpen(File JavaDoc file) throws AutoDeploymentException {
998             boolean fileAlreadyPresent;
999             /*
1000             *Try to map the file to an existing Info object for it.
1001             */

1002            Info info = get(file);
1003            if (info == null) {
1004                /*
1005                 *This file was not previously noted as invalid. Create a new
1006                 *entry and add it to the map.
1007                 */

1008                fileAlreadyPresent = false;
1009                info = new Info(file);
1010                invalidFiles.put(file, info);
1011                if (sLogger.isLoggable(Level.FINE)) {
1012                    String JavaDoc msg = localStrings.getString("enterprise.deployment.autodeploy.begin_monitoring", file.getAbsolutePath(), new Date JavaDoc(info.retryExpiration).toString());
1013                    sLogger.log(Level.FINE, msg);
1014                }
1015            } else {
1016                /*
1017                 *The file has previously been recorded as invalid. Update
1018                 *the recorded info.
1019                 */

1020                fileAlreadyPresent = true;
1021                info.update();
1022                
1023                /*
1024                 *If the file is still eligible for later retries, just return.
1025                 *If the file size has been stable too long, then conclude that
1026                 *the file is just an invalid archive and throw an exception
1027                 *to indicate that.
1028                 */

1029                boolean loggable = sLogger.isLoggable(Level.FINE);
1030                if (info.isEligibleForRetry()) {
1031                    /*
1032                     *Just log that the file is still being monitored.
1033                     */

1034                    if (loggable) {
1035                        String JavaDoc msg = localStrings.getString("enterprise.deployment.autodeploy.continue_monitoring", file.getAbsolutePath(), new Date JavaDoc(info.retryExpiration).toString());
1036                        sLogger.log(Level.FINE, msg);
1037                    }
1038                } else {
1039                    /*
1040                     *Log that monitoring of this file will end, remove the file from
1041                     *the map, and throw an exception
1042                     *with the same message.
1043                     */

1044                    String JavaDoc msg = localStrings.getString("enterprise.deployment.autodeploy.abort_monitoring",
1045                            file.getAbsolutePath(), String.valueOf(RETRY_LIMIT));
1046                    if (loggable) {
1047                        sLogger.log(Level.FINE, msg);
1048                    }
1049                    invalidFiles.remove(file);
1050                    throw new AutoDeploymentException(msg);
1051                }
1052            }
1053            return fileAlreadyPresent;
1054        }
1055        
1056        /**
1057         *Marks a file as successfully opened and no longer subject to retry.
1058         *@param File that is no longer invalid
1059         *@return true if the file had been previously recorded as invalid
1060         */

1061        private boolean recordSuccessfulOpen(File JavaDoc file) {
1062            if (sLogger.isLoggable(Level.FINE)) {
1063                String JavaDoc msg = localStrings.getString("enterprise.deployment.autodeploy.end_monitoring", file.getAbsolutePath());
1064                sLogger.log(Level.FINE, msg);
1065            }
1066            return (invalidFiles.remove(file)) != null;
1067        }
1068    }
1069    
1070    
1071    
1072}
1073
1074
Popular Tags