001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *  http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    
020    package org.apache.geronimo.mavenplugins.geronimo.module;
021    
022    import java.io.IOException;
023    import java.util.List;
024    import java.util.ArrayList;
025    
026    import javax.enterprise.deploy.spi.DeploymentManager;
027    import javax.enterprise.deploy.spi.Target;
028    import javax.enterprise.deploy.spi.TargetModuleID;
029    import javax.enterprise.deploy.spi.status.ProgressObject;
030    import javax.enterprise.deploy.spi.status.ProgressListener;
031    import javax.enterprise.deploy.spi.status.ProgressEvent;
032    import javax.enterprise.deploy.spi.status.DeploymentStatus;
033    import javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException;
034    import javax.enterprise.deploy.shared.factories.DeploymentFactoryManager;
035    
036    import org.apache.geronimo.deployment.plugin.factories.DeploymentFactoryImpl;
037    import org.apache.geronimo.mavenplugins.geronimo.ModuleConfig;
038    import org.apache.geronimo.mavenplugins.geronimo.reporting.ReportingMojoSupport;
039    
040    import org.apache.geronimo.genesis.ArtifactItem;
041    
042    import org.apache.maven.plugin.MojoExecutionException;
043    
044    /**
045     * Support for mojos that operate on modules.
046     *
047     * @version $Rev: 450613 $ $Date: 2006-09-27 15:45:46 -0700 (Wed, 27 Sep 2006) $
048     */
049    public abstract class ModuleMojoSupport
050        extends ReportingMojoSupport
051    {
052        private static final String URI_PREFIX = "deployer:geronimo:jmx";
053    
054        /**
055         * List of module artifact configurations.  Artifacts need to point to jar | war | ear | rar archive.
056         *
057         * @parameter
058         */
059        protected ModuleConfig[] modules = null;
060    
061        /**
062         * Cached deployment manager.
063         */
064        private DeploymentManager deploymentManager;
065    
066        /**
067         * Get a deployment manager; if the manager was previosuly initialized then that cached instance is used.
068         *
069         * @return  Deployment manager instance; never null
070         *
071         * @throws IOException
072         * @throws DeploymentManagerCreationException
073         */
074        protected DeploymentManager getDeploymentManager() throws IOException, DeploymentManagerCreationException {
075            if (deploymentManager == null) {
076                // Register the Geronimo factory
077                DeploymentFactoryManager manager = DeploymentFactoryManager.getInstance();
078                manager.registerDeploymentFactory(new DeploymentFactoryImpl());
079    
080                String uri = URI_PREFIX + "://" + hostname + ":" + port;
081    
082                DeploymentFactoryManager factoryManager = DeploymentFactoryManager.getInstance();
083                deploymentManager = factoryManager.getDeploymentManager(uri, username, password);
084            }
085    
086            return deploymentManager;
087        }
088    
089        /**
090         * Waits for the given progress to stop running.
091         *
092         * @param progress  The progress object to wait for.
093         * @return          The status of the deployment; never null
094         *
095         * @throws InterruptedException
096         */
097        protected DeploymentStatus waitFor(final ProgressObject progress) throws InterruptedException {
098            assert progress != null;
099    
100            //
101            // TODO: Add timeout?
102            //
103            
104            ProgressListener listener = new ProgressListener()
105            {
106                public void handleProgressEvent(final ProgressEvent event) {
107                    DeploymentStatus status = event.getDeploymentStatus();
108    
109                    if (!status.isRunning()) {
110                        synchronized (progress) {
111                            progress.notify();
112                        }
113                    }
114                }
115            };
116    
117            progress.addProgressListener(listener);
118    
119            synchronized (progress) {
120                while (progress.getDeploymentStatus().isRunning()) {
121                    progress.wait();
122                }
123            }
124    
125            return progress.getDeploymentStatus();
126        }
127    
128        /**
129         * Returns the Geronimo moduleId for the given artifact.
130         *
131         * @param item  The artifact item to get the moduleId for.
132         * @return      The moduleId of the given artifact item.
133         */
134        protected String getModuleId(final ArtifactItem item) {
135            assert item != null;
136    
137            return item.getGroupId() + "/" + item.getArtifactId() + "/" + item.getVersion() + "/" + item.getType();
138        }
139    
140        /**
141         * Check of the given module is started.
142         *
143         * @param moduleId  The module ID to check
144         * @return          True if the module for this ID is started.
145         *
146         * @throws Exception
147         */
148        protected boolean isModuleStarted(final String moduleId) throws Exception {
149            assert moduleId != null;
150    
151            log.debug("Checking if module is started: " + moduleId);
152            
153            DeploymentManager manager = getDeploymentManager();
154    
155            Target[] targets = manager.getTargets();
156            TargetModuleID targetIds[] = manager.getRunningModules(null, targets);
157    
158            for (int i = 0; i < targetIds.length; i++) {
159                if (moduleId.equals(targetIds[i].getModuleID())) {
160                    return true;
161                }
162            }
163    
164            return false;
165        }
166    
167        protected TargetModuleID[] findModules(final String moduleId, final TargetModuleID targetIds[]) {
168            assert moduleId != null;
169            assert targetIds != null;
170    
171            List found = new ArrayList();
172    
173            log.debug("Scanning for modules that match: " + moduleId);
174            for (int i = 0; i < targetIds.length; i++) {
175                log.debug("Checking: " + targetIds[i].getModuleID());
176    
177                if (moduleId.equals(targetIds[i].getModuleID())) {
178                    found.add(targetIds[i]);
179                }
180            }
181    
182            return (TargetModuleID[]) found.toArray(new TargetModuleID[found.size()]);
183        }
184    
185        //
186        // TODO: Can probably wrap up some of this into findModules with a flag for running or non-running
187        //
188        
189        protected void startModule() throws Exception {
190            assert modules != null;
191    
192            DeploymentManager manager = getDeploymentManager();
193            Target[] targets = manager.getTargets();
194            TargetModuleID[] targetIds = manager.getNonRunningModules(null, targets);
195    
196            for (int i=0; i<modules.length; i++) {
197               String moduleId = getModuleId(modules[i]);
198            
199               if (isModuleStarted(moduleId)) {
200                   log.warn("Module is already started: " + moduleId);
201                   continue;
202                   //throw new MojoExecutionException("Module is already started: " + moduleId);
203               }
204    
205               TargetModuleID[] found = findModules(moduleId, targetIds);
206    
207               if (found.length == 0) {
208                   throw new MojoExecutionException("Module is not deployed: " + moduleId);
209               }
210    
211               log.info("Starting module: " + moduleId);
212               ProgressObject progress = manager.start(found);
213    
214               DeploymentStatus status = waitFor(progress);
215               if (status.isFailed()) {
216                   throw new MojoExecutionException("Failed to start module: " + moduleId);
217               }
218    
219               log.info("Started module(s):");
220               logModules(found, "    ");
221            }
222        }
223    
224        protected void stopModule() throws Exception {
225            assert modules != null;
226    
227            DeploymentManager manager = getDeploymentManager();
228            Target[] targets = manager.getTargets();
229            TargetModuleID[] targetIds = manager.getRunningModules(null, targets);
230    
231             for (int i=0; i<modules.length; i++) {
232               String moduleId = getModuleId(modules[i]);
233               if (!isModuleStarted(moduleId)) {
234                   log.warn("Module is already stopped: " + moduleId);
235                   continue;
236                   //throw new MojoExecutionException("Module is not started: " + moduleId);
237               }
238    
239               TargetModuleID[] found = findModules(moduleId, targetIds);
240    
241               if (found.length == 0) {
242                   throw new MojoExecutionException("Module not deployed: " + moduleId);
243               }
244    
245               log.info("Stopping module: " + moduleId);
246               ProgressObject progress = manager.stop(found);
247    
248               DeploymentStatus status = waitFor(progress);
249               if (status.isFailed()) {
250                   throw new MojoExecutionException("Failed to stop module: " + moduleId);
251               }
252    
253               log.info("Stopped module(s):");
254               logModules(found, "    ");
255             }
256        }
257    
258        protected void undeployModule() throws Exception {
259            assert modules != null;
260    
261            stopModule();
262    
263            DeploymentManager manager = getDeploymentManager();
264            Target[] targets = manager.getTargets();
265            TargetModuleID[] targetIds = manager.getNonRunningModules(null, targets);
266    
267            for (int i=0; i<modules.length; i++) {
268              String moduleId = getModuleId(modules[i]);
269    
270              TargetModuleID[] found = findModules(moduleId, targetIds);
271    
272              if (found.length == 0) {
273                  throw new Exception("Module is not deployed: " + moduleId);
274              }
275    
276              log.info("Undeploying module: " + moduleId);
277              ProgressObject progress = manager.undeploy(found);
278    
279              DeploymentStatus status = waitFor(progress);
280              if (status.isFailed()) {
281                  throw new MojoExecutionException("Failed to undeploy module: " + moduleId);
282              }
283    
284              log.info("Undeployed module(s):");
285              logModules(found, "    ");
286            }
287        }
288    
289        protected void logModules(final TargetModuleID[] targetIds) {
290            logModules(targetIds, "");
291        }
292    
293        protected void logModules(final TargetModuleID[] targetIds, final String pad) {
294            assert targetIds != null;
295            assert pad != null;
296    
297            for (int i=0; i<targetIds.length; i++) {
298                String url = targetIds[i].getWebURL();
299                log.info(pad + "[" + i + "] " + targetIds[i].getModuleID() + (url == null ? "" : ("; URL: " + url)));
300    
301                TargetModuleID[] children = targetIds[i].getChildTargetModuleID();
302                if (children != null) {
303                    logModules(children, pad + "    ");
304                }
305            }
306        }
307    
308    }