001    /**
002     *
003     * Copyright 2003-2004 The Apache Software Foundation
004     *
005     *  Licensed under the Apache License, Version 2.0 (the "License");
006     *  you may not use this file except in compliance with the License.
007     *  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.geronimo.deployment.plugin.local;
018    
019    import java.io.File;
020    import java.io.InputStream;
021    import java.util.Iterator;
022    import javax.enterprise.deploy.shared.CommandType;
023    import javax.enterprise.deploy.spi.Target;
024    import javax.enterprise.deploy.spi.TargetModuleID;
025    import org.apache.geronimo.deployment.plugin.ConfigIDExtractor;
026    import org.apache.geronimo.deployment.plugin.TargetImpl;
027    import org.apache.geronimo.deployment.plugin.TargetModuleIDImpl;
028    import org.apache.geronimo.deployment.util.DeploymentUtil;
029    import org.apache.geronimo.gbean.AbstractName;
030    import org.apache.geronimo.kernel.InternalKernelException;
031    import org.apache.geronimo.kernel.Kernel;
032    import org.apache.geronimo.kernel.config.ConfigurationManager;
033    import org.apache.geronimo.kernel.config.ConfigurationUtil;
034    import org.apache.geronimo.kernel.config.LifecycleResults;
035    import org.apache.geronimo.kernel.config.NoSuchConfigException;
036    import org.apache.geronimo.kernel.repository.Artifact;
037    
038    /**
039     * @version $Rev: 428535 $ $Date: 2006-08-03 14:36:04 -0700 (Thu, 03 Aug 2006) $
040     */
041    public class RedeployCommand extends AbstractDeployCommand {
042        private static final String[] IS_IN_PLACE_CONFIGURATION_SIG =  {Artifact.class.getName()};
043        private static final String IS_IN_PLACE_CONFIGURATION_METH = "isInPlaceConfiguration";
044    
045        private final TargetModuleID[] modules;
046    
047        public RedeployCommand(Kernel kernel, TargetModuleID[] moduleIDList, File moduleArchive, File deploymentPlan) {
048            super(CommandType.REDEPLOY, kernel, moduleArchive, deploymentPlan, null, null, false);
049            this.modules = moduleIDList;
050        }
051    
052        public RedeployCommand(Kernel kernel, TargetModuleID[] moduleIDList, InputStream moduleArchive, InputStream deploymentPlan) {
053            super(CommandType.REDEPLOY, kernel, null, null, moduleArchive, deploymentPlan, true);
054            this.modules = moduleIDList;
055        }
056    
057        public void run() {
058            if (deployer == null) {
059                return;
060            }
061    
062            try {
063                if (spool) {
064                    if (moduleStream != null) {
065                        moduleArchive = DeploymentUtil.createTempFile();
066                        copyTo(moduleArchive, moduleStream);
067                    }
068                    if (deploymentStream != null) {
069                        deploymentPlan = DeploymentUtil.createTempFile();
070                        copyTo(deploymentPlan, deploymentStream);
071                    }
072                }
073                Artifact configID = null;
074                if(deploymentPlan != null) {
075                    String extracted = ConfigIDExtractor.extractModuleIdFromPlan(deploymentPlan);
076                    if(extracted != null) {
077                        configID = Artifact.create(extracted);
078                    }
079                } else {
080                    String extracted = ConfigIDExtractor.extractModuleIdFromArchive(moduleArchive);
081                    if(extracted != null) {
082                        configID = Artifact.create(extracted);
083                    }
084                }
085                if(configID != null && configID.getGroupId() == null) {
086                    configID = new Artifact(Artifact.DEFAULT_GROUP_ID, configID.getArtifactId(),
087                                            configID.getVersion(), configID.getType());
088                }
089    
090                ConfigurationManager configurationManager = ConfigurationUtil.getConfigurationManager(kernel);
091                try {
092                    for (int i = 0; i < modules.length; i++) {
093                        TargetModuleIDImpl module = (TargetModuleIDImpl) modules[i];
094                        Artifact artifact = Artifact.create(module.getModuleID());
095                        if(configID != null && configID.isResolved()) {
096                            if(configID.getGroupId().equals(artifact.getGroupId()) &&
097                                    configID.getArtifactId().equals(artifact.getArtifactId()) &&
098                                    configID.getVersion().equals(artifact.getVersion())) {
099                                redeploySameConfiguration(configurationManager, artifact, module.getTarget());
100                            } else {
101                                redeployUpdatedConfiguration(configurationManager, artifact, module.getTarget());
102                            }
103                        } else {
104                            redeployUpdatedConfiguration(configurationManager, artifact, module.getTarget());
105                        }
106                    }
107                } finally {
108                    ConfigurationUtil.releaseConfigurationManager(kernel, configurationManager);
109                }
110                addWebURLs(kernel);
111                complete("Completed");
112            } catch (Exception e) {
113                doFail(e);
114            } finally {
115                if (spool) {
116                    if (moduleArchive != null) {
117                        moduleArchive.delete();
118                    }
119                    if (deploymentPlan != null) {
120                        deploymentPlan.delete();
121                    }
122                }
123            }
124        }
125    
126        private void redeployUpdatedConfiguration(ConfigurationManager manager, Artifact previous, Target target) throws Exception, NoSuchConfigException {
127            // Send the new configuration to the server
128    
129                // if the configuration is an in-place one, then redeploys
130                // in in-place mode.
131            TargetImpl impl = (TargetImpl) target;
132            AbstractName storeName = impl.getAbstractName();
133            Boolean inPlaceConfiguration = (Boolean) kernel.invoke(storeName, IS_IN_PLACE_CONFIGURATION_METH, new Object[]{previous}, IS_IN_PLACE_CONFIGURATION_SIG);
134            commandContext.setInPlace(inPlaceConfiguration.booleanValue());
135            doDeploy(target, false);
136            Artifact configID = Artifact.create(getResultTargetModuleIDs()[0].getModuleID());
137            LifecycleResults results = manager.reloadConfiguration(previous, configID.getVersion());
138    
139            // Activate it
140            //todo: make this asynchronous
141            boolean newStarted = false;
142            for (Iterator it = results.getStopped().iterator(); it.hasNext();) {
143                Artifact name = (Artifact) it.next();
144                updateStatus("Stopped "+name);
145            }
146            for (Iterator it = results.getUnloaded().iterator(); it.hasNext();) {
147                Artifact name = (Artifact) it.next();
148                updateStatus("Unloaded "+name);
149            }
150            for (Iterator it = results.getLoaded().iterator(); it.hasNext();) {
151                Artifact name = (Artifact) it.next();
152                updateStatus("Loaded "+name);
153            }
154            for (Iterator it = results.getStarted().iterator(); it.hasNext();) {
155                Artifact name = (Artifact) it.next();
156                updateStatus("Started "+name);
157                if(configID.matches(name)) {
158                    newStarted = true;
159                }
160            }
161            for (Iterator it = results.getFailed().keySet().iterator(); it.hasNext();) {
162                Artifact name = (Artifact) it.next();
163                updateStatus("Failed on "+name+": "+results.getFailedCause(name).getMessage());
164                doFail((Exception)results.getFailedCause(name));
165            }
166            if(results.getFailed().size() == 0 && !newStarted) {
167                updateStatus("Note: new module was not started (probably because old module was not running).");
168            }
169        }
170    
171        private void redeploySameConfiguration(ConfigurationManager configurationManager, Artifact configID, Target target) throws Exception {
172            if(!configID.isResolved()) {
173                throw new IllegalStateException("Cannot redeploy same module when module ID is not fully resolved ("+configID+")");
174            }
175            try {
176                configurationManager.stopConfiguration(configID);
177                updateStatus("Stopped "+configID);
178            } catch (InternalKernelException e) {
179                Exception cause = (Exception)e.getCause();
180                if(cause instanceof NoSuchConfigException) {
181                    // The modules isn't loaded -- that's OK
182                } else {
183                    throw cause;
184                }
185            } catch(NoSuchConfigException e) {
186                // The module isn't loaded -- that's OK
187            }
188            try {
189                configurationManager.unloadConfiguration(configID);
190                updateStatus("Unloaded "+configID);
191            } catch(InternalKernelException e) {
192                Exception cause = (Exception)e.getCause();
193                if(cause instanceof NoSuchConfigException) {
194                    // The modules isn't loaded -- that's OK
195                } else {
196                    throw cause;
197                }
198            } catch (NoSuchConfigException e) {
199                // The modules isn't loaded -- that's OK
200            }
201    
202            // if the configuration is an in-place one, then redeploys
203            // in in-place mode.
204            TargetImpl impl = (TargetImpl) target;
205            AbstractName storeName = impl.getAbstractName();
206            Boolean inPlaceConfiguration = (Boolean) kernel.invoke(storeName, IS_IN_PLACE_CONFIGURATION_METH, new Object[]{configID}, IS_IN_PLACE_CONFIGURATION_SIG);
207            commandContext.setInPlace(inPlaceConfiguration.booleanValue());
208    
209            try {
210                configurationManager.uninstallConfiguration(configID);
211                updateStatus("Uninstalled "+configID);
212            } catch(InternalKernelException e) {
213                Exception cause = (Exception)e.getCause();
214                if(cause instanceof NoSuchConfigException) {
215                    throw new IllegalStateException("Module "+configID+" is not installed!");
216                } else {
217                    throw cause;
218                }
219            } catch (NoSuchConfigException e) {
220                throw new IllegalStateException("Module "+configID+" is not installed!");
221            }
222    
223            doDeploy(target, false);
224            updateStatus("Deployed "+configID);
225    
226            configurationManager.loadConfiguration(configID);
227            configurationManager.startConfiguration(configID);
228            updateStatus("Started " + configID);
229        }
230    }