Coverage Report - org.mule.module.launcher.DefaultMuleDeployer
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultMuleDeployer
0%
0/89
0%
0/34
9.2
 
 1  
 /*
 2  
  * $Id: DefaultMuleDeployer.java 20719 2010-12-14 19:23:28Z aperepel $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.module.launcher;
 12  
 
 13  
 import org.mule.config.i18n.MessageFactory;
 14  
 import org.mule.module.launcher.application.Application;
 15  
 import org.mule.module.reboot.MuleContainerBootstrapUtils;
 16  
 import org.mule.util.FileUtils;
 17  
 import org.mule.util.FilenameUtils;
 18  
 
 19  
 import java.beans.Introspector;
 20  
 import java.io.File;
 21  
 import java.io.IOException;
 22  
 import java.net.URISyntaxException;
 23  
 import java.net.URL;
 24  
 import java.util.concurrent.TimeUnit;
 25  
 import java.util.concurrent.locks.ReentrantLock;
 26  
 
 27  
 import org.apache.commons.logging.Log;
 28  
 import org.apache.commons.logging.LogFactory;
 29  
 
 30  
 public class DefaultMuleDeployer implements MuleDeployer
 31  
 {
 32  
 
 33  0
     protected transient final Log logger = LogFactory.getLog(getClass());
 34  
     protected DeploymentService deploymentService;
 35  
 
 36  
 
 37  
     public DefaultMuleDeployer(DeploymentService deploymentService)
 38  0
     {
 39  0
         this.deploymentService = deploymentService;
 40  0
     }
 41  
 
 42  
     public void deploy(Application app)
 43  
     {
 44  0
         final ReentrantLock lock = deploymentService.getLock();
 45  
         try
 46  
         {
 47  0
             if (!lock.tryLock(0, TimeUnit.SECONDS))
 48  
             {
 49  
                 return;
 50  
             }
 51  0
             app.install();
 52  0
             app.init();
 53  0
             app.start();
 54  
         }
 55  0
         catch (InterruptedException e)
 56  
         {
 57  0
             Thread.currentThread().interrupt();
 58  
             return;
 59  
         }
 60  0
         catch (Throwable t)
 61  
         {
 62  0
             if (t instanceof DeploymentException)
 63  
             {
 64  
                 // re-throw as is
 65  0
                 throw ((DeploymentException) t);
 66  
             }
 67  
 
 68  0
             final String msg = String.format("Failed to deploy application [%s]", app.getAppName());
 69  0
             throw new DeploymentException(MessageFactory.createStaticMessage(msg), t);
 70  
         }
 71  
         finally
 72  
         {
 73  0
             if (lock.isHeldByCurrentThread())
 74  
             {
 75  0
                 lock.unlock();
 76  
             }
 77  
         }
 78  0
     }
 79  
 
 80  
     public void undeploy(Application app)
 81  
     {
 82  0
         final ReentrantLock lock = deploymentService.getLock();
 83  
         try
 84  
         {
 85  0
             if (!lock.tryLock(0, TimeUnit.SECONDS))
 86  
             {
 87  
                 return;
 88  
             }
 89  
 
 90  0
             app.stop();
 91  0
             app.dispose();
 92  0
             final File appDir = new File(MuleContainerBootstrapUtils.getMuleAppsDir(), app.getAppName());
 93  0
             FileUtils.deleteDirectory(appDir);
 94  
             // remove a marker, harmless, but a tidy app dir is always better :)
 95  0
             File marker = new File(MuleContainerBootstrapUtils.getMuleAppsDir(), String.format("%s-anchor.txt", app.getAppName()));
 96  0
             marker.delete();
 97  0
             Introspector.flushCaches();
 98  
         }
 99  0
         catch (InterruptedException e)
 100  
         {
 101  0
             Thread.currentThread().interrupt();
 102  
             return;
 103  
         }
 104  0
         catch (Throwable t)
 105  
         {
 106  
             // TODO logging
 107  0
             t.printStackTrace();
 108  
         }
 109  
         finally
 110  
         {
 111  0
             if (lock.isHeldByCurrentThread())
 112  
             {
 113  0
                 lock.unlock();
 114  
             }
 115  
         }
 116  0
     }
 117  
 
 118  
     public Application installFromAppDir(String packedMuleAppFileName) throws IOException
 119  
     {
 120  0
         final ReentrantLock lock = deploymentService.getLock();
 121  
         try
 122  
         {
 123  0
             if (!lock.tryLock(0, TimeUnit.SECONDS))
 124  
             {
 125  0
                 throw new IOException("Another deployment operation is in progress");
 126  
             }
 127  
 
 128  0
             final File appsDir = MuleContainerBootstrapUtils.getMuleAppsDir();
 129  0
             File appFile = new File(appsDir, packedMuleAppFileName);
 130  
             // basic security measure: outside apps dir use installFrom(url) and go through any
 131  
             // restrictions applied to it
 132  0
             if (!appFile.getParentFile().equals(appsDir))
 133  
             {
 134  0
                 throw new SecurityException("installFromAppDir() can only deploy from $MULE_HOME/apps. Use installFrom(url) instead.");
 135  
             }
 136  0
             return installFrom(appFile.toURL());
 137  
         }
 138  0
         catch (InterruptedException e)
 139  
         {
 140  0
             Thread.currentThread().interrupt();
 141  0
             throw new IOException("Install operation has been interrupted");
 142  
         }
 143  
         finally
 144  
         {
 145  0
             if (lock.isHeldByCurrentThread())
 146  
             {
 147  0
                 lock.unlock();
 148  
             }
 149  
         }
 150  
     }
 151  
 
 152  
     public Application installFrom(URL url) throws IOException
 153  
     {
 154  
         // TODO plug in app-bloodhound/validator here?
 155  0
         if (!url.toString().endsWith(".zip"))
 156  
         {
 157  0
             throw new IllegalArgumentException("Invalid Mule application archive: " + url);
 158  
         }
 159  
 
 160  0
         final String baseName = FilenameUtils.getBaseName(url.toString());
 161  0
         if (baseName.contains("%20"))
 162  
         {
 163  0
             throw new DeploymentInitException(
 164  
                     MessageFactory.createStaticMessage("Mule application name may not contain spaces: " + baseName));
 165  
         }
 166  
 
 167  0
         final ReentrantLock lock = deploymentService.getLock();
 168  
 
 169  
         String appName;
 170  0
         File appDir = null;
 171  0
         boolean errorEncountered = false;
 172  
         try
 173  
         {
 174  0
             if (!lock.tryLock(0, TimeUnit.SECONDS))
 175  
             {
 176  0
                 throw new IOException("Another deployment operation is in progress");
 177  
             }
 178  
 
 179  0
             final File appsDir = MuleContainerBootstrapUtils.getMuleAppsDir();
 180  
 
 181  0
             final String fullPath = url.toURI().toString();
 182  
 
 183  0
             if (logger.isInfoEnabled())
 184  
             {
 185  0
                 logger.info("Exploding a Mule application archive: " + fullPath);
 186  
             }
 187  
 
 188  0
             appName = FilenameUtils.getBaseName(fullPath);
 189  0
             appDir = new File(appsDir, appName);
 190  
             // normalize the full path + protocol to make unzip happy
 191  0
             final File source = new File(url.toURI());
 192  
             
 193  0
             FileUtils.unzip(source, appDir);
 194  0
             if ("file".equals(url.getProtocol()))
 195  
             {
 196  0
                 FileUtils.deleteQuietly(source);
 197  
             }
 198  
         }
 199  0
         catch (URISyntaxException e)
 200  
         {
 201  0
             errorEncountered = true;
 202  0
             final IOException ex = new IOException(e.getMessage());
 203  0
             ex.fillInStackTrace();
 204  0
             throw ex;
 205  
         }
 206  0
         catch (InterruptedException e)
 207  
         {
 208  0
             errorEncountered = true;
 209  0
             Thread.currentThread().interrupt();
 210  0
             throw new IOException("Install operation has been interrupted");
 211  
         }
 212  0
         catch (IOException e)
 213  
         {
 214  0
             errorEncountered = true;
 215  
             // re-throw
 216  0
             throw e;
 217  
         }
 218  0
         catch (Throwable t)
 219  
         {
 220  0
             errorEncountered = true;
 221  0
             final String msg = "Failed to install app from URL: " + url;
 222  0
             throw new DeploymentInitException(MessageFactory.createStaticMessage(msg), t);
 223  
         }
 224  
         finally {
 225  
             // delete an app dir, as it's broken
 226  0
             if (errorEncountered && appDir != null && appDir.exists())
 227  
             {
 228  0
                 final boolean couldNotDelete = FileUtils.deleteTree(appDir);
 229  
                 /*
 230  
                 if (couldNotDelete)
 231  
                 {
 232  
                     final String msg = String.format("Couldn't delete app directory '%s' after it failed to install", appDir);
 233  
                     logger.error(msg);
 234  
                 }
 235  
                 */
 236  
             }
 237  0
             if (lock.isHeldByCurrentThread())
 238  
             {
 239  0
                 lock.unlock();
 240  
             }
 241  
         }
 242  
 
 243  
         // appname is never null by now
 244  0
         return deploymentService.getAppFactory().createApp(appName);
 245  
     }
 246  
 }