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.tomcat;
018    
019    import java.util.ArrayList;
020    import java.util.Arrays;
021    import java.util.HashMap;
022    import java.util.Iterator;
023    import java.util.List;
024    import java.util.Map;
025    import java.util.Map.Entry;
026    import java.util.Set;
027    
028    import javax.net.ssl.KeyManagerFactory;
029    
030    import org.apache.commons.logging.Log;
031    import org.apache.commons.logging.LogFactory;
032    import org.apache.geronimo.gbean.AbstractName;
033    import org.apache.geronimo.gbean.AbstractNameQuery;
034    import org.apache.geronimo.gbean.GBeanData;
035    import org.apache.geronimo.gbean.GBeanInfo;
036    import org.apache.geronimo.gbean.GBeanInfoBuilder;
037    import org.apache.geronimo.gbean.ReferencePatterns;
038    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
039    import org.apache.geronimo.kernel.GBeanNotFoundException;
040    import org.apache.geronimo.kernel.Kernel;
041    import org.apache.geronimo.kernel.config.ConfigurationUtil;
042    import org.apache.geronimo.kernel.config.EditableConfigurationManager;
043    import org.apache.geronimo.kernel.config.InvalidConfigException;
044    import org.apache.geronimo.kernel.proxy.ProxyManager;
045    import org.apache.geronimo.management.geronimo.NetworkConnector;
046    import org.apache.geronimo.management.geronimo.WebAccessLog;
047    import org.apache.geronimo.management.geronimo.WebContainer;
048    import org.apache.geronimo.management.geronimo.WebManager;
049    import org.apache.geronimo.system.serverinfo.ServerInfo;
050    import org.apache.geronimo.tomcat.connector.AJP13ConnectorGBean;
051    import org.apache.geronimo.tomcat.connector.ConnectorGBean;
052    import org.apache.geronimo.tomcat.connector.Http11APRConnectorGBean;
053    import org.apache.geronimo.tomcat.connector.Http11ConnectorGBean;
054    import org.apache.geronimo.tomcat.connector.Http11NIOConnectorGBean;
055    import org.apache.geronimo.tomcat.connector.Https11APRConnectorGBean;
056    import org.apache.geronimo.tomcat.connector.Https11ConnectorGBean;
057    import org.apache.geronimo.tomcat.connector.Https11NIOConnectorGBean;
058    import org.apache.geronimo.tomcat.connector.TomcatWebConnector;
059    import org.apache.geronimo.crypto.KeystoreUtil;
060    
061    /**
062     * Tomcat implementation of the WebManager management API.  Knows how to
063     * manipulate other Tomcat objects for management purposes.
064     *
065     * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
066     */
067    public class TomcatManagerImpl implements WebManager {
068        private final static Log log = LogFactory.getLog(TomcatManagerImpl.class);
069        private final Kernel kernel;
070        
071        private static final ConnectorType HTTP_BIO = new ConnectorType(Messages.getString("TomcatManagerImpl.0")); //$NON-NLS-1$
072        private static final ConnectorType HTTPS_BIO = new ConnectorType(Messages.getString("TomcatManagerImpl.1")); //$NON-NLS-1$
073        private static final ConnectorType HTTP_NIO = new ConnectorType(Messages.getString("TomcatManagerImpl.2")); //$NON-NLS-1$
074        private static final ConnectorType HTTPS_NIO = new ConnectorType(Messages.getString("TomcatManagerImpl.3")); //$NON-NLS-1$
075        private static final ConnectorType HTTP_APR = new ConnectorType(Messages.getString("TomcatManagerImpl.4")); //$NON-NLS-1$
076        private static final ConnectorType HTTPS_APR = new ConnectorType(Messages.getString("TomcatManagerImpl.5")); //$NON-NLS-1$
077        private static final ConnectorType AJP = new ConnectorType(Messages.getString("TomcatManagerImpl.6")); //$NON-NLS-1$
078        private static List<ConnectorType> CONNECTOR_TYPES = Arrays.asList(
079                HTTP_BIO,
080                HTTPS_BIO,
081                HTTP_NIO,
082                HTTPS_NIO,
083                HTTP_APR,
084                HTTPS_APR,
085                AJP
086        );
087        
088        private static Map<ConnectorType, List<ConnectorAttribute>> CONNECTOR_ATTRIBUTES = new HashMap<ConnectorType, List<ConnectorAttribute>>();
089    
090        static {
091            //******************* HTTP - BIO CONNECTOR
092            List<ConnectorAttribute> connectorAttributes = new ArrayList<ConnectorAttribute>();
093            addCommonConnectorAttributes(connectorAttributes);
094            addHttpConnectorAttributes(connectorAttributes);
095            CONNECTOR_ATTRIBUTES.put(HTTP_BIO, connectorAttributes);
096            
097            //******************* HTTPS - BIO CONNECTOR
098            connectorAttributes = new ArrayList<ConnectorAttribute>();
099            addCommonConnectorAttributes(connectorAttributes);
100            addHttpConnectorAttributes(connectorAttributes);
101            addSslConnectorAttributes(connectorAttributes);
102            setAttribute(connectorAttributes, "port", 8443); // SSL port
103            CONNECTOR_ATTRIBUTES.put(HTTPS_BIO, connectorAttributes);
104            
105            //******************* HTTP - NIO CONNECTOR
106            connectorAttributes = new ArrayList<ConnectorAttribute>();
107            addCommonConnectorAttributes(connectorAttributes);
108            addHttpConnectorAttributes(connectorAttributes);
109            addNioConnectorAttributes(connectorAttributes);
110            CONNECTOR_ATTRIBUTES.put(HTTP_NIO, connectorAttributes);
111            
112            //******************* HTTPS - NIO CONNECTOR
113            connectorAttributes = new ArrayList<ConnectorAttribute>();
114            addCommonConnectorAttributes(connectorAttributes);
115            addHttpConnectorAttributes(connectorAttributes);
116            addSslConnectorAttributes(connectorAttributes);
117            addNioConnectorAttributes(connectorAttributes);
118            setAttribute(connectorAttributes, "port", 8443); // SSL port
119            CONNECTOR_ATTRIBUTES.put(HTTPS_NIO, connectorAttributes);
120            
121            //******************* HTTP - APR CONNECTOR
122            connectorAttributes = new ArrayList<ConnectorAttribute>();        
123            addCommonConnectorAttributes(connectorAttributes);
124            addHttpConnectorAttributes(connectorAttributes);
125            addAprConnectorAttributes(connectorAttributes);
126            CONNECTOR_ATTRIBUTES.put(HTTP_APR, connectorAttributes);
127            
128            //******************* HTTPS - APR CONNECTOR
129            connectorAttributes = new ArrayList<ConnectorAttribute>();
130            addCommonConnectorAttributes(connectorAttributes);
131            addHttpConnectorAttributes(connectorAttributes);
132            addAprConnectorAttributes(connectorAttributes);
133            //APR SSL specific values, different from BIO and NIO SSL because it uses openssl
134            connectorAttributes.add(new ConnectorAttribute<String>("sslProtocol", "all", Messages.getString("TomcatManagerImpl.11"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
135            connectorAttributes.add(new ConnectorAttribute<String>("sslCipherSuite", "ALL", Messages.getString("TomcatManagerImpl.14"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
136            connectorAttributes.add(new ConnectorAttribute<String>("sslCertificateFile", "", Messages.getString("TomcatManagerImpl.17"), String.class, true)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
137            connectorAttributes.add(new ConnectorAttribute<String>("sslCertificateKeyFile", null, Messages.getString("TomcatManagerImpl.19"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$
138            connectorAttributes.add(new ConnectorAttribute<String>("sslPassword", null, Messages.getString("TomcatManagerImpl.21"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$
139            connectorAttributes.add(new ConnectorAttribute<String>("sslVerifyClient", "none", Messages.getString("TomcatManagerImpl.24"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
140            connectorAttributes.add(new ConnectorAttribute<Integer>("sslVerifyDepth", 10, Messages.getString("TomcatManagerImpl.26"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
141            connectorAttributes.add(new ConnectorAttribute<String>("sslCACertificateFile", null, Messages.getString("TomcatManagerImpl.28"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$
142            connectorAttributes.add(new ConnectorAttribute<String>("sslCACertificatePath", null, Messages.getString("TomcatManagerImpl.30"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$
143            connectorAttributes.add(new ConnectorAttribute<String>("sslCertificateChainFile", null, Messages.getString("TomcatManagerImpl.32"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$
144            connectorAttributes.add(new ConnectorAttribute<String>("sslCARevocationFile", null, Messages.getString("TomcatManagerImpl.34"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$
145            connectorAttributes.add(new ConnectorAttribute<String>("sslCARevocationPath", null, Messages.getString("TomcatManagerImpl.36"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$
146            setAttribute(connectorAttributes, "port", 8443); // SSL port
147            CONNECTOR_ATTRIBUTES.put(HTTPS_APR, connectorAttributes);
148            
149            //******************* AJP CONNECTOR
150            connectorAttributes = new ArrayList<ConnectorAttribute>();
151            addCommonConnectorAttributes(connectorAttributes);
152            //AJP Attributes, see http://tomcat.apache.org/tomcat-6.0-doc/config/ajp.html
153            connectorAttributes.add(new ConnectorAttribute<String>("host", "0.0.0.0", Messages.getString("TomcatManagerImpl.40"), String.class, true)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
154            connectorAttributes.add(new ConnectorAttribute<Integer>("port", 8009, Messages.getString("TomcatManagerImpl.42"), Integer.class, true)); //$NON-NLS-1$ //$NON-NLS-2$
155            connectorAttributes.add(new ConnectorAttribute<Integer>("backlog", 10, Messages.getString("TomcatManagerImpl.44"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
156            connectorAttributes.add(new ConnectorAttribute<Integer>("bufferSize", -1, Messages.getString("TomcatManagerImpl.46"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
157            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionTimeout", org.apache.coyote.ajp.Constants.DEFAULT_CONNECTION_TIMEOUT, Messages.getString("TomcatManagerImpl.48"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
158            connectorAttributes.add(new ConnectorAttribute<Integer>("keepAliveTimeout", org.apache.coyote.ajp.Constants.DEFAULT_CONNECTION_TIMEOUT, Messages.getString("TomcatManagerImpl.50"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
159            connectorAttributes.add(new ConnectorAttribute<Integer>("maxThreads", 40, Messages.getString("TomcatManagerImpl.52"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
160            connectorAttributes.add(new ConnectorAttribute<Integer>("minSpareThreads", 10, Messages.getString("TomcatManagerImpl.54"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
161            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSpareThreads", 100, Messages.getString("TomcatManagerImpl.56"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
162            connectorAttributes.add(new ConnectorAttribute<Boolean>("tcpNoDelay", true, Messages.getString("TomcatManagerImpl.58"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
163            connectorAttributes.add(new ConnectorAttribute<Boolean>("tomcatAuthentication", true, Messages.getString("TomcatManagerImpl.60"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
164            CONNECTOR_ATTRIBUTES.put(AJP, connectorAttributes);
165        }
166        
167        private static Map<ConnectorType, GBeanInfo> CONNECTOR_GBEAN_INFOS = new HashMap<ConnectorType, GBeanInfo>();
168    
169        static {
170            CONNECTOR_GBEAN_INFOS.put(HTTP_BIO, Http11ConnectorGBean.GBEAN_INFO);
171            CONNECTOR_GBEAN_INFOS.put(HTTPS_BIO, Https11ConnectorGBean.GBEAN_INFO);
172            CONNECTOR_GBEAN_INFOS.put(HTTP_NIO, Http11NIOConnectorGBean.GBEAN_INFO);
173            CONNECTOR_GBEAN_INFOS.put(HTTPS_NIO, Https11NIOConnectorGBean.GBEAN_INFO);
174            CONNECTOR_GBEAN_INFOS.put(HTTP_APR, Http11APRConnectorGBean.GBEAN_INFO);
175            CONNECTOR_GBEAN_INFOS.put(HTTPS_APR, Https11APRConnectorGBean.GBEAN_INFO);
176            CONNECTOR_GBEAN_INFOS.put(AJP, AJP13ConnectorGBean.GBEAN_INFO);
177        }
178        
179        public TomcatManagerImpl(Kernel kernel) {
180            this.kernel = kernel;
181        }
182    
183        public String getProductName() {
184            return "Tomcat";
185        }
186    
187        /**
188         * Gets the network containers.
189         */
190        public Object[] getContainers() {
191            ProxyManager proxyManager = kernel.getProxyManager();
192            AbstractNameQuery query = new AbstractNameQuery(TomcatWebContainer.class.getName());
193            Set names = kernel.listGBeans(query);
194            TomcatWebContainer[] results = new TomcatWebContainer[names.size()];
195            int i=0;
196            for (Iterator it = names.iterator(); it.hasNext(); i++) {
197                AbstractName name = (AbstractName) it.next();
198                results[i] = (TomcatWebContainer) proxyManager.createProxy(name, TomcatWebContainer.class.getClassLoader());
199            }
200            return results;
201        }
202    
203        /**
204         * Gets the protocols which this container can configure connectors for.
205         */
206        public String[] getSupportedProtocols() {
207            return new String[]{PROTOCOL_HTTP, PROTOCOL_HTTPS, PROTOCOL_AJP};
208        }
209    
210        /**
211         * Removes a connector.  This shuts it down if necessary, and removes it from the server environment.  It must be a
212         * connector that uses this network technology.
213         * @param connectorName
214         */
215        public void removeConnector(AbstractName connectorName) {
216            try {
217                GBeanInfo info = kernel.getGBeanInfo(connectorName);
218                boolean found = false;
219                Set intfs = info.getInterfaces();
220                for (Iterator it = intfs.iterator(); it.hasNext();) {
221                    String intf = (String) it.next();
222                    if (intf.equals(TomcatWebConnector.class.getName())) {
223                        found = true;
224                    }
225                }
226                if (!found) {
227                    throw new GBeanNotFoundException(connectorName);
228                }
229                EditableConfigurationManager mgr = ConfigurationUtil.getEditableConfigurationManager(kernel);
230                if(mgr != null) {
231                    try {
232                        mgr.removeGBeanFromConfiguration(connectorName.getArtifact(), connectorName);
233                    } catch (InvalidConfigException e) {
234                        log.error("Unable to add GBean", e);
235                    } finally {
236                        ConfigurationUtil.releaseConfigurationManager(kernel, mgr);
237                    }
238                } else {
239                    log.warn("The ConfigurationManager in the kernel does not allow editing");
240                }
241            } catch (GBeanNotFoundException e) {
242                log.warn("No such GBean '" + connectorName + "'"); //todo: what if we want to remove a failed GBean?
243            } catch (Exception e) {
244                log.error(e);
245            }
246        }
247    
248        /**
249         * Gets the ObjectNames of any existing connectors for this network technology for the specified protocol.
250         *
251         * @param protocol A protocol as returned by getSupportedProtocols
252         */
253        public NetworkConnector[] getConnectors(String protocol) {
254            if(protocol == null) {
255                return getConnectors();
256            }
257            List result = new ArrayList();
258            ProxyManager proxyManager = kernel.getProxyManager();
259            AbstractNameQuery query = new AbstractNameQuery(TomcatWebConnector.class.getName());
260            Set names = kernel.listGBeans(query);
261            for (Iterator it = names.iterator(); it.hasNext();) {
262                AbstractName name = (AbstractName) it.next();
263                try {
264                    if (kernel.getAttribute(name, "protocol").equals(protocol)) {
265                        result.add(proxyManager.createProxy(name, TomcatWebConnector.class.getClassLoader()));
266                    }
267                } catch (Exception e) {
268                    log.error("Unable to check the protocol for a connector", e);
269                }
270            }
271            return (TomcatWebConnector[]) result.toArray(new TomcatWebConnector[names.size()]);
272        }
273    
274        public WebAccessLog getAccessLog(WebContainer container) {
275            AbstractNameQuery query = new AbstractNameQuery(TomcatLogManager.class.getName());
276            Set names = kernel.listGBeans(query);
277            if(names.size() == 0) {
278                return null;
279            } else if(names.size() > 1) {
280                throw new IllegalStateException("Should not be more than one Tomcat access log manager");
281            }
282            return (WebAccessLog) kernel.getProxyManager().createProxy((AbstractName)names.iterator().next(), TomcatLogManager.class.getClassLoader());
283        }
284    
285        public List<ConnectorType> getConnectorTypes() {
286            return CONNECTOR_TYPES;
287        }
288    
289        public List<ConnectorAttribute> getConnectorAttributes(ConnectorType connectorType) {
290            return ConnectorAttribute.copy(CONNECTOR_ATTRIBUTES.get(connectorType));
291        }
292    
293        public AbstractName getConnectorConfiguration(ConnectorType connectorType, List<ConnectorAttribute> connectorAttributes, WebContainer container, String uniqueName) {
294            GBeanInfo gbeanInfo = CONNECTOR_GBEAN_INFOS.get(connectorType);
295            AbstractName containerName = kernel.getAbstractNameFor(container);
296            AbstractName name = kernel.getNaming().createSiblingName(containerName, uniqueName, NameFactory.GERONIMO_SERVICE);
297            GBeanData gbeanData = new GBeanData(name, gbeanInfo);
298            gbeanData.setAttribute("name", uniqueName);
299            gbeanData.setReferencePattern(ConnectorGBean.CONNECTOR_CONTAINER_REFERENCE, containerName);
300            for (ConnectorAttribute connectorAttribute : connectorAttributes) {
301                gbeanData.setAttribute(connectorAttribute.getAttributeName(), connectorAttribute.getValue());
302            }
303            AbstractNameQuery query = new AbstractNameQuery(ServerInfo.class.getName());
304            Set set = kernel.listGBeans(query);
305            AbstractName serverInfo = (AbstractName)set.iterator().next();
306            gbeanData.setReferencePattern("ServerInfo", serverInfo);
307    
308            EditableConfigurationManager mgr = ConfigurationUtil.getEditableConfigurationManager(kernel);
309            if (mgr != null) {
310                try {
311                    mgr.addGBeanToConfiguration(containerName.getArtifact(), gbeanData, false);
312                } catch (InvalidConfigException e) {
313                    log.error("Unable to add GBean", e);
314                    return null;
315                } finally {
316                    ConfigurationUtil.releaseConfigurationManager(kernel, mgr);
317                }
318            } else {
319                log.warn("The ConfigurationManager in the kernel does not allow editing");
320                return null;
321            }
322            return name;
323        }
324    
325        /**
326         * Gets the ObjectNames of any existing connectors associated with this network technology.
327         */
328        public NetworkConnector[] getConnectors() {
329            ProxyManager proxyManager = kernel.getProxyManager();
330            AbstractNameQuery query = new AbstractNameQuery(TomcatWebConnector.class.getName());
331            Set names = kernel.listGBeans(query);
332            TomcatWebConnector[] results = new TomcatWebConnector[names.size()];
333            int i=0;
334            for (Iterator it = names.iterator(); it.hasNext(); i++) {
335                AbstractName name = (AbstractName) it.next();
336                results[i] = (TomcatWebConnector) proxyManager.createProxy(name, TomcatWebConnector.class.getClassLoader());
337            }
338            return results;
339        }
340    
341        /**
342         * Gets the ObjectNames of any existing connectors for the specified container for the specified protocol.
343         *
344         * @param protocol A protocol as returned by getSupportedProtocols
345         */
346        public NetworkConnector[] getConnectorsForContainer(Object container, String protocol) {
347            if(protocol == null) {
348                return getConnectorsForContainer(container);
349            }
350            AbstractName containerName = kernel.getAbstractNameFor(container);
351            ProxyManager mgr = kernel.getProxyManager();
352            try {
353                List results = new ArrayList();
354                AbstractNameQuery query = new AbstractNameQuery(TomcatWebConnector.class.getName());
355                Set set = kernel.listGBeans(query); // all Tomcat connectors
356                for (Iterator it = set.iterator(); it.hasNext();) {
357                    AbstractName name = (AbstractName) it.next(); // a single Tomcat connector
358                    GBeanData data = kernel.getGBeanData(name);
359                    ReferencePatterns refs = data.getReferencePatterns(ConnectorGBean.CONNECTOR_CONTAINER_REFERENCE);
360                    if(containerName.equals(refs.getAbstractName())) {
361                        try {
362                            String testProtocol = (String) kernel.getAttribute(name, "protocol");
363                            if(testProtocol != null && testProtocol.equals(protocol)) {
364                                results.add(mgr.createProxy(name, TomcatWebConnector.class.getClassLoader()));
365                            }
366                        } catch (Exception e) {
367                            log.error("Unable to look up protocol for connector '"+name+"'",e);
368                        }
369                        break;
370                    }
371                }
372                return (TomcatWebConnector[]) results.toArray(new TomcatWebConnector[results.size()]);
373            } catch (Exception e) {
374                throw (IllegalArgumentException)new IllegalArgumentException("Unable to look up connectors for Tomcat container '"+containerName +"': ").initCause(e);
375            }
376        }
377    
378        /**
379         * Gets the ObjectNames of any existing connectors for the specified container.
380         */
381        public NetworkConnector[] getConnectorsForContainer(Object container) {
382            AbstractName containerName = kernel.getAbstractNameFor(container);
383            ProxyManager mgr = kernel.getProxyManager();
384            try {
385                List results = new ArrayList();
386                AbstractNameQuery query = new AbstractNameQuery(TomcatWebConnector.class.getName());
387                Set set = kernel.listGBeans(query); // all Tomcat connectors
388                for (Iterator it = set.iterator(); it.hasNext();) {
389                    AbstractName name = (AbstractName) it.next(); // a single Tomcat connector
390                    GBeanData data = kernel.getGBeanData(name);
391                    ReferencePatterns refs = data.getReferencePatterns(ConnectorGBean.CONNECTOR_CONTAINER_REFERENCE);
392                    if (containerName.equals(refs.getAbstractName())) {
393                        results.add(mgr.createProxy(name, TomcatWebConnector.class.getClassLoader()));
394                    }
395                }
396                return (TomcatWebConnector[]) results.toArray(new TomcatWebConnector[results.size()]);
397            } catch (Exception e) {
398                throw (IllegalArgumentException) new IllegalArgumentException("Unable to look up connectors for Tomcat container '"+containerName).initCause(e);
399            }
400        }
401    
402        // see http://tomcat.apache.org/tomcat-6.0-doc/config/http.html    
403        private static void addCommonConnectorAttributes(List<ConnectorAttribute> connectorAttributes) {
404            connectorAttributes.add(new ConnectorAttribute<Boolean>("allowTrace", false, Messages.getString("TomcatManagerImpl.80"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
405            connectorAttributes.add(new ConnectorAttribute<Boolean>("emptySessionPath", false, Messages.getString("TomcatManagerImpl.82"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
406            connectorAttributes.add(new ConnectorAttribute<Boolean>("enableLookups", true, Messages.getString("TomcatManagerImpl.84"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
407            connectorAttributes.add(new ConnectorAttribute<Integer>("maxPostSize", 2097152, Messages.getString("TomcatManagerImpl.86"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
408            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSavePostSize", 4096, Messages.getString("TomcatManagerImpl.88"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
409            connectorAttributes.add(new ConnectorAttribute<String>("proxyName", null, Messages.getString("TomcatManagerImpl.90"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$
410            connectorAttributes.add(new ConnectorAttribute<Integer>("proxyPort", 0, Messages.getString("TomcatManagerImpl.92"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
411            connectorAttributes.add(new ConnectorAttribute<Integer>("redirectPort", 8443, Messages.getString("TomcatManagerImpl.94"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
412            connectorAttributes.add(new ConnectorAttribute<String>("uriEncoding", "ISO-8859-1", Messages.getString("TomcatManagerImpl.97"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
413            connectorAttributes.add(new ConnectorAttribute<Boolean>("useBodyEncodingForURI", false, Messages.getString("TomcatManagerImpl.99"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
414            connectorAttributes.add(new ConnectorAttribute<Boolean>("useIPVHosts", false, Messages.getString("TomcatManagerImpl.101"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
415            connectorAttributes.add(new ConnectorAttribute<Boolean>("xpoweredBy", false, Messages.getString("TomcatManagerImpl.103"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
416        }
417        
418        // see http://tomcat.apache.org/tomcat-6.0-doc/config/http.html
419        private static void addHttpConnectorAttributes(List<ConnectorAttribute> connectorAttributes) {
420            connectorAttributes.add(new ConnectorAttribute<Integer>("acceptCount", 10, Messages.getString("TomcatManagerImpl.105"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
421            connectorAttributes.add(new ConnectorAttribute<String>("address", "0.0.0.0", Messages.getString("TomcatManagerImpl.108"), String.class, true)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
422            connectorAttributes.add(new ConnectorAttribute<Integer>("bufferSize", 2048, Messages.getString("TomcatManagerImpl.110"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
423            connectorAttributes.add(new ConnectorAttribute<String>("compressableMimeType", "text/html,text/xml,text/plain", Messages.getString("TomcatManagerImpl.113"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
424            connectorAttributes.add(new ConnectorAttribute<String>("compression", "off", Messages.getString("TomcatManagerImpl.116"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
425            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionLinger", -1, Messages.getString("TomcatManagerImpl.118"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
426            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionTimeout", 60000, Messages.getString("TomcatManagerImpl.120"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
427            connectorAttributes.add(new ConnectorAttribute<String>("executor", null, Messages.getString("TomcatManagerImpl.122"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$
428            connectorAttributes.add(new ConnectorAttribute<Integer>("keepAliveTimeout", 60000, Messages.getString("TomcatManagerImpl.124"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
429            connectorAttributes.add(new ConnectorAttribute<Boolean>("disableUploadTimeout", true, Messages.getString("TomcatManagerImpl.126"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
430            connectorAttributes.add(new ConnectorAttribute<Integer>("maxHttpHeaderSize", 4096, Messages.getString("TomcatManagerImpl.128"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
431            connectorAttributes.add(new ConnectorAttribute<Integer>("maxKeepAliveRequests", 100, Messages.getString("TomcatManagerImpl.130"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
432            connectorAttributes.add(new ConnectorAttribute<Integer>("maxThreads", 40, Messages.getString("TomcatManagerImpl.132"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
433            connectorAttributes.add(new ConnectorAttribute<Integer>("minSpareThreads", 10, Messages.getString("TomcatManagerImpl.134"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
434            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSpareThreads", 100, Messages.getString("TomcatManagerImpl.136"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
435            connectorAttributes.add(new ConnectorAttribute<String>("noCompressionUserAgents", "", Messages.getString("TomcatManagerImpl.139"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
436            connectorAttributes.add(new ConnectorAttribute<Integer>("port", 8080, Messages.getString("TomcatManagerImpl.141"), Integer.class, true)); //$NON-NLS-1$ //$NON-NLS-2$
437            connectorAttributes.add(new ConnectorAttribute<String>("restrictedUserAgents", "", Messages.getString("TomcatManagerImpl.144"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
438            connectorAttributes.add(new ConnectorAttribute<String>("server", "", Messages.getString("TomcatManagerImpl.147"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
439            connectorAttributes.add(new ConnectorAttribute<Integer>("socketBuffer", 9000, Messages.getString("TomcatManagerImpl.149"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
440            connectorAttributes.add(new ConnectorAttribute<Boolean>("tcpNoDelay", true, Messages.getString("TomcatManagerImpl.151"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
441            connectorAttributes.add(new ConnectorAttribute<Integer>("threadPriority", Thread.NORM_PRIORITY, Messages.getString("TomcatManagerImpl.153"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
442        }
443        
444        // see http://tomcat.apache.org/tomcat-6.0-doc/config/http.html
445        private static void addSslConnectorAttributes(List<ConnectorAttribute> connectorAttributes) {
446            connectorAttributes.add(new ConnectorAttribute<String>("algorithm", KeyManagerFactory.getDefaultAlgorithm(), Messages.getString("TomcatManagerImpl.155"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$
447            connectorAttributes.add(new ConnectorAttribute<Boolean>("clientAuth", false, Messages.getString("TomcatManagerImpl.157"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
448            connectorAttributes.add(new ConnectorAttribute<String>("keystoreFile", "", Messages.getString("TomcatManagerImpl.160"), String.class, true)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
449            connectorAttributes.add(new ConnectorAttribute<String>("keystorePass", null, Messages.getString("TomcatManagerImpl.162"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$
450            connectorAttributes.add(new ConnectorAttribute<String>("keystoreType", KeystoreUtil.defaultType, Messages.getString("TomcatManagerImpl.165"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
451            connectorAttributes.add(new ConnectorAttribute<String>("sslProtocol", "TLS", Messages.getString("TomcatManagerImpl.168"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
452            connectorAttributes.add(new ConnectorAttribute<String>("ciphers", "", Messages.getString("TomcatManagerImpl.171"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
453            connectorAttributes.add(new ConnectorAttribute<String>("keyAlias", null, Messages.getString("TomcatManagerImpl.173"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$
454            connectorAttributes.add(new ConnectorAttribute<String>("truststoreFile", null, Messages.getString("TomcatManagerImpl.175"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$
455            connectorAttributes.add(new ConnectorAttribute<String>("truststorePass", null, Messages.getString("TomcatManagerImpl.177"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$
456            connectorAttributes.add(new ConnectorAttribute<String>("truststoreType", KeystoreUtil.defaultType, Messages.getString("TomcatManagerImpl.179"), String.class)); //$NON-NLS-1$ //$NON-NLS-2$
457        }
458        
459        // see http://tomcat.apache.org/tomcat-6.0-doc/config/http.html
460        private static void addNioConnectorAttributes(List<ConnectorAttribute> connectorAttributes) {
461            connectorAttributes.add(new ConnectorAttribute<Boolean>("useSendfile", true, Messages.getString("TomcatManagerImpl.181"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
462            connectorAttributes.add(new ConnectorAttribute<Boolean>("useExecutor", true, Messages.getString("TomcatManagerImpl.183"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
463            connectorAttributes.add(new ConnectorAttribute<Integer>("acceptorThreadCount", 1, Messages.getString("TomcatManagerImpl.185"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
464            connectorAttributes.add(new ConnectorAttribute<Integer>("pollerThreadCount", 1, Messages.getString("TomcatManagerImpl.187"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
465            connectorAttributes.add(new ConnectorAttribute<Integer>("pollerThreadPriority", Thread.NORM_PRIORITY, Messages.getString("TomcatManagerImpl.189"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
466            connectorAttributes.add(new ConnectorAttribute<Integer>("acceptorThreadPriority", Thread.NORM_PRIORITY, Messages.getString("TomcatManagerImpl.191"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
467            connectorAttributes.add(new ConnectorAttribute<Integer>("selectorTimeout", 1000, Messages.getString("TomcatManagerImpl.193"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
468            connectorAttributes.add(new ConnectorAttribute<Boolean>("useComet", true, Messages.getString("TomcatManagerImpl.195"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
469            connectorAttributes.add(new ConnectorAttribute<Integer>("processCache", 200, Messages.getString("TomcatManagerImpl.197"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
470            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_directBuffer", false, Messages.getString("TomcatManagerImpl.199"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
471            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_rxBufSize", 25188, Messages.getString("TomcatManagerImpl.201"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
472            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_txBufSize", 43800, Messages.getString("TomcatManagerImpl.203"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
473            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_appReadBufSize", 8192, Messages.getString("TomcatManagerImpl.205"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
474            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_appWriteBufSize", 8192, Messages.getString("TomcatManagerImpl.207"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
475            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_bufferPool", 500, Messages.getString("TomcatManagerImpl.209"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
476            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_bufferPoolSize", 104857600, Messages.getString("TomcatManagerImpl.211"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
477            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_processorCache", 500, Messages.getString("TomcatManagerImpl.213"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
478            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_keyCache", 500, Messages.getString("TomcatManagerImpl.215"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
479            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_eventCache", 500, Messages.getString("TomcatManagerImpl.217"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
480            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_tcpNoDelay", false, Messages.getString("TomcatManagerImpl.219"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
481            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_soKeepAlive", false, Messages.getString("TomcatManagerImpl.221"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
482            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_ooBInline", true, Messages.getString("TomcatManagerImpl.223"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
483            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_soReuseAddress", true, Messages.getString("TomcatManagerImpl.225"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
484            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_soLingerOn", true, Messages.getString("TomcatManagerImpl.227"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
485            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_soLingerTime", 25, Messages.getString("TomcatManagerImpl.229"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
486            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_soTimeout", 5000, Messages.getString("TomcatManagerImpl.231"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
487            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_soTrafficClass", (0x04 | 0x08 | 0x010), Messages.getString("TomcatManagerImpl.233"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
488            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_performanceConnectionTime", 1, Messages.getString("TomcatManagerImpl.235"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
489            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_performanceLatency", 0, Messages.getString("TomcatManagerImpl.237"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
490            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_performanceBandwidth", 1, Messages.getString("TomcatManagerImpl.239"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
491            connectorAttributes.add(new ConnectorAttribute<Integer>("selectorPool_maxSelectors", 200, Messages.getString("TomcatManagerImpl.241"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
492            connectorAttributes.add(new ConnectorAttribute<Integer>("selectorPool_maxSpareSelectors", -1, Messages.getString("TomcatManagerImpl.243"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
493            connectorAttributes.add(new ConnectorAttribute<Boolean>("command_line_options", true, Messages.getString("TomcatManagerImpl.245"), Boolean.class)); //$NON-NLS-1$ //$NON-NLS-2$
494            connectorAttributes.add(new ConnectorAttribute<Integer>("oomParachute", 1048576, Messages.getString("TomcatManagerImpl.247"), Integer.class)); //$NON-NLS-1$ //$NON-NLS-2$
495        }
496    
497        // http://tomcat.apache.org/tomcat-6.0-doc/apr.html
498        private static void addAprConnectorAttributes(List<ConnectorAttribute> connectorAttributes) {
499            connectorAttributes.add(new ConnectorAttribute<Integer>("pollTime", 2000, Messages.getString("TomcatManagerImpl.249"), Integer.class, true)); //$NON-NLS-1$ //$NON-NLS-2$
500            connectorAttributes.add(new ConnectorAttribute<Integer>("pollerSize", 8192, Messages.getString("TomcatManagerImpl.251"), Integer.class, true)); //$NON-NLS-1$ //$NON-NLS-2$
501            connectorAttributes.add(new ConnectorAttribute<Boolean>("useSendfile", true, Messages.getString("TomcatManagerImpl.253"), Boolean.class, true)); //$NON-NLS-1$ //$NON-NLS-2$
502            connectorAttributes.add(new ConnectorAttribute<Integer>("sendfileSize", 1024, Messages.getString("TomcatManagerImpl.255"), Integer.class, true)); //$NON-NLS-1$ //$NON-NLS-2$
503        }
504           
505        private static <T> void setAttribute (List<ConnectorAttribute> connectorAttributes, String attributeName, T value) {
506            for (ConnectorAttribute connectorAttribute : connectorAttributes) {
507                if (connectorAttribute.getAttributeName().equals(attributeName)) {
508                    connectorAttribute.setValue(value);
509                    return;
510                }
511            }
512        }
513        
514    
515        public ConnectorType getConnectorType(AbstractName connectorName) {
516            ConnectorType connectorType = null; 
517            try {
518                GBeanInfo info = kernel.getGBeanInfo(connectorName);
519                boolean found = false;
520                Set intfs = info.getInterfaces();
521                for (Iterator it = intfs.iterator(); it.hasNext() && !found;) {
522                    String intf = (String) it.next();
523                    if (intf.equals(TomcatWebConnector.class.getName())) {
524                        found = true;
525                    }
526                }
527                if (!found) {
528                    throw new GBeanNotFoundException(connectorName);
529                }
530                String searchingFor = info.getName();
531                for (Entry<ConnectorType, GBeanInfo> entry : CONNECTOR_GBEAN_INFOS.entrySet() ) {
532                    String candidate = entry.getValue().getName();
533                    if (candidate.equals(searchingFor)) {
534                        return entry.getKey();
535                    }
536                }
537            } catch (GBeanNotFoundException e) {
538                log.warn("No such GBean '" + connectorName + "'");
539            } catch (Exception e) {
540                log.error(e);
541            }
542                
543            return connectorType;
544        }
545        
546        public static final GBeanInfo GBEAN_INFO;
547    
548        static {
549            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic("Tomcat Web Manager", TomcatManagerImpl.class);
550            infoFactory.addAttribute("kernel", Kernel.class, false);
551            infoFactory.addInterface(WebManager.class);
552            infoFactory.setConstructor(new String[] {"kernel"});
553            GBEAN_INFO = infoFactory.getBeanInfo();
554        }
555    
556        public static GBeanInfo getGBeanInfo() {
557            return GBEAN_INFO;
558        }
559    
560    }