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