KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > deployment > SingleFileHotDeployer


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.geronimo.deployment;
18
19 import java.io.File JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Arrays JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.LinkedList JavaDoc;
27 import java.util.jar.JarFile JavaDoc;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.geronimo.common.DeploymentException;
32 import org.apache.geronimo.deployment.util.DeploymentUtil;
33 import org.apache.geronimo.kernel.config.ConfigurationData;
34 import org.apache.geronimo.kernel.config.ConfigurationInfo;
35 import org.apache.geronimo.kernel.config.ConfigurationManager;
36 import org.apache.geronimo.kernel.config.ConfigurationStore;
37 import org.apache.geronimo.kernel.config.InvalidConfigException;
38 import org.apache.geronimo.kernel.config.NoSuchConfigException;
39 import org.apache.geronimo.kernel.repository.Artifact;
40 import org.apache.geronimo.kernel.repository.ArtifactResolver;
41 import org.apache.geronimo.kernel.repository.Version;
42 import org.apache.geronimo.system.serverinfo.ServerInfo;
43 import org.apache.geronimo.gbean.GBeanInfo;
44 import org.apache.geronimo.gbean.GBeanInfoBuilder;
45
46 /**
47  * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
48  */

49 public class SingleFileHotDeployer {
50     private static final Log log = LogFactory.getLog(SingleFileHotDeployer.class);
51     private static final String JavaDoc LINE_SEP = System.getProperty("line.separator");
52     private final File JavaDoc dir;
53     private final String JavaDoc[] watchPaths;
54     private final Collection JavaDoc builders;
55     private final ConfigurationStore store;
56     private final ConfigurationManager configurationManager;
57     private final boolean forceDeploy;
58     private final Artifact configurationId;
59     private boolean wasDeployed;
60
61     public SingleFileHotDeployer(String JavaDoc path, ServerInfo serverInfo, String JavaDoc[] watchPaths, Collection JavaDoc builders, ConfigurationStore store, ConfigurationManager configurationManager, boolean forceDeploy) throws DeploymentException {
62         this(serverInfo.resolve(path), watchPaths, builders, store, configurationManager, forceDeploy);
63     }
64
65     public SingleFileHotDeployer(File JavaDoc dir, String JavaDoc[] watchPaths, Collection JavaDoc builders, ConfigurationStore store, ConfigurationManager configurationManager, boolean forceDeploy) throws DeploymentException {
66         this.dir = dir;
67         this.watchPaths = watchPaths;
68         this.builders = builders;
69         this.store = store;
70         this.configurationManager = configurationManager;
71         this.forceDeploy = forceDeploy;
72
73         configurationId = start(dir);
74     }
75
76     private Artifact start(File JavaDoc dir) throws DeploymentException {
77         if (!dir.exists()) {
78             throw new IllegalArgumentException JavaDoc("Directory does not exist " + dir.getAbsolutePath());
79         }
80         if (!dir.isDirectory()) {
81             throw new IllegalArgumentException JavaDoc("Directory is not a directory " + dir.getAbsolutePath());
82         }
83
84         // take no action if there is nothing in the directory to deploy. Perhaps we should
85
// consider doing an undeploy in this case if the application is already deployed. Howevr
86
// for now this is to handle the case where the application is not already laid down at the
87
// time of the initial deploy of this gbean.
88
if (dir.list().length == 0) {
89             return null;
90         }
91
92         // get the existing inplace configuration if there is one
93
ConfigurationInfo existingConfiguration = null;
94         List JavaDoc list = configurationManager.listConfigurations();
95         for (Iterator JavaDoc iterator = list.iterator(); iterator.hasNext();) {
96             ConfigurationInfo configurationInfo = (ConfigurationInfo) iterator.next();
97             if (dir.equals(configurationInfo.getInPlaceLocation())) {
98                 existingConfiguration = configurationInfo;
99             }
100         }
101         Artifact existingConfigurationId = (existingConfiguration == null) ? null : existingConfiguration.getConfigID();
102
103         if (!forceDeploy && existingConfiguration != null && !isModifiedSince(existingConfiguration.getCreated())) {
104             try {
105                 configurationManager.loadConfiguration(existingConfigurationId);
106                 configurationManager.startConfiguration(existingConfigurationId);
107             } catch (Exception JavaDoc e) {
108                 throw new DeploymentException("Unable to load and start " + dir, e);
109             }
110             return existingConfigurationId;
111         }
112
113         // if the current id and the new id only differ by version, we can reload, otherwise we need to load and start
114
if (existingConfigurationId != null && configurationManager.isLoaded(existingConfigurationId)) {
115             try {
116                 configurationManager.unloadConfiguration(existingConfigurationId);
117             } catch (NoSuchConfigException e) {
118                 throw new DeploymentException("Unable to unload existing configuration " + existingConfigurationId);
119             }
120         }
121
122         ModuleIDBuilder idBuilder = new ModuleIDBuilder();
123
124         JarFile JavaDoc module = null;
125         try {
126             module = DeploymentUtil.createJarFile(dir);
127         } catch (IOException JavaDoc e) {
128             throw new DeploymentException("Cound not open module file: " + dir.getAbsolutePath(), e);
129         }
130
131         try {
132             // get the builder and plan
133
Object JavaDoc plan = null;
134             ConfigurationBuilder builder = null;
135             for (Iterator JavaDoc i = builders.iterator(); i.hasNext();) {
136                 ConfigurationBuilder candidate = (ConfigurationBuilder) i.next();
137                 plan = candidate.getDeploymentPlan(null, module, idBuilder);
138                 if (plan != null) {
139                     builder = candidate;
140                     break;
141                 }
142             }
143             if (builder == null) {
144                 throw new DeploymentException("Cannot deploy the requested application module because no builder is able to handle it (dir=" + dir.getAbsolutePath() + ")");
145             }
146
147             // determine the new configuration id
148
Artifact configurationId = builder.getConfigurationID(plan, module, idBuilder);
149
150             // if the new configuration id isn't fully resolved, populate it with defaults
151
if (!configurationId.isResolved()) {
152                 configurationId = resolve(configurationId);
153             }
154
155             // If we didn't find a previous configuration based upon the path then check one more time to
156
// see if one exists by the same configurationID. This will catch situations where the target
157
// path was renamed or moved such that the path associated with the previous configuration no longer
158
// matches the patch associated with the new configuration.
159
if ((existingConfigurationId == null) && configurationManager.isInstalled(configurationId)) {
160                 log.info("Existing Module found by moduleId");
161                 existingConfigurationId = configurationId;
162             }
163
164             // if we are deploying over the exisitng version we need to uninstall first
165
if(configurationId.equals(existingConfigurationId)) {
166                 log.info("Undeploying " + existingConfigurationId);
167                 configurationManager.uninstallConfiguration(existingConfigurationId);
168             }
169
170             // deploy it
171
deployConfiguration(builder, store, configurationId, plan, module, Arrays.asList(configurationManager.getStores()), configurationManager.getArtifactResolver());
172             wasDeployed = true;
173
174             configurationManager.loadConfiguration(configurationId);
175             configurationManager.startConfiguration(configurationId);
176
177             log.info("Successfully deployed and started " + configurationId + " in location " + dir);
178
179             return configurationId;
180         } catch (Exception JavaDoc e) {
181             throw new DeploymentException("Unable to deploy " + dir, e);
182         } finally {
183             DeploymentUtil.close(module);
184         }
185
186     }
187
188     private boolean isModifiedSince(long created) {
189         for (int i = 0; i < watchPaths.length; i++) {
190             String JavaDoc path = watchPaths[i];
191             File JavaDoc file = new File JavaDoc(dir, path);
192             if (!file.exists()) {
193                 log.warn("Watched file does not exist " + file);
194             }
195             if (file.isFile() && file.lastModified() > created) {
196                 log.info("Redeploying " + dir + " because file " + file + " was modified;");
197                 return true;
198             }
199         }
200         return false;
201     }
202
203     private Artifact resolve(Artifact configID) throws DeploymentException {
204         String JavaDoc group = configID.getGroupId();
205         if (group == null) {
206             group = Artifact.DEFAULT_GROUP_ID;
207         }
208         String JavaDoc artifactId = configID.getArtifactId();
209         if (artifactId == null) {
210             throw new DeploymentException("Every configuration to deploy must have a ConfigID with an ArtifactID (not " + configID + ")");
211         }
212         Version version = configID.getVersion();
213         if (version == null) {
214             version = new Version(Long.toString(System.currentTimeMillis()));
215         }
216         String JavaDoc type = configID.getType();
217         if (type == null) {
218             type = "car";
219         }
220         return new Artifact(group, artifactId, version, type);
221     }
222
223     private List JavaDoc deployConfiguration(ConfigurationBuilder builder, ConfigurationStore store, Artifact configurationId, Object JavaDoc plan, JarFile JavaDoc module, Collection JavaDoc stores, ArtifactResolver artifactResolver) throws DeploymentException {
224         try {
225             // It's our responsibility to close this context, once we're done with it...
226
DeploymentContext context = builder.buildConfiguration(true, configurationId, plan, module, stores, artifactResolver, store);
227
228             List JavaDoc configurations = new ArrayList JavaDoc();
229             try {
230                 configurations.add(context.getConfigurationData());
231                 configurations.addAll(context.getAdditionalDeployment());
232
233                 if (configurations.isEmpty()) {
234                     throw new DeploymentException("Deployer did not create any configurations");
235                 }
236                 List JavaDoc deployedURIs = new ArrayList JavaDoc();
237                 for (Iterator JavaDoc iterator = configurations.iterator(); iterator.hasNext();) {
238                     ConfigurationData configurationData = (ConfigurationData) iterator.next();
239                     configurationData.setAutoStart(false);
240                     store.install(configurationData);
241                     deployedURIs.add(configurationData.getId().toString());
242                 }
243                 return deployedURIs;
244             } catch (IOException JavaDoc e) {
245                 cleanupConfigurations(configurations);
246                 throw e;
247             } catch (InvalidConfigException e) {
248                 cleanupConfigurations(configurations);
249                 // unlikely as we just built this
250
throw new DeploymentException(e);
251             } finally {
252                 if (context != null) {
253                     context.close();
254                 }
255             }
256         } catch (Throwable JavaDoc e) {
257             if (e instanceof Error JavaDoc) {
258                 log.error("Deployment failed due to ", e);
259                 throw (Error JavaDoc) e;
260             } else if (e instanceof DeploymentException) {
261                 throw (DeploymentException) e;
262             } else if (e instanceof Exception JavaDoc) {
263                 log.error("Deployment failed due to ", e);
264                 throw new DeploymentException(e);
265             }
266             throw new Error JavaDoc(e);
267         } finally {
268             DeploymentUtil.close(module);
269         }
270     }
271
272     private void cleanupConfigurations(List JavaDoc configurations) {
273         LinkedList JavaDoc cannotBeDeletedList = new LinkedList JavaDoc();
274         for (Iterator JavaDoc iterator = configurations.iterator(); iterator.hasNext();) {
275             ConfigurationData configurationData = (ConfigurationData) iterator.next();
276             File JavaDoc dir = configurationData.getConfigurationDir();
277             cannotBeDeletedList.clear();
278             if (!DeploymentUtil.recursiveDelete(dir,cannotBeDeletedList)) {
279                 // Output a message to help user track down file problem
280
log.warn("Unable to delete " + cannotBeDeletedList.size() +
281                         " files while recursively deleting directory "
282                         + dir + LINE_SEP +
283                         "The first file that could not be deleted was:" + LINE_SEP + " "+
284                         ( !cannotBeDeletedList.isEmpty() ? cannotBeDeletedList.getFirst() : "") );
285             }
286         }
287     }
288
289     public File JavaDoc getDir() {
290         return dir;
291     }
292
293     public Artifact getConfigurationId() {
294         return configurationId;
295     }
296
297     public boolean isForceDeploy() {
298         return forceDeploy;
299     }
300
301     public boolean wasDeployed() {
302         return wasDeployed;
303     }
304
305     public static final GBeanInfo GBEAN_INFO;
306
307     static {
308         GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(SingleFileHotDeployer.class);
309
310         infoFactory.addAttribute("path", String JavaDoc.class, true);
311         infoFactory.addReference("ServerInfo", ServerInfo.class);
312         infoFactory.addAttribute("watchPaths", String JavaDoc[].class, true);
313         infoFactory.addReference("Builders", ConfigurationBuilder.class);
314         infoFactory.addReference("Store", ConfigurationStore.class);
315         infoFactory.addReference("ConfigurationManager", ConfigurationManager.class);
316         infoFactory.addAttribute("forceDeploy", boolean.class, true);
317
318         infoFactory.setConstructor(new String JavaDoc[]{"path", "ServerInfo", "watchPaths", "Builders", "Store", "ConfigurationManager", "forceDeploy"});
319
320         GBEAN_INFO = infoFactory.getBeanInfo();
321     }
322
323     public static GBeanInfo getGBeanInfo() {
324         return GBEAN_INFO;
325     }
326 }
327
Popular Tags