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    
060    /**
061     * Tomcat implementation of the WebManager management API.  Knows how to
062     * manipulate other Tomcat objects for management purposes.
063     *
064     * @version $Rev: 562301 $ $Date: 2007-08-02 20:28:32 -0400 (Thu, 02 Aug 2007) $
065     */
066    public class TomcatManagerImpl implements WebManager {
067        private final static Log log = LogFactory.getLog(TomcatManagerImpl.class);
068        private final Kernel kernel;
069        
070        private static final ConnectorType HTTP_BIO = new ConnectorType("Tomcat BIO HTTP Connector");
071        private static final ConnectorType HTTPS_BIO = new ConnectorType("Tomcat BIO HTTPS Connector");
072        private static final ConnectorType HTTP_NIO = new ConnectorType("Tomcat NIO HTTP Connector");
073        private static final ConnectorType HTTPS_NIO = new ConnectorType("Tomcat NIO HTTPS Connector");
074        private static final ConnectorType HTTP_APR = new ConnectorType("Tomcat APR HTTP Connector");
075        private static final ConnectorType HTTPS_APR = new ConnectorType("Tomcat APR HTTPS Connector");
076        private static final ConnectorType AJP = new ConnectorType("Tomcat AJP Connector");
077        private static List<ConnectorType> CONNECTOR_TYPES = Arrays.asList(
078                HTTP_BIO,
079                HTTPS_BIO,
080                HTTP_NIO,
081                HTTPS_NIO,
082                HTTP_APR,
083                HTTPS_APR,
084                AJP
085        );
086        
087        private static Map<ConnectorType, List<ConnectorAttribute>> CONNECTOR_ATTRIBUTES = new HashMap<ConnectorType, List<ConnectorAttribute>>();
088    
089        static {
090            //******************* HTTP - BIO CONNECTOR
091            List<ConnectorAttribute> connectorAttributes = new ArrayList<ConnectorAttribute>();
092            //HTTP Attributes
093            connectorAttributes.add(new ConnectorAttribute<String>("host", "0.0.0.0", "The host name or IP to bind to. The normal values are 0.0.0.0 (all interfaces) or localhost (local connections only)", String.class, true));
094            connectorAttributes.add(new ConnectorAttribute<Integer>("port", 8080, "The network port to bind to.", Integer.class, true));
095            connectorAttributes.add(new ConnectorAttribute<Integer>("maxThreads", 40, "The maximum number of threads this connector should use to handle incoming requests", Integer.class));
096            connectorAttributes.add(new ConnectorAttribute<Integer>("minSpareThreads", 10, "Minimum spare threads", Integer.class));
097            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSpareThreads", 100, "Maximum spare threads", Integer.class));
098            connectorAttributes.add(new ConnectorAttribute<Integer>("bufferSize", 2048, "Buffer size", Integer.class));
099            connectorAttributes.add(new ConnectorAttribute<Integer>("acceptCount", 10, "acceptCount", Integer.class));
100            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionLinger", -1, "connectionLinger", Integer.class));
101            connectorAttributes.add(new ConnectorAttribute<Boolean>("tcpNoDelay", true, "If set to true, the TCP_NO_DELAY option will be set on the server socket, which improves performance under most circumstances.", Boolean.class));
102            connectorAttributes.add(new ConnectorAttribute<String>("compressableMimeType", "text/html,text/xml,text/plain", "compressableMimeType", String.class));
103            connectorAttributes.add(new ConnectorAttribute<String>("compression", "off", "compression", String.class));
104            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionTimeout", 60000, "Connection timeout in milliseconds", Integer.class));
105            connectorAttributes.add(new ConnectorAttribute<Integer>("keepAliveTimeout", 60000, "Keep alive timeout in milliseconds", Integer.class));
106            connectorAttributes.add(new ConnectorAttribute<Boolean>("disableUploadTimeout", true, "disableUploadTimeout", Boolean.class));
107            connectorAttributes.add(new ConnectorAttribute<Integer>("maxHttpHeaderSize", 4096, "Maximum HTTP header size in bytes", Integer.class));
108            connectorAttributes.add(new ConnectorAttribute<Integer>("maxKeepAliveRequests", 100, "Maximum keep alive requests", Integer.class));
109            connectorAttributes.add(new ConnectorAttribute<String>("noCompressionUserAgents", "", "Comma separated list of regular expressions matching user-agents for which compression should not be used", String.class));
110            connectorAttributes.add(new ConnectorAttribute<String>("restrictedUserAgents", "", "Comma separated list of regular expressions matching user-agents for which which HTTP/1.1 or HTTP/1.0 keep alive should not be used", String.class));
111            connectorAttributes.add(new ConnectorAttribute<String>("server", "", "The Server header for the http response.", String.class));
112            connectorAttributes.add(new ConnectorAttribute<Integer>("socketBuffer", 9000, "The size (in bytes) of the buffer to be provided for socket output buffering", Integer.class));
113            connectorAttributes.add(new ConnectorAttribute<Integer>("threadPriority", Thread.NORM_PRIORITY, "The priority of the request processing threads within the JVM", Integer.class));
114            //Common attributes
115            connectorAttributes.add(new ConnectorAttribute<Boolean>("allowTrace", false, "Used to enable or disable the TRACE HTTP method.", Boolean.class));
116            connectorAttributes.add(new ConnectorAttribute<Boolean>("emptySessionPath", false, "emptySessionPath", Boolean.class));
117            connectorAttributes.add(new ConnectorAttribute<Boolean>("enableLookups", true, "enableLookups", Boolean.class));
118            connectorAttributes.add(new ConnectorAttribute<Integer>("maxPostSize", 2097152, "maxPostSize", Integer.class));
119            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSavePostSize", 4096, "maxSavePostSize", Integer.class));
120            connectorAttributes.add(new ConnectorAttribute<String>("proxyName", null, "proxyName", String.class));
121            connectorAttributes.add(new ConnectorAttribute<Integer>("proxyPort", 0, "proxyPort", Integer.class));
122            connectorAttributes.add(new ConnectorAttribute<Integer>("redirectPort", 8443, "redirectPort", Integer.class));
123            connectorAttributes.add(new ConnectorAttribute<String>("uriEncoding", "ISO-8859-1", "uriEncoding", String.class));
124            connectorAttributes.add(new ConnectorAttribute<Boolean>("useBodyEncodingForURI", false, "useBodyEncodingForURI", Boolean.class));
125            connectorAttributes.add(new ConnectorAttribute<Boolean>("useIPVHosts", false, "useIPVHosts", Boolean.class));
126            connectorAttributes.add(new ConnectorAttribute<Boolean>("xpoweredBy", false, "xpoweredBy", Boolean.class));
127    
128            CONNECTOR_ATTRIBUTES.put(HTTP_BIO, connectorAttributes);
129            
130            //******************* HTTPS - BIO CONNECTOR
131            connectorAttributes = new ArrayList<ConnectorAttribute>();
132            
133            //HTTP Attributes
134            connectorAttributes.add(new ConnectorAttribute<String>("host", "0.0.0.0", "The host name or IP to bind to. The normal values are 0.0.0.0 (all interfaces) or localhost (local connections only)", String.class, true));
135            connectorAttributes.add(new ConnectorAttribute<Integer>("port", 8443, "The network port to bind to.", Integer.class, true));
136            //SSL
137            connectorAttributes.add(new ConnectorAttribute<String>("keystoreFile", "", "The file that holds the keystore (relative to the Geronimo install dir)", String.class, true));
138            connectorAttributes.add(new ConnectorAttribute<String>("keystorePass", null, "Set the password used to access the keystore file. This is also the password used to access the server private key within the keystore (so the two passwords must be set to be the same on the keystore).", String.class));
139            connectorAttributes.add(new ConnectorAttribute<String>("keystoreType", "JKS", "Set the keystore type. There is normally no reason not to use the default (JKS).", String.class));
140            connectorAttributes.add(new ConnectorAttribute<String>("algorithm", KeyManagerFactory.getDefaultAlgorithm(), "Set the HTTPS algorithm. This should normally be set to match the JVM vendor.", String.class));
141            connectorAttributes.add(new ConnectorAttribute<Boolean>("clientAuth", false, "clientAuth", Boolean.class));
142            connectorAttributes.add(new ConnectorAttribute<String>("sslProtocol", "TLS", "Set the HTTPS protocol. This should normally be set to TLS, though some (IBM) JVMs don't work properly with popular browsers unless it is changed to SSL.", String.class));
143            connectorAttributes.add(new ConnectorAttribute<String>("ciphers", "", "Ciphers", String.class));
144            connectorAttributes.add(new ConnectorAttribute<String>("keyAlias", null, "keyAlias", String.class));
145            connectorAttributes.add(new ConnectorAttribute<String>("truststoreFile", null, "The file that holds the truststore (relative to the Geronimo install dir)", String.class));
146            connectorAttributes.add(new ConnectorAttribute<String>("truststorePass", null, "truststorePass", String.class));
147            connectorAttributes.add(new ConnectorAttribute<String>("truststoreType", null, "Set the truststore type. There is normally no reason not to use the default (JKS).", String.class));
148            //HTTP
149            connectorAttributes.add(new ConnectorAttribute<Integer>("maxThreads", 40, "The maximum number of threads this connector should use to handle incoming requests", Integer.class));
150            connectorAttributes.add(new ConnectorAttribute<Integer>("minSpareThreads", 10, "Minimum spare threads", Integer.class));
151            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSpareThreads", 100, "Maximum spare threads", Integer.class));
152            connectorAttributes.add(new ConnectorAttribute<Integer>("bufferSize", 2048, "Buffer size", Integer.class));
153            connectorAttributes.add(new ConnectorAttribute<Integer>("acceptCount", 10, "acceptCount", Integer.class));
154            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionLinger", -1, "connectionLinger", Integer.class));
155            connectorAttributes.add(new ConnectorAttribute<Boolean>("tcpNoDelay", true, "If set to true, the TCP_NO_DELAY option will be set on the server socket, which improves performance under most circumstances.", Boolean.class));
156            connectorAttributes.add(new ConnectorAttribute<String>("compressableMimeType", "text/html,text/xml,text/plain", "compressableMimeType", String.class));
157            connectorAttributes.add(new ConnectorAttribute<String>("compression", "off", "compression", String.class));
158            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionTimeout", 60000, "Connection timeout in milliseconds", Integer.class));
159            connectorAttributes.add(new ConnectorAttribute<Integer>("keepAliveTimeout", 60000, "Keep alive timeout in milliseconds", Integer.class));
160            connectorAttributes.add(new ConnectorAttribute<Boolean>("disableUploadTimeout", true, "disableUploadTimeout", Boolean.class));
161            connectorAttributes.add(new ConnectorAttribute<Integer>("maxHttpHeaderSize", 4096, "Maximum HTTP header size in bytes", Integer.class));
162            connectorAttributes.add(new ConnectorAttribute<Integer>("maxKeepAliveRequests", 100, "Maximum keep alive requests", Integer.class));
163            connectorAttributes.add(new ConnectorAttribute<String>("noCompressionUserAgents", "", "Comma separated list of regular expressions matching user-agents for which compression should not be used", String.class));
164            connectorAttributes.add(new ConnectorAttribute<String>("restrictedUserAgents", "", "Comma separated list of regular expressions matching user-agents for which which HTTP/1.1 or HTTP/1.0 keep alive should not be used", String.class));
165            connectorAttributes.add(new ConnectorAttribute<String>("restrictedUserAgents", "", "Comma separated list of regular expressions matching user-agents for which which HTTP/1.1 or HTTP/1.0 keep alive should not be used", String.class));
166            connectorAttributes.add(new ConnectorAttribute<String>("server", null, "The Server header for the http response.", String.class));
167            connectorAttributes.add(new ConnectorAttribute<Integer>("socketBuffer", 9000, "The size (in bytes) of the buffer to be provided for socket output buffering", Integer.class));
168            connectorAttributes.add(new ConnectorAttribute<Integer>("threadPriority", Thread.NORM_PRIORITY, "The priority of the request processing threads within the JVM", Integer.class));
169            //Common attributes
170            connectorAttributes.add(new ConnectorAttribute<Boolean>("allowTrace", false, "Used to enable or disable the TRACE HTTP method.", Boolean.class));
171            connectorAttributes.add(new ConnectorAttribute<Boolean>("emptySessionPath", false, "emptySessionPath", Boolean.class));
172            connectorAttributes.add(new ConnectorAttribute<Boolean>("enableLookups", true, "enableLookups", Boolean.class));
173            connectorAttributes.add(new ConnectorAttribute<Integer>("maxPostSize", 2097152, "maxPostSize", Integer.class));
174            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSavePostSize", 4096, "maxSavePostSize", Integer.class));
175            connectorAttributes.add(new ConnectorAttribute<String>("proxyName", null, "proxyName", String.class));
176            connectorAttributes.add(new ConnectorAttribute<Integer>("proxyPort", 0, "proxyPort", Integer.class));
177            connectorAttributes.add(new ConnectorAttribute<Integer>("redirectPort", 8443, "redirectPort", Integer.class));
178            connectorAttributes.add(new ConnectorAttribute<String>("uriEncoding", "ISO-8859-1", "uriEncoding", String.class));
179            connectorAttributes.add(new ConnectorAttribute<Boolean>("useBodyEncodingForURI", false, "useBodyEncodingForURI", Boolean.class));
180            connectorAttributes.add(new ConnectorAttribute<Boolean>("useIPVHosts", false, "useIPVHosts", Boolean.class));
181            connectorAttributes.add(new ConnectorAttribute<Boolean>("xpoweredBy", false, "xpoweredBy", Boolean.class));
182            CONNECTOR_ATTRIBUTES.put(HTTPS_BIO, connectorAttributes);
183            
184            //******************* HTTP - NIO CONNECTOR
185            connectorAttributes = new ArrayList<ConnectorAttribute>();
186            //HTTP Attributes
187            connectorAttributes.add(new ConnectorAttribute<String>("host", "0.0.0.0", "The host name or IP to bind to. The normal values are 0.0.0.0 (all interfaces) or localhost (local connections only)", String.class, true));
188            connectorAttributes.add(new ConnectorAttribute<Integer>("port", 8080, "The network port to bind to.", Integer.class, true));
189            connectorAttributes.add(new ConnectorAttribute<Integer>("maxThreads", 40, "The maximum number of threads this connector should use to handle incoming requests", Integer.class));
190            connectorAttributes.add(new ConnectorAttribute<Integer>("minSpareThreads", 10, "Minimum spare threads", Integer.class));
191            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSpareThreads", 100, "Maximum spare threads", Integer.class));
192            connectorAttributes.add(new ConnectorAttribute<Integer>("bufferSize", 2048, "Buffer size", Integer.class));
193            connectorAttributes.add(new ConnectorAttribute<Integer>("acceptCount", 10, "acceptCount", Integer.class));
194            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionLinger", -1, "connectionLinger", Integer.class));
195            connectorAttributes.add(new ConnectorAttribute<Boolean>("tcpNoDelay", true, "If set to true, the TCP_NO_DELAY option will be set on the server socket, which improves performance under most circumstances.", Boolean.class));
196            connectorAttributes.add(new ConnectorAttribute<String>("compressableMimeType", "text/html,text/xml,text/plain", "compressableMimeType", String.class));
197            connectorAttributes.add(new ConnectorAttribute<String>("compression", "off", "compression", String.class));
198            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionTimeout", 60000, "Connection timeout in milliseconds", Integer.class));
199            connectorAttributes.add(new ConnectorAttribute<Integer>("keepAliveTimeout", 60000, "Keep alive timeout in milliseconds", Integer.class));
200            connectorAttributes.add(new ConnectorAttribute<Boolean>("disableUploadTimeout", true, "disableUploadTimeout", Boolean.class));
201            connectorAttributes.add(new ConnectorAttribute<Integer>("maxHttpHeaderSize", 4096, "Maximum HTTP header size in bytes", Integer.class));
202            connectorAttributes.add(new ConnectorAttribute<Integer>("maxKeepAliveRequests", 100, "Maximum keep alive requests", Integer.class));
203            connectorAttributes.add(new ConnectorAttribute<String>("noCompressionUserAgents", "", "Comma separated list of regular expressions matching user-agents for which compression should not be used", String.class));
204            connectorAttributes.add(new ConnectorAttribute<String>("restrictedUserAgents", "", "Comma separated list of regular expressions matching user-agents for which which HTTP/1.1 or HTTP/1.0 keep alive should not be used", String.class));
205            connectorAttributes.add(new ConnectorAttribute<String>("restrictedUserAgents", "", "Comma separated list of regular expressions matching user-agents for which which HTTP/1.1 or HTTP/1.0 keep alive should not be used", String.class));
206            connectorAttributes.add(new ConnectorAttribute<String>("server", null, "The Server header for the http response.", String.class));
207            connectorAttributes.add(new ConnectorAttribute<Integer>("socketBuffer", 9000, "The size (in bytes) of the buffer to be provided for socket output buffering", Integer.class));
208            connectorAttributes.add(new ConnectorAttribute<Integer>("threadPriority", Thread.NORM_PRIORITY, "The priority of the request processing threads within the JVM", Integer.class));
209            //Common attributes
210            connectorAttributes.add(new ConnectorAttribute<Boolean>("allowTrace", false, "Used to enable or disable the TRACE HTTP method.", Boolean.class));
211            connectorAttributes.add(new ConnectorAttribute<Boolean>("emptySessionPath", false, "emptySessionPath", Boolean.class));
212            connectorAttributes.add(new ConnectorAttribute<Boolean>("enableLookups", true, "enableLookups", Boolean.class));
213            connectorAttributes.add(new ConnectorAttribute<Integer>("maxPostSize", 2097152, "maxPostSize", Integer.class));
214            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSavePostSize", 4096, "maxSavePostSize", Integer.class));
215            connectorAttributes.add(new ConnectorAttribute<String>("proxyName", null, "proxyName", String.class));
216            connectorAttributes.add(new ConnectorAttribute<Integer>("proxyPort", 0, "proxyPort", Integer.class));
217            connectorAttributes.add(new ConnectorAttribute<Integer>("redirectPort", 8443, "redirectPort", Integer.class));
218            connectorAttributes.add(new ConnectorAttribute<String>("uriEncoding", "ISO-8859-1", "uriEncoding", String.class));
219            connectorAttributes.add(new ConnectorAttribute<Boolean>("useBodyEncodingForURI", false, "useBodyEncodingForURI", Boolean.class));
220            connectorAttributes.add(new ConnectorAttribute<Boolean>("useIPVHosts", false, "useIPVHosts", Boolean.class));
221            connectorAttributes.add(new ConnectorAttribute<Boolean>("xpoweredBy", false, "xpoweredBy", Boolean.class));
222            //NIO Attributes        
223            connectorAttributes.add(new ConnectorAttribute<Boolean>("useSendfile", true, "useSendfile", Boolean.class));
224            connectorAttributes.add(new ConnectorAttribute<Boolean>("useExecutor", true, "useExecutor", Boolean.class));
225            connectorAttributes.add(new ConnectorAttribute<Integer>("acceptorThreadCount", 1, "acceptorThreadCount", Integer.class));
226            connectorAttributes.add(new ConnectorAttribute<Integer>("pollerThreadCount", 1, "pollerThreadCount", Integer.class));
227            connectorAttributes.add(new ConnectorAttribute<Integer>("pollerThreadPriority", Thread.NORM_PRIORITY, "pollerThreadPriority", Integer.class));
228            connectorAttributes.add(new ConnectorAttribute<Integer>("acceptorThreadPriority", Thread.NORM_PRIORITY, "acceptorThreadPriority", Integer.class));
229            connectorAttributes.add(new ConnectorAttribute<Integer>("selectorTimeout", 1000, "selectorTimeout", Integer.class));
230            connectorAttributes.add(new ConnectorAttribute<Boolean>("useComet", true, "useComet", Boolean.class));
231            connectorAttributes.add(new ConnectorAttribute<Integer>("processCache", 200, "processCache", Integer.class));
232            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_directBuffer", false, "socket_directBuffer", Boolean.class));
233            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_rxBufSize", 25188, "socket_rxBufSize", Integer.class));
234            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_txBufSize", 43800, "socket_txBufSize", Integer.class));
235            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_appReadBufSize", 8192, "socket_appReadBufSize", Integer.class));
236            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_appWriteBufSize", 8192, "socket_appWriteBufSize", Integer.class));
237            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_processorCache", 500, "socket_processorCache", Integer.class));
238            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_bufferPoolSize", 104857600, "socket_bufferPoolSize", Integer.class));
239            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_keyCache", 500, "socket_keyCache", Integer.class));
240            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_eventCache", 500, "socket_eventCache", Integer.class));
241            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_tcpNoDelay", false, "socket_tcpNoDelay", Boolean.class));
242            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_soKeepAlive", false, "socket_soKeepAlive", Boolean.class));
243            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_ooBInline", true, "socket_ooBInline", Boolean.class));
244            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_soReuseAddress", false, "socket_soReuseAddress", Boolean.class));
245            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_soLingerOn", true, "socket_soLingerOn", Boolean.class));
246            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_soLingerTime", 25, "socket_soLingerTime", Integer.class));
247            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_soTimeout", 5000, "socket_soTimeout", Integer.class));
248            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_soTrafficClass", (0x04 | 0x08 | 0x010), "socket_soTrafficClass", Integer.class));
249            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_performanceConnectionTime", 1, "socket_performanceConnectionTime", Integer.class));
250            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_performanceLatency", 0, "socket_performanceLatency", Integer.class));
251            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_performanceBandwidth", 1, "socket_performanceBandwidth", Integer.class));
252            connectorAttributes.add(new ConnectorAttribute<Integer>("selectorPool_maxSelectors", 200, "selectorPool_maxSelectors", Integer.class));
253            connectorAttributes.add(new ConnectorAttribute<Integer>("selectorPool_maxSpareSelectors", -1, "selectorPool_maxSpareSelectors", Integer.class));
254            connectorAttributes.add(new ConnectorAttribute<Boolean>("command_line_options", true, "command_line_options", Boolean.class));
255            connectorAttributes.add(new ConnectorAttribute<Integer>("oomParachute", 1048576, "oomParachute", Integer.class));
256            CONNECTOR_ATTRIBUTES.put(HTTP_NIO, connectorAttributes);
257            
258            //******************* HTTPS - NIO CONNECTOR
259            connectorAttributes = new ArrayList<ConnectorAttribute>();
260            //HTTP Attributes
261            connectorAttributes.add(new ConnectorAttribute<String>("host", "0.0.0.0", "The host name or IP to bind to. The normal values are 0.0.0.0 (all interfaces) or localhost (local connections only)", String.class, true));
262            connectorAttributes.add(new ConnectorAttribute<Integer>("port", 8443, "The network port to bind to.", Integer.class, true));
263            //SSL
264            connectorAttributes.add(new ConnectorAttribute<String>("keystoreFile", "", "The file that holds the keystore (relative to the Geronimo install dir)", String.class, true));
265            connectorAttributes.add(new ConnectorAttribute<String>("keystorePass", null, "Set the password used to access the keystore file. This is also the password used to access the server private key within the keystore (so the two passwords must be set to be the same on the keystore).", String.class));
266            connectorAttributes.add(new ConnectorAttribute<String>("keystoreType", "JKS", "Set the keystore type. There is normally no reason not to use the default (JKS).", String.class));
267            connectorAttributes.add(new ConnectorAttribute<String>("algorithm", KeyManagerFactory.getDefaultAlgorithm(), "Set the HTTPS algorithm. This should normally be set to match the JVM vendor.", String.class));
268            connectorAttributes.add(new ConnectorAttribute<Boolean>("clientAuth", false, "clientAuth", Boolean.class));
269            connectorAttributes.add(new ConnectorAttribute<String>("sslProtocol", "TLS", "Set the HTTPS protocol. This should normally be set to TLS, though some (IBM) JVMs don't work properly with popular browsers unless it is changed to SSL.", String.class));
270            connectorAttributes.add(new ConnectorAttribute<String>("ciphers", "", "Ciphers", String.class));
271            connectorAttributes.add(new ConnectorAttribute<String>("keyAlias", null, "keyAlias", String.class));
272            connectorAttributes.add(new ConnectorAttribute<String>("truststoreFile", null, "The file that holds the truststore (relative to the Geronimo install dir)", String.class));
273            connectorAttributes.add(new ConnectorAttribute<String>("truststorePass", null, "truststorePass", String.class));
274            connectorAttributes.add(new ConnectorAttribute<String>("truststoreType", null, "Set the truststore type. There is normally no reason not to use the default (JKS).", String.class));
275    
276            connectorAttributes.add(new ConnectorAttribute<Integer>("maxThreads", 40, "The maximum number of threads this connector should use to handle incoming requests", Integer.class));
277            connectorAttributes.add(new ConnectorAttribute<Integer>("minSpareThreads", 10, "Minimum spare threads", Integer.class));
278            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSpareThreads", 100, "Maximum spare threads", Integer.class));
279            connectorAttributes.add(new ConnectorAttribute<Integer>("bufferSize", 2048, "Buffer size", Integer.class));
280            connectorAttributes.add(new ConnectorAttribute<Integer>("acceptCount", 10, "acceptCount", Integer.class));
281            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionLinger", -1, "connectionLinger", Integer.class));
282            connectorAttributes.add(new ConnectorAttribute<Boolean>("tcpNoDelay", true, "If set to true, the TCP_NO_DELAY option will be set on the server socket, which improves performance under most circumstances.", Boolean.class));
283            connectorAttributes.add(new ConnectorAttribute<String>("compressableMimeType", "text/html,text/xml,text/plain", "compressableMimeType", String.class));
284            connectorAttributes.add(new ConnectorAttribute<String>("compression", "off", "compression", String.class));
285            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionTimeout", 60000, "Connection timeout in milliseconds", Integer.class));
286            connectorAttributes.add(new ConnectorAttribute<Integer>("keepAliveTimeout", 60000, "Keep alive timeout in milliseconds", Integer.class));
287            connectorAttributes.add(new ConnectorAttribute<Boolean>("disableUploadTimeout", true, "disableUploadTimeout", Boolean.class));
288            connectorAttributes.add(new ConnectorAttribute<Integer>("maxHttpHeaderSize", 4096, "Maximum HTTP header size in bytes", Integer.class));
289            connectorAttributes.add(new ConnectorAttribute<Integer>("maxKeepAliveRequests", 100, "Maximum keep alive requests", Integer.class));
290            connectorAttributes.add(new ConnectorAttribute<String>("noCompressionUserAgents", "", "Comma separated list of regular expressions matching user-agents for which compression should not be used", String.class));
291            connectorAttributes.add(new ConnectorAttribute<String>("restrictedUserAgents", "", "Comma separated list of regular expressions matching user-agents for which which HTTP/1.1 or HTTP/1.0 keep alive should not be used", String.class));
292            connectorAttributes.add(new ConnectorAttribute<String>("restrictedUserAgents", "", "Comma separated list of regular expressions matching user-agents for which which HTTP/1.1 or HTTP/1.0 keep alive should not be used", String.class));
293            connectorAttributes.add(new ConnectorAttribute<String>("server", null, "The Server header for the http response.", String.class));
294            connectorAttributes.add(new ConnectorAttribute<Integer>("socketBuffer", 9000, "The size (in bytes) of the buffer to be provided for socket output buffering", Integer.class));
295            connectorAttributes.add(new ConnectorAttribute<Integer>("threadPriority", Thread.NORM_PRIORITY, "The priority of the request processing threads within the JVM", Integer.class));
296            //Common attributes
297            connectorAttributes.add(new ConnectorAttribute<Boolean>("allowTrace", false, "Used to enable or disable the TRACE HTTP method.", Boolean.class));
298            connectorAttributes.add(new ConnectorAttribute<Boolean>("emptySessionPath", false, "emptySessionPath", Boolean.class));
299            connectorAttributes.add(new ConnectorAttribute<Boolean>("enableLookups", true, "enableLookups", Boolean.class));
300            connectorAttributes.add(new ConnectorAttribute<Integer>("maxPostSize", 2097152, "maxPostSize", Integer.class));
301            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSavePostSize", 4096, "maxSavePostSize", Integer.class));
302            connectorAttributes.add(new ConnectorAttribute<String>("proxyName", null, "proxyName", String.class));
303            connectorAttributes.add(new ConnectorAttribute<Integer>("proxyPort", 0, "proxyPort", Integer.class));
304            connectorAttributes.add(new ConnectorAttribute<Integer>("redirectPort", 8443, "redirectPort", Integer.class));
305            connectorAttributes.add(new ConnectorAttribute<String>("uriEncoding", "ISO-8859-1", "uriEncoding", String.class));
306            connectorAttributes.add(new ConnectorAttribute<Boolean>("useBodyEncodingForURI", false, "useBodyEncodingForURI", Boolean.class));
307            connectorAttributes.add(new ConnectorAttribute<Boolean>("useIPVHosts", false, "useIPVHosts", Boolean.class));
308            connectorAttributes.add(new ConnectorAttribute<Boolean>("xpoweredBy", false, "xpoweredBy", Boolean.class));
309            //NIO Attributes        
310            connectorAttributes.add(new ConnectorAttribute<Boolean>("useSendfile", true, "useSendfile", Boolean.class));
311            connectorAttributes.add(new ConnectorAttribute<Boolean>("useExecutor", true, "useExecutor", Boolean.class));
312            connectorAttributes.add(new ConnectorAttribute<Integer>("acceptorThreadCount", 1, "acceptorThreadCount", Integer.class));
313            connectorAttributes.add(new ConnectorAttribute<Integer>("pollerThreadCount", 1, "pollerThreadCount", Integer.class));
314            connectorAttributes.add(new ConnectorAttribute<Integer>("pollerThreadPriority", Thread.NORM_PRIORITY, "pollerThreadPriority", Integer.class));
315            connectorAttributes.add(new ConnectorAttribute<Integer>("acceptorThreadPriority", Thread.NORM_PRIORITY, "acceptorThreadPriority", Integer.class));
316            connectorAttributes.add(new ConnectorAttribute<Integer>("selectorTimeout", 1000, "selectorTimeout", Integer.class));
317            connectorAttributes.add(new ConnectorAttribute<Boolean>("useComet", true, "useComet", Boolean.class));
318            connectorAttributes.add(new ConnectorAttribute<Integer>("processCache", 200, "processCache", Integer.class));
319            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_directBuffer", false, "socket_directBuffer", Boolean.class));
320            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_rxBufSize", 25188, "socket_rxBufSize", Integer.class));
321            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_txBufSize", 43800, "socket_txBufSize", Integer.class));
322            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_appReadBufSize", 8192, "socket_appReadBufSize", Integer.class));
323            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_appWriteBufSize", 8192, "socket_appWriteBufSize", Integer.class));
324            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_processorCache", 500, "socket_processorCache", Integer.class));
325            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_bufferPoolSize", 104857600, "socket_bufferPoolSize", Integer.class));
326            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_keyCache", 500, "socket_keyCache", Integer.class));
327            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_eventCache", 500, "socket_eventCache", Integer.class));
328            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_tcpNoDelay", false, "socket_tcpNoDelay", Boolean.class));
329            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_soKeepAlive", false, "socket_soKeepAlive", Boolean.class));
330            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_ooBInline", true, "socket_ooBInline", Boolean.class));
331            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_soReuseAddress", false, "socket_soReuseAddress", Boolean.class));
332            connectorAttributes.add(new ConnectorAttribute<Boolean>("socket_soLingerOn", true, "socket_soLingerOn", Boolean.class));
333            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_soLingerTime", 25, "socket_soLingerTime", Integer.class));
334            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_soTimeout", 5000, "socket_soTimeout", Integer.class));
335            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_soTrafficClass", (0x04 | 0x08 | 0x010), "socket_soTrafficClass", Integer.class));
336            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_performanceConnectionTime", 1, "socket_performanceConnectionTime", Integer.class));
337            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_performanceLatency", 0, "socket_performanceLatency", Integer.class));
338            connectorAttributes.add(new ConnectorAttribute<Integer>("socket_performanceBandwidth", 1, "socket_performanceBandwidth", Integer.class));
339            connectorAttributes.add(new ConnectorAttribute<Integer>("selectorPool_maxSelectors", 200, "selectorPool_maxSelectors", Integer.class));
340            connectorAttributes.add(new ConnectorAttribute<Integer>("selectorPool_maxSpareSelectors", -1, "selectorPool_maxSpareSelectors", Integer.class));
341            connectorAttributes.add(new ConnectorAttribute<Boolean>("command_line_options", true, "command_line_options", Boolean.class));
342            connectorAttributes.add(new ConnectorAttribute<Integer>("oomParachute", 1048576, "oomParachute", Integer.class));
343            CONNECTOR_ATTRIBUTES.put(HTTPS_NIO, connectorAttributes);
344            
345            //******************* HTTP - APR CONNECTOR
346            connectorAttributes = new ArrayList<ConnectorAttribute>();        
347            connectorAttributes.add(new ConnectorAttribute<String>("host", "0.0.0.0", "The host name or IP to bind to. The normal values are 0.0.0.0 (all interfaces) or localhost (local connections only)", String.class, true));
348            connectorAttributes.add(new ConnectorAttribute<Integer>("port", 8080, "The network port to bind to.", Integer.class, true));
349            //APR Attributes
350            connectorAttributes.add(new ConnectorAttribute<Integer>("pollTime", 2000, "Duration of a poll call. Lowering this value will slightly decrease latency of connections being kept alive in some cases, but will use more CPU as more poll calls are being made.", Integer.class, true));
351            connectorAttributes.add(new ConnectorAttribute<Integer>("pollerSize", 8192, "Amount of sockets that the poller responsible for polling kept alive connections can hold at a given time.", Integer.class, true));
352            connectorAttributes.add(new ConnectorAttribute<Boolean>("useSendfile", true, "Use kernel level sendfile for certain static files.", Boolean.class, true));
353            connectorAttributes.add(new ConnectorAttribute<Integer>("sendfileSize", 1024, "Amount of sockets that the poller responsible for sending static files asynchronously can hold at a given time.", Integer.class, true));
354            //HTTP
355            connectorAttributes.add(new ConnectorAttribute<Integer>("maxThreads", 40, "The maximum number of threads this connector should use to handle incoming requests", Integer.class));
356            connectorAttributes.add(new ConnectorAttribute<Integer>("minSpareThreads", 10, "Minimum spare threads", Integer.class));
357            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSpareThreads", 100, "Maximum spare threads", Integer.class));
358            connectorAttributes.add(new ConnectorAttribute<Integer>("bufferSize", 2048, "Buffer size", Integer.class));
359            connectorAttributes.add(new ConnectorAttribute<Integer>("acceptCount", 10, "acceptCount", Integer.class));
360            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionLinger", -1, "connectionLinger", Integer.class));
361            connectorAttributes.add(new ConnectorAttribute<Boolean>("tcpNoDelay", true, "If set to true, the TCP_NO_DELAY option will be set on the server socket, which improves performance under most circumstances.", Boolean.class));
362            connectorAttributes.add(new ConnectorAttribute<String>("compressableMimeType", "text/html,text/xml,text/plain", "compressableMimeType", String.class));
363            connectorAttributes.add(new ConnectorAttribute<String>("compression", "off", "compression", String.class));
364            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionTimeout", 60000, "Connection timeout in milliseconds", Integer.class));
365            connectorAttributes.add(new ConnectorAttribute<Integer>("keepAliveTimeout", 60000, "Keep alive timeout in milliseconds", Integer.class));
366            connectorAttributes.add(new ConnectorAttribute<Boolean>("disableUploadTimeout", true, "disableUploadTimeout", Boolean.class));
367            connectorAttributes.add(new ConnectorAttribute<Integer>("maxHttpHeaderSize", 4096, "Maximum HTTP header size in bytes", Integer.class));
368            connectorAttributes.add(new ConnectorAttribute<Integer>("maxKeepAliveRequests", 100, "Maximum keep alive requests", Integer.class));
369            connectorAttributes.add(new ConnectorAttribute<String>("noCompressionUserAgents", "", "Comma separated list of regular expressions matching user-agents for which compression should not be used", String.class));
370            connectorAttributes.add(new ConnectorAttribute<String>("restrictedUserAgents", "", "Comma separated list of regular expressions matching user-agents for which which HTTP/1.1 or HTTP/1.0 keep alive should not be used", String.class));
371            connectorAttributes.add(new ConnectorAttribute<String>("restrictedUserAgents", "", "Comma separated list of regular expressions matching user-agents for which which HTTP/1.1 or HTTP/1.0 keep alive should not be used", String.class));
372            connectorAttributes.add(new ConnectorAttribute<String>("server", null, "The Server header for the http response.", String.class));
373            connectorAttributes.add(new ConnectorAttribute<Integer>("socketBuffer", 9000, "The size (in bytes) of the buffer to be provided for socket output buffering", Integer.class));
374            connectorAttributes.add(new ConnectorAttribute<Integer>("threadPriority", Thread.NORM_PRIORITY, "The priority of the request processing threads within the JVM", Integer.class));
375            //Common attributes
376            connectorAttributes.add(new ConnectorAttribute<Boolean>("allowTrace", false, "Used to enable or disable the TRACE HTTP method.", Boolean.class));
377            connectorAttributes.add(new ConnectorAttribute<Boolean>("emptySessionPath", false, "emptySessionPath", Boolean.class));
378            connectorAttributes.add(new ConnectorAttribute<Boolean>("enableLookups", true, "enableLookups", Boolean.class));
379            connectorAttributes.add(new ConnectorAttribute<Integer>("maxPostSize", 2097152, "maxPostSize", Integer.class));
380            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSavePostSize", 4096, "maxSavePostSize", Integer.class));
381            connectorAttributes.add(new ConnectorAttribute<String>("proxyName", null, "proxyName", String.class));
382            connectorAttributes.add(new ConnectorAttribute<Integer>("proxyPort", 0, "proxyPort", Integer.class));
383            connectorAttributes.add(new ConnectorAttribute<Integer>("redirectPort", 8443, "redirectPort", Integer.class));
384            connectorAttributes.add(new ConnectorAttribute<String>("uriEncoding", "ISO-8859-1", "uriEncoding", String.class));
385            connectorAttributes.add(new ConnectorAttribute<Boolean>("useBodyEncodingForURI", false, "useBodyEncodingForURI", Boolean.class));
386            connectorAttributes.add(new ConnectorAttribute<Boolean>("useIPVHosts", false, "useIPVHosts", Boolean.class));
387            connectorAttributes.add(new ConnectorAttribute<Boolean>("xpoweredBy", false, "xpoweredBy", Boolean.class));
388            CONNECTOR_ATTRIBUTES.put(HTTP_APR, connectorAttributes);
389            
390            //******************* HTTPS - APR CONNECTOR
391            connectorAttributes = new ArrayList<ConnectorAttribute>();
392            connectorAttributes.add(new ConnectorAttribute<String>("host", "0.0.0.0", "The host name or IP to bind to. The normal values are 0.0.0.0 (all interfaces) or localhost (local connections only)", String.class, true));
393            connectorAttributes.add(new ConnectorAttribute<Integer>("port", 8443, "The network port to bind to.", Integer.class, true));
394            //APR Attributes
395            connectorAttributes.add(new ConnectorAttribute<Integer>("pollTime", 2000, "Duration of a poll call. Lowering this value will slightly decrease latency of connections being kept alive in some cases, but will use more CPU as more poll calls are being made.", Integer.class, true));
396            connectorAttributes.add(new ConnectorAttribute<Integer>("pollerSize", 8192, "Amount of sockets that the poller responsible for polling kept alive connections can hold at a given time.", Integer.class, true));
397            connectorAttributes.add(new ConnectorAttribute<Boolean>("useSendfile", true, "Use kernel level sendfile for certain static files.", Boolean.class, true));
398            connectorAttributes.add(new ConnectorAttribute<Integer>("sendfileSize", 1024, "Amount of sockets that the poller responsible for sending static files asynchronously can hold at a given time.", Integer.class, true));
399            //HTTP
400            connectorAttributes.add(new ConnectorAttribute<Integer>("maxThreads", 40, "The maximum number of threads this connector should use to handle incoming requests", Integer.class));
401            connectorAttributes.add(new ConnectorAttribute<Integer>("minSpareThreads", 10, "Minimum spare threads", Integer.class));
402            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSpareThreads", 100, "Maximum spare threads", Integer.class));
403            connectorAttributes.add(new ConnectorAttribute<Integer>("bufferSize", 2048, "Buffer size", Integer.class));
404            connectorAttributes.add(new ConnectorAttribute<Integer>("acceptCount", 10, "acceptCount", Integer.class));
405            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionLinger", -1, "connectionLinger", Integer.class));
406            connectorAttributes.add(new ConnectorAttribute<Boolean>("tcpNoDelay", true, "If set to true, the TCP_NO_DELAY option will be set on the server socket, which improves performance under most circumstances.", Boolean.class));
407            connectorAttributes.add(new ConnectorAttribute<String>("compressableMimeType", "text/html,text/xml,text/plain", "compressableMimeType", String.class));
408            connectorAttributes.add(new ConnectorAttribute<String>("compression", "off", "compression", String.class));
409            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionTimeout", 60000, "Connection timeout in milliseconds", Integer.class));
410            connectorAttributes.add(new ConnectorAttribute<Integer>("keepAliveTimeout", 60000, "Keep alive timeout in milliseconds", Integer.class));
411            connectorAttributes.add(new ConnectorAttribute<Boolean>("disableUploadTimeout", true, "disableUploadTimeout", Boolean.class));
412            connectorAttributes.add(new ConnectorAttribute<Integer>("maxHttpHeaderSize", 4096, "Maximum HTTP header size in bytes", Integer.class));
413            connectorAttributes.add(new ConnectorAttribute<Integer>("maxKeepAliveRequests", 100, "Maximum keep alive requests", Integer.class));
414            connectorAttributes.add(new ConnectorAttribute<String>("noCompressionUserAgents", "", "Comma separated list of regular expressions matching user-agents for which compression should not be used", String.class));
415            connectorAttributes.add(new ConnectorAttribute<String>("restrictedUserAgents", "", "Comma separated list of regular expressions matching user-agents for which which HTTP/1.1 or HTTP/1.0 keep alive should not be used", String.class));
416            connectorAttributes.add(new ConnectorAttribute<String>("restrictedUserAgents", "", "Comma separated list of regular expressions matching user-agents for which which HTTP/1.1 or HTTP/1.0 keep alive should not be used", String.class));
417            connectorAttributes.add(new ConnectorAttribute<String>("server", null, "The Server header for the http response.", String.class));
418            connectorAttributes.add(new ConnectorAttribute<Integer>("socketBuffer", 9000, "The size (in bytes) of the buffer to be provided for socket output buffering", Integer.class));
419            connectorAttributes.add(new ConnectorAttribute<Integer>("threadPriority", Thread.NORM_PRIORITY, "The priority of the request processing threads within the JVM", Integer.class));
420            //Common attributes
421            connectorAttributes.add(new ConnectorAttribute<Boolean>("allowTrace", false, "Used to enable or disable the TRACE HTTP method.", Boolean.class));
422            connectorAttributes.add(new ConnectorAttribute<Boolean>("emptySessionPath", false, "emptySessionPath", Boolean.class));
423            connectorAttributes.add(new ConnectorAttribute<Boolean>("enableLookups", true, "enableLookups", Boolean.class));
424            connectorAttributes.add(new ConnectorAttribute<Integer>("maxPostSize", 2097152, "maxPostSize", Integer.class));
425            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSavePostSize", 4096, "maxSavePostSize", Integer.class));
426            connectorAttributes.add(new ConnectorAttribute<String>("proxyName", null, "proxyName", String.class));
427            connectorAttributes.add(new ConnectorAttribute<Integer>("proxyPort", 0, "proxyPort", Integer.class));
428            connectorAttributes.add(new ConnectorAttribute<Integer>("redirectPort", 8443, "redirectPort", Integer.class));
429            connectorAttributes.add(new ConnectorAttribute<String>("uriEncoding", "ISO-8859-1", "uriEncoding", String.class));
430            connectorAttributes.add(new ConnectorAttribute<Boolean>("useBodyEncodingForURI", false, "useBodyEncodingForURI", Boolean.class));
431            connectorAttributes.add(new ConnectorAttribute<Boolean>("useIPVHosts", false, "useIPVHosts", Boolean.class));
432            connectorAttributes.add(new ConnectorAttribute<Boolean>("xpoweredBy", false, "xpoweredBy", Boolean.class));
433            //APR SSL specific values
434            connectorAttributes.add(new ConnectorAttribute<String>("sslCertificateFile", "", "Name of the file that contains the server certificate. The format is PEM-encoded.", String.class, true));
435            connectorAttributes.add(new ConnectorAttribute<String>("sslPassword", null, "Pass phrase for the encrypted private key.", String.class));
436            connectorAttributes.add(new ConnectorAttribute<String>("sslProtocol", "all", "Protocol which may be used for communicating with clients.", String.class));
437            connectorAttributes.add(new ConnectorAttribute<String>("sslCipherSuite", "ALL", "Ciphers which may be used for communicating with clients.", String.class));
438            connectorAttributes.add(new ConnectorAttribute<String>("sslCertificateKeyFile", null, "Name of the file that contains the server private key.", String.class));
439            connectorAttributes.add(new ConnectorAttribute<String>("sslVerifyClient", "none", "Ask client for certificate.", String.class));
440            connectorAttributes.add(new ConnectorAttribute<Integer>("sslVerifyDepth", 10, "Maximum verification depth for client certificates.", Integer.class));
441            connectorAttributes.add(new ConnectorAttribute<String>("sslCACertificateFile", null, "File of concatenated PEM-encoded CA Certificates for Client Auth.", String.class));
442            connectorAttributes.add(new ConnectorAttribute<String>("sslCACertificatePath", null, "Directory of PEM-encoded CA Certificates for Client Auth.", String.class));
443            connectorAttributes.add(new ConnectorAttribute<String>("sslCertificateChainFile", null, "File of PEM-encoded Server CA Certificates.", String.class));
444            connectorAttributes.add(new ConnectorAttribute<String>("sslCARevocationFile", null, "File of concatenated PEM-encoded CA CRLs for Client Auth.", String.class));
445            connectorAttributes.add(new ConnectorAttribute<String>("sslCARevocationPath", null, "Directory of PEM-encoded CA CRLs for Client Auth.", String.class));
446            CONNECTOR_ATTRIBUTES.put(HTTPS_APR, connectorAttributes);
447            
448            //******************* AJP CONNECTOR
449            connectorAttributes = new ArrayList<ConnectorAttribute>();
450            //APR Attributes
451            connectorAttributes.add(new ConnectorAttribute<String>("host", "0.0.0.0", "The host name or IP to bind to. The normal values are 0.0.0.0 (all interfaces) or localhost (local connections only)", String.class, true));
452            connectorAttributes.add(new ConnectorAttribute<Integer>("port", 8009, "The network port to bind to.", Integer.class, true));
453            connectorAttributes.add(new ConnectorAttribute<Integer>("backlog", 10, "The maximum queue length for incoming connection requests when all possible request processing threads are in use.", Integer.class));
454            connectorAttributes.add(new ConnectorAttribute<Integer>("bufferSize", 2048, "Buffer size", Integer.class));
455            connectorAttributes.add(new ConnectorAttribute<Integer>("connectionTimeout", org.apache.coyote.ajp.Constants.DEFAULT_CONNECTION_TIMEOUT, "Connection timeout in milliseconds", Integer.class));
456            connectorAttributes.add(new ConnectorAttribute<Integer>("keepAliveTimeout", org.apache.coyote.ajp.Constants.DEFAULT_CONNECTION_TIMEOUT, "Keep alive timeout in milliseconds", Integer.class));
457            connectorAttributes.add(new ConnectorAttribute<Integer>("maxThreads", 40, "The maximum number of threads this connector should use to handle incoming requests", Integer.class));
458            connectorAttributes.add(new ConnectorAttribute<Integer>("minSpareThreads", 10, "Minimum spare threads", Integer.class));
459            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSpareThreads", 100, "Maximum spare threads", Integer.class));
460            connectorAttributes.add(new ConnectorAttribute<Boolean>("tcpNoDelay", true, "If set to true, the TCP_NO_DELAY option will be set on the server socket, which improves performance under most circumstances.", Boolean.class));
461            connectorAttributes.add(new ConnectorAttribute<Boolean>("tomcatAuthentication", true, "If set to true, the authetication will be done in Geronimo. Otherwise, the authenticated principal will be propagated from the native webaserver and used for authorization in Geronimo.", Boolean.class));
462            
463            //Common attributes
464            connectorAttributes.add(new ConnectorAttribute<Boolean>("allowTrace", false, "Used to enable or disable the TRACE HTTP method.", Boolean.class));
465            connectorAttributes.add(new ConnectorAttribute<Boolean>("emptySessionPath", false, "emptySessionPath", Boolean.class));
466            connectorAttributes.add(new ConnectorAttribute<Boolean>("enableLookups", true, "enableLookups", Boolean.class));
467            connectorAttributes.add(new ConnectorAttribute<Integer>("maxPostSize", 2097152, "maxPostSize", Integer.class));
468            connectorAttributes.add(new ConnectorAttribute<Integer>("maxSavePostSize", 4096, "maxSavePostSize", Integer.class));
469            connectorAttributes.add(new ConnectorAttribute<String>("proxyName", null, "proxyName", String.class));
470            connectorAttributes.add(new ConnectorAttribute<Integer>("proxyPort", 0, "proxyPort", Integer.class));
471            connectorAttributes.add(new ConnectorAttribute<Integer>("redirectPort", 8443, "redirectPort", Integer.class));
472            connectorAttributes.add(new ConnectorAttribute<String>("uriEncoding", "ISO-8859-1", "uriEncoding", String.class));
473            connectorAttributes.add(new ConnectorAttribute<Boolean>("useBodyEncodingForURI", false, "useBodyEncodingForURI", Boolean.class));
474            connectorAttributes.add(new ConnectorAttribute<Boolean>("useIPVHosts", false, "useIPVHosts", Boolean.class));
475            connectorAttributes.add(new ConnectorAttribute<Boolean>("xpoweredBy", false, "xpoweredBy", Boolean.class));
476            CONNECTOR_ATTRIBUTES.put(AJP, connectorAttributes);
477        }
478        
479        private static Map<ConnectorType, GBeanInfo> CONNECTOR_GBEAN_INFOS = new HashMap<ConnectorType, GBeanInfo>();
480    
481        static {
482            CONNECTOR_GBEAN_INFOS.put(HTTP_BIO, Http11ConnectorGBean.GBEAN_INFO);
483            CONNECTOR_GBEAN_INFOS.put(HTTPS_BIO, Https11ConnectorGBean.GBEAN_INFO);
484            CONNECTOR_GBEAN_INFOS.put(HTTP_NIO, Http11NIOConnectorGBean.GBEAN_INFO);
485            CONNECTOR_GBEAN_INFOS.put(HTTPS_NIO, Https11NIOConnectorGBean.GBEAN_INFO);
486            CONNECTOR_GBEAN_INFOS.put(HTTP_APR, Http11APRConnectorGBean.GBEAN_INFO);
487            CONNECTOR_GBEAN_INFOS.put(HTTPS_APR, Https11APRConnectorGBean.GBEAN_INFO);
488            CONNECTOR_GBEAN_INFOS.put(AJP, AJP13ConnectorGBean.GBEAN_INFO);
489        }
490        
491        public TomcatManagerImpl(Kernel kernel) {
492            this.kernel = kernel;
493        }
494    
495        public String getProductName() {
496            return "Tomcat";
497        }
498    
499        /**
500         * Gets the network containers.
501         */
502        public Object[] getContainers() {
503            ProxyManager proxyManager = kernel.getProxyManager();
504            AbstractNameQuery query = new AbstractNameQuery(TomcatWebContainer.class.getName());
505            Set names = kernel.listGBeans(query);
506            TomcatWebContainer[] results = new TomcatWebContainer[names.size()];
507            int i=0;
508            for (Iterator it = names.iterator(); it.hasNext(); i++) {
509                AbstractName name = (AbstractName) it.next();
510                results[i] = (TomcatWebContainer) proxyManager.createProxy(name, TomcatWebContainer.class.getClassLoader());
511            }
512            return results;
513        }
514    
515        /**
516         * Gets the protocols which this container can configure connectors for.
517         */
518        public String[] getSupportedProtocols() {
519            return new String[]{PROTOCOL_HTTP, PROTOCOL_HTTPS, PROTOCOL_AJP};
520        }
521    
522        /**
523         * Removes a connector.  This shuts it down if necessary, and removes it from the server environment.  It must be a
524         * connector that uses this network technology.
525         * @param connectorName
526         */
527        public void removeConnector(AbstractName connectorName) {
528            try {
529                GBeanInfo info = kernel.getGBeanInfo(connectorName);
530                boolean found = false;
531                Set intfs = info.getInterfaces();
532                for (Iterator it = intfs.iterator(); it.hasNext();) {
533                    String intf = (String) it.next();
534                    if (intf.equals(TomcatWebConnector.class.getName())) {
535                        found = true;
536                    }
537                }
538                if (!found) {
539                    throw new GBeanNotFoundException(connectorName);
540                }
541                EditableConfigurationManager mgr = ConfigurationUtil.getEditableConfigurationManager(kernel);
542                if(mgr != null) {
543                    try {
544                        mgr.removeGBeanFromConfiguration(connectorName.getArtifact(), connectorName);
545                    } catch (InvalidConfigException e) {
546                        log.error("Unable to add GBean", e);
547                    } finally {
548                        ConfigurationUtil.releaseConfigurationManager(kernel, mgr);
549                    }
550                } else {
551                    log.warn("The ConfigurationManager in the kernel does not allow editing");
552                }
553            } catch (GBeanNotFoundException e) {
554                log.warn("No such GBean '" + connectorName + "'"); //todo: what if we want to remove a failed GBean?
555            } catch (Exception e) {
556                log.error(e);
557            }
558        }
559    
560        /**
561         * Gets the ObjectNames of any existing connectors for this network technology for the specified protocol.
562         *
563         * @param protocol A protocol as returned by getSupportedProtocols
564         */
565        public NetworkConnector[] getConnectors(String protocol) {
566            if(protocol == null) {
567                return getConnectors();
568            }
569            List result = new ArrayList();
570            ProxyManager proxyManager = kernel.getProxyManager();
571            AbstractNameQuery query = new AbstractNameQuery(TomcatWebConnector.class.getName());
572            Set names = kernel.listGBeans(query);
573            for (Iterator it = names.iterator(); it.hasNext();) {
574                AbstractName name = (AbstractName) it.next();
575                try {
576                    if (kernel.getAttribute(name, "protocol").equals(protocol)) {
577                        result.add(proxyManager.createProxy(name, TomcatWebConnector.class.getClassLoader()));
578                    }
579                } catch (Exception e) {
580                    log.error("Unable to check the protocol for a connector", e);
581                }
582            }
583            return (TomcatWebConnector[]) result.toArray(new TomcatWebConnector[names.size()]);
584        }
585    
586        public WebAccessLog getAccessLog(WebContainer container) {
587            AbstractNameQuery query = new AbstractNameQuery(TomcatLogManager.class.getName());
588            Set names = kernel.listGBeans(query);
589            if(names.size() == 0) {
590                return null;
591            } else if(names.size() > 1) {
592                throw new IllegalStateException("Should not be more than one Tomcat access log manager");
593            }
594            return (WebAccessLog) kernel.getProxyManager().createProxy((AbstractName)names.iterator().next(), TomcatLogManager.class.getClassLoader());
595        }
596    
597        public List<ConnectorType> getConnectorTypes() {
598            return CONNECTOR_TYPES;
599        }
600    
601        public List<ConnectorAttribute> getConnectorAttributes(ConnectorType connectorType) {
602            return ConnectorAttribute.copy(CONNECTOR_ATTRIBUTES.get(connectorType));
603        }
604    
605        public AbstractName getConnectorConfiguration(ConnectorType connectorType, List<ConnectorAttribute> connectorAttributes, WebContainer container, String uniqueName) {
606            GBeanInfo gbeanInfo = CONNECTOR_GBEAN_INFOS.get(connectorType);
607            AbstractName containerName = kernel.getAbstractNameFor(container);
608            AbstractName name = kernel.getNaming().createSiblingName(containerName, uniqueName, NameFactory.GERONIMO_SERVICE);
609            GBeanData gbeanData = new GBeanData(name, gbeanInfo);
610            gbeanData.setAttribute("name", uniqueName);
611            gbeanData.setReferencePattern(ConnectorGBean.CONNECTOR_CONTAINER_REFERENCE, containerName);
612            for (ConnectorAttribute connectorAttribute : connectorAttributes) {
613                gbeanData.setAttribute(connectorAttribute.getAttributeName(), connectorAttribute.getValue());
614            }
615            AbstractNameQuery query = new AbstractNameQuery(ServerInfo.class.getName());
616            Set set = kernel.listGBeans(query);
617            AbstractName serverInfo = (AbstractName)set.iterator().next();
618            gbeanData.setReferencePattern("ServerInfo", serverInfo);
619    
620            EditableConfigurationManager mgr = ConfigurationUtil.getEditableConfigurationManager(kernel);
621            if (mgr != null) {
622                try {
623                    mgr.addGBeanToConfiguration(containerName.getArtifact(), gbeanData, false);
624                } catch (InvalidConfigException e) {
625                    log.error("Unable to add GBean", e);
626                    return null;
627                } finally {
628                    ConfigurationUtil.releaseConfigurationManager(kernel, mgr);
629                }
630            } else {
631                log.warn("The ConfigurationManager in the kernel does not allow editing");
632                return null;
633            }
634            return name;
635        }
636    
637        /**
638         * Gets the ObjectNames of any existing connectors associated with this network technology.
639         */
640        public NetworkConnector[] getConnectors() {
641            ProxyManager proxyManager = kernel.getProxyManager();
642            AbstractNameQuery query = new AbstractNameQuery(TomcatWebConnector.class.getName());
643            Set names = kernel.listGBeans(query);
644            TomcatWebConnector[] results = new TomcatWebConnector[names.size()];
645            int i=0;
646            for (Iterator it = names.iterator(); it.hasNext(); i++) {
647                AbstractName name = (AbstractName) it.next();
648                results[i] = (TomcatWebConnector) proxyManager.createProxy(name, TomcatWebConnector.class.getClassLoader());
649            }
650            return results;
651        }
652    
653        /**
654         * Gets the ObjectNames of any existing connectors for the specified container for the specified protocol.
655         *
656         * @param protocol A protocol as returned by getSupportedProtocols
657         */
658        public NetworkConnector[] getConnectorsForContainer(Object container, String protocol) {
659            if(protocol == null) {
660                return getConnectorsForContainer(container);
661            }
662            AbstractName containerName = kernel.getAbstractNameFor(container);
663            ProxyManager mgr = kernel.getProxyManager();
664            try {
665                List results = new ArrayList();
666                AbstractNameQuery query = new AbstractNameQuery(TomcatWebConnector.class.getName());
667                Set set = kernel.listGBeans(query); // all Tomcat connectors
668                for (Iterator it = set.iterator(); it.hasNext();) {
669                    AbstractName name = (AbstractName) it.next(); // a single Tomcat connector
670                    GBeanData data = kernel.getGBeanData(name);
671                    ReferencePatterns refs = data.getReferencePatterns(ConnectorGBean.CONNECTOR_CONTAINER_REFERENCE);
672                    if(containerName.equals(refs.getAbstractName())) {
673                        try {
674                            String testProtocol = (String) kernel.getAttribute(name, "protocol");
675                            if(testProtocol != null && testProtocol.equals(protocol)) {
676                                results.add(mgr.createProxy(name, TomcatWebConnector.class.getClassLoader()));
677                            }
678                        } catch (Exception e) {
679                            log.error("Unable to look up protocol for connector '"+name+"'",e);
680                        }
681                        break;
682                    }
683                }
684                return (TomcatWebConnector[]) results.toArray(new TomcatWebConnector[results.size()]);
685            } catch (Exception e) {
686                throw (IllegalArgumentException)new IllegalArgumentException("Unable to look up connectors for Tomcat container '"+containerName +"': ").initCause(e);
687            }
688        }
689    
690        /**
691         * Gets the ObjectNames of any existing connectors for the specified container.
692         */
693        public NetworkConnector[] getConnectorsForContainer(Object container) {
694            AbstractName containerName = kernel.getAbstractNameFor(container);
695            ProxyManager mgr = kernel.getProxyManager();
696            try {
697                List results = new ArrayList();
698                AbstractNameQuery query = new AbstractNameQuery(TomcatWebConnector.class.getName());
699                Set set = kernel.listGBeans(query); // all Tomcat connectors
700                for (Iterator it = set.iterator(); it.hasNext();) {
701                    AbstractName name = (AbstractName) it.next(); // a single Tomcat connector
702                    GBeanData data = kernel.getGBeanData(name);
703                    ReferencePatterns refs = data.getReferencePatterns(ConnectorGBean.CONNECTOR_CONTAINER_REFERENCE);
704                    if (containerName.equals(refs.getAbstractName())) {
705                        results.add(mgr.createProxy(name, TomcatWebConnector.class.getClassLoader()));
706                    }
707                }
708                return (TomcatWebConnector[]) results.toArray(new TomcatWebConnector[results.size()]);
709            } catch (Exception e) {
710                throw (IllegalArgumentException) new IllegalArgumentException("Unable to look up connectors for Tomcat container '"+containerName).initCause(e);
711            }
712        }
713    
714        public static final GBeanInfo GBEAN_INFO;
715    
716        static {
717            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic("Tomcat Web Manager", TomcatManagerImpl.class);
718            infoFactory.addAttribute("kernel", Kernel.class, false);
719            infoFactory.addInterface(WebManager.class);
720            infoFactory.setConstructor(new String[] {"kernel"});
721            GBEAN_INFO = infoFactory.getBeanInfo();
722        }
723    
724        public static GBeanInfo getGBeanInfo() {
725            return GBEAN_INFO;
726        }
727    
728        public ConnectorType getConnectorType(AbstractName connectorName) {
729            ConnectorType connectorType = null; 
730            try {
731                GBeanInfo info = kernel.getGBeanInfo(connectorName);
732                boolean found = false;
733                Set intfs = info.getInterfaces();
734                for (Iterator it = intfs.iterator(); it.hasNext() && !found;) {
735                    String intf = (String) it.next();
736                    if (intf.equals(TomcatWebConnector.class.getName())) {
737                        found = true;
738                    }
739                }
740                if (!found) {
741                    throw new GBeanNotFoundException(connectorName);
742                }
743                String searchingFor = info.getName();
744                for (Entry<ConnectorType, GBeanInfo> entry : CONNECTOR_GBEAN_INFOS.entrySet() ) {
745                    String candidate = entry.getValue().getName();
746                    if (candidate.equals(searchingFor)) {
747                        return entry.getKey();
748                    }
749                }
750            } catch (GBeanNotFoundException e) {
751                log.warn("No such GBean '" + connectorName + "'");
752            } catch (Exception e) {
753                log.error(e);
754            }
755                
756            return connectorType;
757        }
758    }