KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > ve > luz > ica > jackass > daemon > NodeDeployerImpl


1 /*
2  * Copyright (c) 2003 by The Jackass Team
3  * Licensed under the Open Software License version 2.0
4  */

5 package ve.luz.ica.jackass.daemon;
6
7 import java.io.File JavaDoc;
8 import java.io.InputStream JavaDoc;
9 import java.io.InputStreamReader JavaDoc;
10 import java.io.Reader JavaDoc;
11 import java.net.MalformedURLException JavaDoc;
12 import java.net.URL JavaDoc;
13 import java.net.URLClassLoader JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Properties JavaDoc;
18 import java.util.zip.ZipFile JavaDoc;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.omg.CosNaming.NamingContextExt JavaDoc;
23 import org.omg.PortableServer.POA JavaDoc;
24
25 import ve.luz.ica.jackass.component.ApplicationContext;
26 import ve.luz.ica.jackass.component.ApplicationContextHelper;
27 import ve.luz.ica.jackass.component.ApplicationContextImpl;
28 import ve.luz.ica.jackass.component.ApplicationContextPOATie;
29 import ve.luz.ica.jackass.component.DeploymentRequirement;
30 import ve.luz.ica.jackass.deploy.UnableToDeployException;
31 import ve.luz.ica.jackass.deploy.UnableToUndeployException;
32 import ve.luz.ica.jackass.deploy.daemon.NodeDeployerPOA;
33 import ve.luz.ica.jackass.deploy.daemon.ProxyInfo;
34 import ve.luz.ica.jackass.deploy.descriptor.ica.IcaJackassApplication;
35 import ve.luz.ica.jackass.deploy.descriptor.standard.JackassApplication;
36 import ve.luz.ica.jackass.deploy.descriptor.standard.Property;
37 import ve.luz.ica.jackass.deploy.util.Application;
38 import ve.luz.ica.jackass.deploy.util.Component;
39 import ve.luz.ica.jackass.instantiator.JInstantiator;
40 import ve.luz.ica.jackass.instantiator.StatelessPoolData;
41 import ve.luz.ica.jackass.util.ConfigurationManager;
42 import ve.luz.ica.remoteio.FileUtil;
43 import ve.luz.ica.remoteio.RemoteFile;
44 import ve.luz.ica.util.ZipUtil;
45
46 /**
47  * A NodeDeployerImpl deploys applications locally. This class is the
48  * implementation of Corba interface NodeDeployer
49  * @author Carlos Arévalo
50  */

