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.jmx;
018    
019    import java.io.File;
020    import java.io.IOException;
021    import java.io.InputStream;
022    import java.net.InetAddress;
023    import java.net.NetworkInterface;
024    import java.net.URL;
025    import java.util.ArrayList;
026    import java.util.Arrays;
027    import java.util.Collection;
028    import java.util.Enumeration;
029    import java.util.Iterator;
030    import java.util.List;
031    import java.util.Map;
032    import java.util.Set;
033    
034    import javax.enterprise.deploy.shared.CommandType;
035    import javax.enterprise.deploy.shared.ModuleType;
036    import javax.enterprise.deploy.spi.Target;
037    import javax.enterprise.deploy.spi.TargetModuleID;
038    import javax.enterprise.deploy.spi.status.ProgressEvent;
039    import javax.enterprise.deploy.spi.status.ProgressListener;
040    import javax.management.MBeanServerConnection;
041    import javax.management.remote.JMXConnector;
042    import javax.security.auth.login.FailedLoginException;
043    
044    import org.apache.commons.logging.Log;
045    import org.apache.commons.logging.LogFactory;
046    import org.apache.geronimo.deployment.ModuleConfigurer;
047    import org.apache.geronimo.deployment.plugin.GeronimoDeploymentManager;
048    import org.apache.geronimo.deployment.plugin.local.AbstractDeployCommand;
049    import org.apache.geronimo.deployment.plugin.local.DistributeCommand;
050    import org.apache.geronimo.deployment.plugin.local.RedeployCommand;
051    import org.apache.geronimo.deployment.plugin.remote.RemoteDeployUtil;
052    import org.apache.geronimo.gbean.AbstractName;
053    import org.apache.geronimo.gbean.AbstractNameQuery;
054    import org.apache.geronimo.gbean.GBeanInfo;
055    import org.apache.geronimo.gbean.GBeanInfoBuilder;
056    import org.apache.geronimo.kernel.repository.Artifact;
057    import org.apache.geronimo.system.jmx.KernelDelegate;
058    import org.apache.geronimo.system.plugin.DownloadPoller;
059    import org.apache.geronimo.system.plugin.DownloadResults;
060    import org.apache.geronimo.system.plugin.PluginInstaller;
061    import org.apache.geronimo.system.plugin.PluginList;
062    import org.apache.geronimo.system.plugin.PluginMetadata;
063    import org.apache.geronimo.system.plugin.PluginRepositoryList;
064    
065    /**
066     * Connects to a Kernel in a remote VM (may or many not be on the same machine).
067     *
068     * @version $Rev: 512979 $ $Date: 2007-02-28 16:28:28 -0500 (Wed, 28 Feb 2007) $
069     */
070    public class RemoteDeploymentManager extends JMXDeploymentManager implements GeronimoDeploymentManager {
071        private static final Log log = LogFactory.getLog(RemoteDeploymentManager.class);
072    
073        private JMXConnector jmxConnector;
074        private boolean isSameMachine;
075    
076        public RemoteDeploymentManager(Collection<ModuleConfigurer> moduleConfigurers) {
077            super(moduleConfigurers);
078        }
079    
080        public void init(JMXConnector jmxConnector, String hostname) throws IOException {
081            this.jmxConnector = jmxConnector;
082            MBeanServerConnection mbServerConnection = jmxConnector.getMBeanServerConnection();
083            initialize(new KernelDelegate(mbServerConnection));
084            checkSameMachine(hostname);
085        }
086        
087        public boolean isSameMachine() {
088            return isSameMachine;
089        }
090    
091        private void checkSameMachine(String hostname) {
092            isSameMachine = false;
093            if(hostname.equals("localhost") || hostname.equals("127.0.0.1")) {
094                isSameMachine = true;
095                return;
096            }
097            try {
098                InetAddress dest = InetAddress.getByName(hostname);
099                Enumeration en = NetworkInterface.getNetworkInterfaces();
100                while(en.hasMoreElements()) {
101                    NetworkInterface iface = (NetworkInterface) en.nextElement();
102                    Enumeration ine = iface.getInetAddresses();
103                    while (ine.hasMoreElements()) {
104                        InetAddress address = (InetAddress) ine.nextElement();
105                        if(address.equals(dest)) {
106                            isSameMachine = true;
107                        }
108                    }
109                }
110            } catch (Exception e) {
111                log.error("Unable to look up host name '"+hostname+"'; assuming it is a different machine, but this may not get very far.", e);
112            }
113        }
114    
115        public void release() {
116            super.release();
117            try {
118                jmxConnector.close();
119                jmxConnector = null;
120            } catch (IOException e) {
121                throw (IllegalStateException) new IllegalStateException("Unable to close connection").initCause(e);
122            }
123        }
124    
125        protected DistributeCommand createDistributeCommand(Target[] targetList, File moduleArchive, File deploymentPlan) {
126            if(isSameMachine) {
127                return super.createDistributeCommand(targetList, moduleArchive, deploymentPlan);
128            } else {
129                return new org.apache.geronimo.deployment.plugin.remote.DistributeCommand(kernel, targetList, moduleArchive, deploymentPlan);
130            }
131        }
132    
133        protected DistributeCommand createDistributeCommand(Target[] targetList, ModuleType moduleType, InputStream moduleArchive, InputStream deploymentPlan) {
134            if(isSameMachine) {
135                return super.createDistributeCommand(targetList, moduleType, moduleArchive, deploymentPlan);
136            } else {
137                return new org.apache.geronimo.deployment.plugin.remote.DistributeCommand(kernel, targetList, moduleType, moduleArchive, deploymentPlan);
138            }
139        }
140    
141        protected RedeployCommand createRedeployCommand(TargetModuleID[] moduleIDList, File moduleArchive, File deploymentPlan) {
142            if(isSameMachine) {
143                return super.createRedeployCommand(moduleIDList, moduleArchive, deploymentPlan);
144            } else {
145                return new org.apache.geronimo.deployment.plugin.remote.RedeployCommand(kernel, moduleIDList, moduleArchive, deploymentPlan);
146            }
147        }
148    
149        protected RedeployCommand createRedeployCommand(TargetModuleID[] moduleIDList, InputStream moduleArchive, InputStream deploymentPlan) {
150            if(isSameMachine) {
151                return super.createRedeployCommand(moduleIDList, moduleArchive, deploymentPlan);
152            } else {
153                return new org.apache.geronimo.deployment.plugin.remote.RedeployCommand(kernel, moduleIDList, moduleArchive, deploymentPlan);
154            }
155        }
156    
157        public PluginList listPlugins(URL mavenRepository, String username, String password) throws FailedLoginException, IOException {
158            Set set = kernel.listGBeans(new AbstractNameQuery(PluginInstaller.class.getName()));
159            for (Iterator it = set.iterator(); it.hasNext();) {
160                AbstractName name = (AbstractName) it.next();
161                PluginInstaller installer = (PluginInstaller) kernel.getProxyManager().createProxy(name, PluginInstaller.class);
162                PluginList results = installer.listPlugins(mavenRepository, username, password);
163                kernel.getProxyManager().destroyProxy(installer);
164                return results;
165            }
166            return null;
167        }
168    
169        public DownloadResults install(PluginList installList, String username, String password) {
170            Set set = kernel.listGBeans(new AbstractNameQuery(PluginInstaller.class.getName()));
171            for (Iterator it = set.iterator(); it.hasNext();) {
172                AbstractName name = (AbstractName) it.next();
173                PluginInstaller installer = (PluginInstaller) kernel.getProxyManager().createProxy(name, PluginInstaller.class);
174                DownloadResults results = installer.install(installList, username, password);
175                kernel.getProxyManager().destroyProxy(installer);
176                return results;
177            }
178            return null;
179        }
180    
181        public void install(PluginList configsToInstall, String username, String password, DownloadPoller poller) {
182            Set set = kernel.listGBeans(new AbstractNameQuery(PluginInstaller.class.getName()));
183            for (Iterator it = set.iterator(); it.hasNext();) {
184                AbstractName name = (AbstractName) it.next();
185                PluginInstaller installer = (PluginInstaller) kernel.getProxyManager().createProxy(name, PluginInstaller.class);
186                installer.install(configsToInstall, username, password, poller);
187                kernel.getProxyManager().destroyProxy(installer);
188                return;
189            }
190        }
191    
192        public Object startInstall(PluginList configsToInstall, String username, String password) {
193            Set set = kernel.listGBeans(new AbstractNameQuery(PluginInstaller.class.getName()));
194            for (Iterator it = set.iterator(); it.hasNext();) {
195                AbstractName name = (AbstractName) it.next();
196                PluginInstaller installer = (PluginInstaller) kernel.getProxyManager().createProxy(name, PluginInstaller.class);
197                Object result = installer.startInstall(configsToInstall, username, password);
198                kernel.getProxyManager().destroyProxy(installer);
199                return result;
200            }
201            return null;
202        }
203    
204        public Object startInstall(File carFile, String username, String password) {
205            File[] args = new File[]{carFile};
206            if(!isSameMachine) {
207                AbstractDeployCommand progress = new AbstractDeployCommand(CommandType.DISTRIBUTE, kernel, null, null, null, null, null, false) {
208                    public void run() {
209                    }
210                };
211                progress.addProgressListener(new ProgressListener() {
212                    public void handleProgressEvent(ProgressEvent event) {
213                        log.info(event.getDeploymentStatus().getMessage());
214                    }
215                });
216                RemoteDeployUtil.uploadFilesToServer(args, progress);
217            }
218            Set set = kernel.listGBeans(new AbstractNameQuery(PluginInstaller.class.getName()));
219            for (Iterator it = set.iterator(); it.hasNext();) {
220                AbstractName name = (AbstractName) it.next();
221                PluginInstaller installer = (PluginInstaller) kernel.getProxyManager().createProxy(name, PluginInstaller.class);
222                Object result = installer.startInstall(carFile, username, password);
223                kernel.getProxyManager().destroyProxy(installer);
224                return result;
225            }
226            return null;
227        }
228    
229        public DownloadResults checkOnInstall(Object key) {
230            Set set = kernel.listGBeans(new AbstractNameQuery(PluginInstaller.class.getName()));
231            for (Iterator it = set.iterator(); it.hasNext();) {
232                AbstractName name = (AbstractName) it.next();
233                PluginInstaller installer = (PluginInstaller) kernel.getProxyManager().createProxy(name, PluginInstaller.class);
234                DownloadResults result = installer.checkOnInstall(key);
235                kernel.getProxyManager().destroyProxy(installer);
236                return result;
237            }
238            return null;
239        }
240    
241        public Map getInstalledPlugins() {
242            Set set = kernel.listGBeans(new AbstractNameQuery(PluginInstaller.class.getName()));
243            for (Iterator it = set.iterator(); it.hasNext();) {
244                AbstractName name = (AbstractName) it.next();
245                PluginInstaller installer = (PluginInstaller) kernel.getProxyManager().createProxy(name, PluginInstaller.class);
246                Map result = installer.getInstalledPlugins();
247                kernel.getProxyManager().destroyProxy(installer);
248                return result;
249            }
250            return null;
251        }
252    
253        public PluginMetadata getPluginMetadata(Artifact configId) {
254            Set set = kernel.listGBeans(new AbstractNameQuery(PluginInstaller.class.getName()));
255            for (Iterator it = set.iterator(); it.hasNext();) {
256                AbstractName name = (AbstractName) it.next();
257                PluginInstaller installer = (PluginInstaller) kernel.getProxyManager().createProxy(name, PluginInstaller.class);
258                PluginMetadata result = installer.getPluginMetadata(configId);
259                kernel.getProxyManager().destroyProxy(installer);
260                return result;
261            }
262            return null;
263        }
264    
265        public void updatePluginMetadata(PluginMetadata metadata) {
266            Set set = kernel.listGBeans(new AbstractNameQuery(PluginInstaller.class.getName()));
267            for (Iterator it = set.iterator(); it.hasNext();) {
268                AbstractName name = (AbstractName) it.next();
269                PluginInstaller installer = (PluginInstaller) kernel.getProxyManager().createProxy(name, PluginInstaller.class);
270                installer.updatePluginMetadata(metadata);
271                kernel.getProxyManager().destroyProxy(installer);
272                return;
273            }
274        }
275    
276        public URL[] getRepositories() {
277            List list = new ArrayList();
278            Set set = kernel.listGBeans(new AbstractNameQuery(PluginRepositoryList.class.getName()));
279            for (Iterator it = set.iterator(); it.hasNext();) {
280                AbstractName name = (AbstractName) it.next();
281                PluginRepositoryList repo = (PluginRepositoryList) kernel.getProxyManager().createProxy(name, PluginRepositoryList.class);
282                list.addAll(Arrays.asList(repo.getRepositories()));
283                kernel.getProxyManager().destroyProxy(repo);
284            }
285            return (URL[]) list.toArray(new URL[list.size()]);
286        }
287        
288        public static final GBeanInfo GBEAN_INFO;
289        public static final String GBEAN_REF_MODULE_CONFIGURERS = "ModuleConfigurers";
290        
291        static {
292            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(RemoteDeploymentManager.class, "RemoteDeploymentManager");
293            infoFactory.addInterface(GeronimoDeploymentManager.class);
294            infoFactory.addReference(GBEAN_REF_MODULE_CONFIGURERS, ModuleConfigurer.class);
295    
296            infoFactory.setConstructor(new String[] {GBEAN_REF_MODULE_CONFIGURERS});
297            
298            GBEAN_INFO = infoFactory.getBeanInfo();
299        }
300    
301        public static GBeanInfo getGBeanInfo() {
302            return GBEAN_INFO;
303        }
304    
305    }