1
2
3
4
5
6
7
8
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 protected transient final Log logger = LogFactory.getLog(getClass());
34 protected DeploymentService deploymentService;
35
36 public DefaultMuleDeployer(DeploymentService deploymentService)
37 {
38 this.deploymentService = deploymentService;
39 }
40
41 public void deploy(Application app)
42 {
43 final ReentrantLock lock = deploymentService.getLock();
44 try
45 {
46 if (!lock.tryLock(0, TimeUnit.SECONDS))
47 {
48 return;
49 }
50 app.install();
51 app.init();
52 app.start();
53 }
54 catch (InterruptedException e)
55 {
56 Thread.currentThread().interrupt();
57 return;
58 }
59 catch (Throwable t)
60 {
61 if (t instanceof DeploymentException)
62 {
63
64 throw ((DeploymentException) t);
65 }
66
67 final String msg = String.format("Failed to deploy application [%s]", app.getAppName());
68 throw new DeploymentException(MessageFactory.createStaticMessage(msg), t);
69 }
70 finally
71 {
72 if (lock.isHeldByCurrentThread())
73 {
74 lock.unlock();
75 }
76 }
77 }
78
79 public void undeploy(Application app)
80 {
81 final ReentrantLock lock = deploymentService.getLock();
82 try
83 {
84 if (!lock.tryLock(0, TimeUnit.SECONDS))
85 {
86 return;
87 }
88
89 app.stop();
90 app.dispose();
91 final File appDir = new File(MuleContainerBootstrapUtils.getMuleAppsDir(), app.getAppName());
92 FileUtils.deleteDirectory(appDir);
93
94 File marker = new File(MuleContainerBootstrapUtils.getMuleAppsDir(), String.format("%s-anchor.txt", app.getAppName()));
95 marker.delete();
96 Introspector.flushCaches();
97 }
98 catch (InterruptedException e)
99 {
100 Thread.currentThread().interrupt();
101 return;
102 }
103 catch (Throwable t)
104 {
105 if (t instanceof DeploymentException)
106 {
107
108 throw ((DeploymentException) t);
109 }
110
111 final String msg = String.format("Failed to undeploy application [%s]", app.getAppName());
112 throw new DeploymentException(MessageFactory.createStaticMessage(msg), t);
113 }
114 finally
115 {
116 if (lock.isHeldByCurrentThread())
117 {
118 lock.unlock();
119 }
120 }
121 }
122
123 public Application installFromAppDir(String packedMuleAppFileName) throws IOException
124 {
125 final ReentrantLock lock = deploymentService.getLock();
126 try
127 {
128 if (!lock.tryLock(0, TimeUnit.SECONDS))
129 {
130 throw new IOException("Another deployment operation is in progress");
131 }
132
133 final File appsDir = MuleContainerBootstrapUtils.getMuleAppsDir();
134 File appFile = new File(appsDir, packedMuleAppFileName);
135
136
137 if (!appFile.getParentFile().equals(appsDir))
138 {
139 throw new SecurityException("installFromAppDir() can only deploy from $MULE_HOME/apps. Use installFrom(url) instead.");
140 }
141 return installFrom(appFile.toURL());
142 }
143 catch (InterruptedException e)
144 {
145 Thread.currentThread().interrupt();
146 throw new IOException("Install operation has been interrupted");
147 }
148 finally
149 {
150 if (lock.isHeldByCurrentThread())
151 {
152 lock.unlock();
153 }
154 }
155 }
156
157 public Application installFrom(URL url) throws IOException
158 {
159
160 if (!url.toString().endsWith(".zip"))
161 {
162 throw new IllegalArgumentException("Invalid Mule application archive: " + url);
163 }
164
165 final String baseName = FilenameUtils.getBaseName(url.toString());
166 if (baseName.contains("%20"))
167 {
168 throw new DeploymentInitException(
169 MessageFactory.createStaticMessage("Mule application name may not contain spaces: " + baseName));
170 }
171
172 final ReentrantLock lock = deploymentService.getLock();
173
174 String appName;
175 File appDir = null;
176 boolean errorEncountered = false;
177 try
178 {
179 if (!lock.tryLock(0, TimeUnit.SECONDS))
180 {
181 throw new IOException("Another deployment operation is in progress");
182 }
183
184 final File appsDir = MuleContainerBootstrapUtils.getMuleAppsDir();
185
186 final String fullPath = url.toURI().toString();
187
188 if (logger.isInfoEnabled())
189 {
190 logger.info("Exploding a Mule application archive: " + fullPath);
191 }
192
193 appName = FilenameUtils.getBaseName(fullPath);
194 appDir = new File(appsDir, appName);
195
196 final File source = new File(url.toURI());
197
198 FileUtils.unzip(source, appDir);
199 if ("file".equals(url.getProtocol()))
200 {
201 FileUtils.deleteQuietly(source);
202 }
203 }
204 catch (URISyntaxException e)
205 {
206 errorEncountered = true;
207 final IOException ex = new IOException(e.getMessage());
208 ex.fillInStackTrace();
209 throw ex;
210 }
211 catch (InterruptedException e)
212 {
213 errorEncountered = true;
214 Thread.currentThread().interrupt();
215 throw new IOException("Install operation has been interrupted");
216 }
217 catch (IOException e)
218 {
219 errorEncountered = true;
220
221 throw e;
222 }
223 catch (Throwable t)
224 {
225 errorEncountered = true;
226 final String msg = "Failed to install app from URL: " + url;
227 throw new DeploymentInitException(MessageFactory.createStaticMessage(msg), t);
228 }
229 finally {
230
231 if (errorEncountered && appDir != null && appDir.exists())
232 {
233 final boolean couldNotDelete = FileUtils.deleteTree(appDir);
234
235
236
237
238
239
240
241 }
242 if (lock.isHeldByCurrentThread())
243 {
244 lock.unlock();
245 }
246 }
247
248
249 return deploymentService.getAppFactory().createApp(appName);
250 }
251 }