51 public class NodeDeployerImpl extends NodeDeployerPOA
52 {
53     private static final Log LOG = LogFactory.getLog(NodeDeployerImpl.class);
54
55     private static final String JavaDoc ZIP_EXTENSION = ".zip";
56     private static final String JavaDoc POOL_MAX_IDLE = "500";
57     private static final String JavaDoc POOL_MAX_ACTIVE = "100";
58     private static final String JavaDoc POOL_CHECK_INTERVAL = "100";
59     private static final String JavaDoc POOL_MAX_IDLE_PROPERTY = "pool.maxactive";
60     private static final String JavaDoc POOL_MAX_ACTIVE_PROPERTY = "pool.maxidle";
61     private static final String JavaDoc POOL_CHECK_INTERVAL_PROPERTY = "pool.checkinterval";
62
63     private static final String JavaDoc JAR_FILE_PREFIX = "jackass-";
64     private static final String JavaDoc JAR_EXTENSION = ".jar";
65
66     private String JavaDoc deploymentPath = null;
67     private int instantiatorCounter = 0;
68     private int totalInstantiators = 0;
69     private POA JavaDoc contextPoa = null;
70     private NamingContextExt JavaDoc rootNamingContext = null;
71     private ComponentDeployer componentDeployer = null;
72     private ArrayList JavaDoc instantiatorList = null;
73
74     /**
75      * Class constructor
76      * @param numInstantiators the number of instantiatores defined in the
77      * configuration file
78      * @param ctxPoa the poa used to create context object references
79      * @param prxPoa the poa used to create proxy references
80      * @param rootNamingCtx the root name context
81      */

82     public NodeDeployerImpl(int numInstantiators, POA JavaDoc ctxPoa, POA JavaDoc prxPoa, NamingContextExt JavaDoc rootNamingCtx)
83     {
84         Properties JavaDoc cf = ConfigurationManager.getConfigFile();
85         this.deploymentPath = cf.getProperty(ConfigurationManager.DEPLOYMENT_PATH_PROPERTY);
86
87         this.contextPoa = ctxPoa;
88         this.rootNamingContext = rootNamingCtx;
89
90         this.instantiatorList = new ArrayList JavaDoc();
91         this.totalInstantiators = numInstantiators;
92
93         // create default stateless pool data
94
int poolMaxIdle = Integer.parseInt(cf.getProperty(POOL_MAX_IDLE_PROPERTY, POOL_MAX_IDLE));
95         int poolMaxActive = Integer.parseInt(cf.getProperty(POOL_MAX_ACTIVE_PROPERTY, POOL_MAX_ACTIVE));
96         int poolCheckInterval = Integer.parseInt(cf.getProperty(POOL_CHECK_INTERVAL_PROPERTY, POOL_CHECK_INTERVAL));
97         StatelessPoolData statelessPoolData = new StatelessPoolData(poolMaxActive, poolMaxIdle, poolCheckInterval);
98
99         componentDeployer = new ComponentDeployer(ctxPoa, prxPoa, statelessPoolData);
100     }
101
102     /**
103      * Returns the deployment path
104      * @return the deployment path
105      */

106     public String JavaDoc getDeploymentPath()
107     {
108         return this.deploymentPath;
109     }
110
111     /**
112      * Deploy an application. This method is invoked via Corba. It expands the
113      * application zip file and calls deployApplication. This method returs an
114      * array of ProxyInfo objects, one for each deployed component. A ProxyInfo
115      * is a simple structure containing the name of the component and the proxy
116      * reference.
117      * @param applicationName a string containing the application name.
118      * @param remoteFile the application zip file
119      * @return an array of ProxyInfo objects.
120      * @throws UnableToDeployException thrown if for any reason the deployer
121      * cannot deploy the application
122      */

123     public ProxyInfo[] deploy(String JavaDoc applicationName, RemoteFile remoteFile) throws UnableToDeployException
124     {
125         try
126         {
127             if (LOG.isInfoEnabled()) LOG.info("Deploying application " + applicationName);
128
129             String JavaDoc zipFileName = applicationName + ZIP_EXTENSION;
130             String JavaDoc zipPath = FileUtil.getRemoteFile(remoteFile, deploymentPath, zipFileName);
131
132             InputStream JavaDoc stantardIs = ZipUtil.getInputStream(zipPath, Application.STANDARD_DESCRIPTOR_NAME);
133             InputStream JavaDoc icaIs = ZipUtil.getInputStream(zipPath, Application.ICA_DESCRIPTOR_NAME);
134
135             Reader JavaDoc standardReader = new InputStreamReader JavaDoc(stantardIs);
136             Reader JavaDoc icaReader = new InputStreamReader JavaDoc(icaIs);
137             JackassApplication jackApp = JackassApplication.unmarshal(standardReader);
138             IcaJackassApplication icaApp = IcaJackassApplication.unmarshal(icaReader);
139             Application app = new Application(jackApp, icaApp);
140
141             File JavaDoc deploymentDir = new File JavaDoc(deploymentPath, app.getName());
142             deploymentDir.mkdir();
143
144             ZipFile JavaDoc zipFile = new ZipFile JavaDoc(zipPath);
145             String JavaDoc depPath = ZipUtil.extractFiles(zipFile, deploymentDir, null);
146
147             if (LOG.isDebugEnabled()) LOG.debug("Extracted archive " + remoteFile.getName());
148
149             ProxyInfo[] proxyInfoList = this.deployApplication(depPath, app);
150
151             if (LOG.isInfoEnabled()) LOG.info("Application " + applicationName + " deployed");
152
153             return proxyInfoList;
154         }
155         catch (Exception JavaDoc e)
156         {
157             if (LOG.isErrorEnabled()) LOG.error("Unexpected error deploying", e);
158             throw new UnableToDeployException(e.getMessage());
159         }
160     }
161
162     /**
163      * Deploy an application.
164      * @param deploymentPath the path where the application will be deployed
165      * @param app the Application object containg the application's
166      * descriptor data.
167      * @return an array of ProxyInfo objects.
168      * @throws Exception thrown if there an error during deployment
169      */

170     private ProxyInfo[] deployApplication(String JavaDoc deploymentPath, Application app) throws Exception JavaDoc
171     {
172         // load invocation jar file
173
// this should be removed when using dynamic invocation
174
URLClassLoader JavaDoc proxyClassLoader = this.createClassLoader(deploymentPath, app);
175
176         // create the application context
177
if (LOG.isDebugEnabled()) LOG.debug("Creating the application context");
178
179         Property[] properties = null;
180         ve.luz.ica.jackass.deploy.descriptor.standard.Properties propertyList = app.getProperties();
181         if (propertyList != null)
182         {
183             properties = propertyList.getProperty();
184         }
185
186         ApplicationContextImpl contextImpl = new ApplicationContextImpl(rootNamingContext, properties);
187         ApplicationContextPOATie contextServant = new ApplicationContextPOATie(contextImpl);
188         byte[] contextID = app.getName().getBytes();
189         org.omg.CORBA.Object JavaDoc obj = contextPoa.create_reference_with_id(contextID, ApplicationContextHelper.id());
190         contextPoa.activate_object_with_id(contextID, contextServant);
191         ApplicationContext appContext = ApplicationContextHelper.narrow(obj);
192         if (LOG.isDebugEnabled()) LOG.debug("Application context created");
193
194         // create an array of ProxyInfo objects (ProxyInfo objects map the
195
// component name to the proxy reference).
196
// This list will be used by the external deployer to create the component reference
197
ProxyInfo[] proxyInfoList = new ProxyInfo[app.getComponentCount()];
198         List JavaDoc initializedInstantiators = new ArrayList JavaDoc();
199         Iterator JavaDoc components = app.getComponents();
200         int n = 0;
201         while (components.hasNext())
202         {
203             Component comp = (Component) components.next();
204
205             JInstantiator instantiator = this.findInstantiator(comp);
206             if (instantiator != null)
207             {
208                 if (!initializedInstantiators.contains(instantiator))
209                 {
210                     instantiator.registerApplication(app.getName(), deploymentPath);
211                     initializedInstantiators.add(instantiator);
212                 }
213
214                 if (LOG.isDebugEnabled()) LOG.debug("Creating component " + comp.getName());
215                 ProxyInfo proxyInfo = componentDeployer.deployComponent(instantiator, app, comp,
216                         appContext, proxyClassLoader);
217                 proxyInfoList[n++] = proxyInfo;
218             }
219             else
220             {
221                 if (LOG.isErrorEnabled()) LOG.error("No instantiator found for component " + comp.getName());
222                 throw new Exception JavaDoc("No instantiator found for component " + comp.getName());
223             }
224         }
225         return proxyInfoList;
226     }
227
228     /**
229      * Creates the class loader used to load the component's proxy class
230      * @param deploymentPath path where the applications are deployed
231      * @param app the object containing the application deployement data
232      * @return the created class loader.
233      * @throws MalformedURLException if there is an error during class loader creation
234      */

235     private URLClassLoader JavaDoc createClassLoader(String JavaDoc deploymentPath, Application app)
236             throws MalformedURLException JavaDoc
237     {
238         File JavaDoc file = new File JavaDoc(deploymentPath, JAR_FILE_PREFIX + app.getName() + JAR_EXTENSION);
239
240         if (LOG.isDebugEnabled())
241             LOG.info("loading " + file.getPath());
242
243         URL JavaDoc[] urls = {file.toURL()};
244         URLClassLoader JavaDoc loader = new URLClassLoader JavaDoc(urls);
245         return loader;
246     }
247
248     /**
249      * Finds an intantiator that meets the deployment requirements of a component
250      * @param comp the component for which an instantiator is to be found
251      * @return an instantiator that meets the component's requirements
252      */

253     private JInstantiator findInstantiator(Component comp)
254     {
255         ve.luz.ica.jackass.deploy.descriptor.ica.Requirement[] compReq =
256             comp.getDeploymentRequirements().getRequirement();
257         Iterator JavaDoc instantiators = instantiatorList.iterator();
258         while (instantiators.hasNext())
259         {
260             JInstantiator instantiator = (JInstantiator) instantiators.next();
261             DeploymentRequirement[] instantiatorReq = instantiator.getDeployementRequirements();
262             if (this.meetsRequirements(compReq, instantiatorReq))
263             {
264                 return instantiator;
265             }
266         }
267         return null;
268     }
269
270     /**
271      * Checks whether the component's requerimets are met by the instantiator
272      * @param componentReq an array of component requirements
273      * @param instantiatorReq an array of instantiator requirements
274      * @return true if the instantiator meets the componet's requirements.
275      * False otherwise.
276      */

277     private boolean meetsRequirements(
278         ve.luz.ica.jackass.deploy.descriptor.ica.Requirement[] componentReq,
279         DeploymentRequirement[] instantiatorReq)
280     {
281         for (int n = 0; n < componentReq.length; ++n)
282         {
283             if (!componentReq[n].getValue().equals(instantiatorReq[n].value) ||
284                 !componentReq[n].getVersion().equals(instantiatorReq[n].version))
285             {
286                 return false;
287             }
288         }
289         return true;
290     }
291
292     /**
293      * Add an instantiator to the list of available instantiators
294      * @param instantiator the instantiator reference
295      */

296     public void addInstantiator(JInstantiator instantiator)
297     {
298         if (LOG.isDebugEnabled()) LOG.debug("Registering insntantiator number " + instantiatorCounter);
299         if (instantiatorList.contains(instantiator))
300         {
301             // Error ya está registrado
302
return;
303         }
304         instantiatorList.add(instantiator);
305         instantiatorCounter++;
306         if (instantiatorCounter >= totalInstantiators)
307         {
308             synchronized (this)
309             {
310                 notify();
311             }
312         }
313     }
314
315     /**
316      * Undeploys an application
317      * @param applicationName the name of the application to be undeployed
318      * @throws UnableToUndeployException thrown if there is an error during undeployment.
319      */

320     public void undeploy(String JavaDoc applicationName) throws UnableToUndeployException
321     {
322         try
323         {
324             LOG.info("Undeploying application " + applicationName);
325
326             boolean error = false;
327
328             File JavaDoc zipFile = new File JavaDoc(deploymentPath, applicationName + ZIP_EXTENSION);
329             String JavaDoc zipPath = zipFile.getPath();
330
331             InputStream JavaDoc stantardIs = ZipUtil.getInputStream(zipPath, Application.STANDARD_DESCRIPTOR_NAME);
332             InputStream JavaDoc icaIs = ZipUtil.getInputStream(zipPath, Application.ICA_DESCRIPTOR_NAME);
333
334             Reader JavaDoc standardReader = new InputStreamReader JavaDoc(stantardIs);
335             Reader JavaDoc icaReader = new InputStreamReader JavaDoc(icaIs);
336             JackassApplication jackApp = JackassApplication.unmarshal(standardReader);
337             IcaJackassApplication icaApp = IcaJackassApplication.unmarshal(icaReader);
338             Application app = new Application(jackApp, icaApp);
339
340             // destroy the application context
341
try
342             {
343                 contextPoa.deactivate_object(app.getName().getBytes());
344             }
345             catch (Exception JavaDoc e)
346             {
347                 LOG.warn("The contextPoa has reported this exception " + e.getMessage());
348                 if (LOG.isDebugEnabled()) LOG.debug("Stack trace follows", e);
349             }
350
351             Iterator JavaDoc components = app.getComponents();
352             while (components.hasNext())
353             {
354                 try
355                 {
356                     Component comp = (Component) components.next();
357                     componentDeployer.undeployComponent(app, comp);
358                 }
359                 catch (Exception JavaDoc e)
360                 {
361                     error = true;
362                     LOG.warn(e.getMessage());
363                     if (LOG.isDebugEnabled()) LOG.debug(e);
364                 }
365             }
366
367             // tell the instantiators to remove the application
368
Iterator JavaDoc instantiators = instantiatorList.iterator();
369             while (instantiators.hasNext())
370             {
371                 JInstantiator instantiator = (JInstantiator) instantiators.next();
372                 try
373                 {
374                     instantiator.unregisterApplication(applicationName);
375                 }
376                 catch (Exception JavaDoc e)
377                 {
378                     error = true;
379                     LOG.warn("Error removing the application from the instantiator " + e.getMessage());
380                     if (LOG.isDebugEnabled()) LOG.debug("Stack trace follows", e);
381                 }
382             }
383
384             if (error)
385             {
386                 throw new Exception JavaDoc("Some warnings were issued during undeployment. You should check the log files");
387             }
388         }
389         catch (Exception JavaDoc e)
390         {
391             LOG.warn("Error undeploying application " + e.getMessage());
392             if (LOG.isDebugEnabled()) LOG.error("Stack trace follows", e);
393             throw new UnableToUndeployException(e.getMessage());
394         }
395         finally
396         {
397             File JavaDoc applicationDirectory = new File JavaDoc(deploymentPath, applicationName);
398             File JavaDoc zipFile = new File JavaDoc(deploymentPath, applicationName + ZIP_EXTENSION);
399             if (LOG.isDebugEnabled()) LOG.debug("Deleting application directory " + applicationDirectory);
400             this.deleteFile(applicationDirectory);
401             this.deleteFile(zipFile);
402
403             if (LOG.isInfoEnabled()) LOG.info("Application " + applicationName + " undeployed");
404         }
405     }
406
407     /**
408      * Recursively delete a directory and all the files it contains.
409      * @param file the file representing the directory to be deleted.
410      */

411     private void deleteFile(File JavaDoc file)
412     {
413         if (file.isDirectory())
414         {
415             File JavaDoc[] fileList = file.listFiles();
416             for (int i = 0; i<fileList.length; ++i)
417             {
418                 deleteFile(fileList[i]);
419             }
420         }
421         file.delete();
422     }
423
424 }
425
Popular Tags