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    
018    package org.apache.geronimo.jetty6.connector;
019    
020    import java.net.InetAddress;
021    import java.net.InetSocketAddress;
022    import java.net.UnknownHostException;
023    
024    import org.apache.geronimo.gbean.GBeanInfo;
025    import org.apache.geronimo.gbean.GBeanInfoBuilder;
026    import org.apache.geronimo.gbean.GBeanLifecycle;
027    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
028    import org.apache.geronimo.jetty6.JettyContainer;
029    import org.apache.geronimo.jetty6.JettyWebConnector;
030    import org.apache.geronimo.system.threads.ThreadPool;
031    import org.mortbay.jetty.AbstractConnector;
032    
033    /**
034     * Base class for GBeans for Jetty network connectors (HTTP, HTTPS, AJP, etc.).
035     *
036     * @version $Rev: 549825 $ $Date: 2007-06-22 10:17:31 -0400 (Fri, 22 Jun 2007) $
037     */
038    public abstract class JettyConnector implements GBeanLifecycle, JettyWebConnector {
039        public final static String CONNECTOR_CONTAINER_REFERENCE = "JettyContainer";
040        private final JettyContainer container;
041        protected final AbstractConnector listener;
042        private String connectHost;
043    
044        /**
045         * Only used to allow declaration as a reference.
046         */
047        public JettyConnector() {
048            container = null;
049            listener = null;
050        }
051    
052        public JettyConnector(JettyContainer container, ThreadPool threadPool) {
053            this.container = container;
054            this.listener = null;
055        }
056    
057        public JettyConnector(JettyContainer container, AbstractConnector listener, ThreadPool threadPool, String name) {
058            this.container = container;
059            this.listener = listener;
060            if (threadPool != null) {
061                JettyThreadPool jettyThreadPool = new JettyThreadPool(threadPool, name);
062                listener.setThreadPool(jettyThreadPool);
063            }
064        }
065    
066        //TODO: support the jetty6 specific methods
067        public String getHost() {
068            return listener.getHost();
069        }
070    
071        public void setHost(String host) throws UnknownHostException {
072            // underlying impl treats null as 0.0.0.0
073            listener.setHost(host);
074        }
075    
076        public int getPort() {
077            return listener.getPort();
078        }
079    
080        public void setPort(int port) {
081            listener.setPort(port);
082        }
083    
084        public abstract int getDefaultPort();
085    
086        public String getDefaultScheme() {
087            return null;
088        }
089    
090        public String getConnectUrl() {
091            if (connectHost == null) {
092                String host = getHost();
093                if (host == null || host.equals("0.0.0.0")) {
094                    InetAddress address = null;
095                    try {
096                        address = InetAddress.getLocalHost();
097                    } catch (UnknownHostException e) {
098                        host = "unknown-host";
099                    }
100                    if (address != null) {
101                        host = address.getHostName();
102                        if (host == null || host.equals("")) {
103                            host = address.getHostAddress();
104                        }
105                    }
106                }
107                connectHost = host;
108            }
109            return getProtocol().toLowerCase() + "://" + connectHost + (getPort() == getDefaultPort() ? "" : ":" + getPort());
110        }
111    
112        public int getMaxIdleTimeMs() {
113            return listener.getMaxIdleTime();
114        }
115    
116        public void setMaxIdleTimeMs(int idleTime) {
117            listener.setMaxIdleTime(idleTime);
118        }
119    
120        public int getBufferSizeBytes() {
121            //TODO return the request buffer size, what about the response and header buffer size?
122            return listener.getRequestBufferSize();
123        }
124    
125        public void setBufferSizeBytes(int bytes) {
126            //TODO what about the response and header buffer size?
127            listener.setRequestBufferSize(bytes);
128        }
129    
130        public int getAcceptQueueSize() {
131            return listener.getAcceptQueueSize();
132        }
133    
134        public void setAcceptQueueSize(int size) {
135            listener.setAcceptQueueSize(size);
136        }
137    
138        public int getLingerMillis() {
139            return (int) ((AbstractConnector) listener).getSoLingerTime();
140        }
141    
142        public void setLingerMillis(int millis) {
143            listener.setSoLingerTime(millis);
144        }
145    
146        public boolean isTcpNoDelay() {
147            return true;
148        }
149    
150        public void setTcpNoDelay(boolean enable) {
151            throw new UnsupportedOperationException(listener == null ? "No Listener" : listener.getClass().getName());
152        }
153    
154        public void setMaxThreads(int maxThreads) {
155            //TODO: in jetty6 connectors have a number of acceptor threads
156            listener.setAcceptors(maxThreads);
157        }
158    
159        public int getMaxThreads() {
160            //TODO: confirm that this is reasonable
161            return listener.getAcceptors();
162        }
163    
164        public int getRedirectPort() {
165            return listener.getConfidentialPort();
166        }
167    
168        public InetSocketAddress getListenAddress() {
169            try {
170                return new InetSocketAddress(InetAddress.getByName(listener.getHost()), listener.getPort());
171            } catch (UnknownHostException e) {
172                throw new IllegalStateException("InetSocketAddress cannot be determined for host=" + listener.getHost(), e);
173            }
174        }
175    
176    
177        public void setRedirectPort(int port) {
178            throw new UnsupportedOperationException("No redirect port on " + this.getClass().getName());
179        }
180    
181        public abstract String getProtocol();
182    
183        public void doStart() throws Exception {
184            container.addListener(listener);
185            listener.start();
186        }
187    
188        public void doStop() {
189            while (true) {
190                try {
191                    listener.stop();
192                    container.removeListener(listener);
193                    return;
194                } catch (Exception e) {
195                    continue;
196                }
197            }
198        }
199    
200        public void doFail() {
201            while (true) {
202                try {
203                    listener.stop();
204                    container.removeListener(listener);
205                    return;
206                } catch (Exception e) {
207                    continue;
208                }
209            }
210        }
211    
212        public static final GBeanInfo GBEAN_INFO;
213    
214        static {
215            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic("Jetty HTTP Connector", JettyConnector.class);
216            infoFactory.addReference(CONNECTOR_CONTAINER_REFERENCE, JettyContainer.class, NameFactory.GERONIMO_SERVICE);
217            infoFactory.addReference("ThreadPool", ThreadPool.class, NameFactory.GERONIMO_SERVICE);
218            // removed 'minThreads' from persistent and manageable String[]
219            // removed 'tcpNoDelay' from persistent String[]
220            // added 'protocol' to persistent and manageable String[]
221            infoFactory.addInterface(JettyWebConnector.class, new String[]{"host", "port", "minThreads", "maxThreads", "bufferSizeBytes", "acceptQueueSize", "lingerMillis", "protocol", "redirectPort", "connectUrl", "maxIdleTimeMs"},
222                    new String[]{"host", "port", "redirectPort", "maxThreads", "minThreads", "protocol"});
223            infoFactory.setConstructor(new String[]{"JettyContainer", "ThreadPool"});
224            GBEAN_INFO = infoFactory.getBeanInfo();
225        }
226    }