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