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;
019    
020    import java.util.HashMap;
021    import java.util.Map;
022    
023    import javax.management.j2ee.statistics.Stats;
024    
025    import org.apache.geronimo.gbean.GBeanInfo;
026    import org.apache.geronimo.gbean.GBeanInfoBuilder;
027    import org.apache.geronimo.gbean.GBeanLifecycle;
028    import org.apache.geronimo.management.StatisticsProvider;
029    import org.apache.geronimo.management.geronimo.NetworkConnector;
030    import org.apache.geronimo.management.geronimo.WebManager;
031    import org.apache.geronimo.webservices.SoapHandler;
032    import org.apache.geronimo.webservices.WebServiceContainer;
033    import org.mortbay.jetty.Connector;
034    import org.mortbay.jetty.Handler;
035    import org.mortbay.jetty.RequestLog;
036    import org.mortbay.jetty.Server;
037    import org.mortbay.jetty.handler.ContextHandler;
038    import org.mortbay.jetty.handler.ContextHandlerCollection;
039    import org.mortbay.jetty.handler.DefaultHandler;
040    import org.mortbay.jetty.handler.HandlerCollection;
041    import org.mortbay.jetty.handler.RequestLogHandler;
042    import org.mortbay.jetty.handler.AbstractHandlerContainer;
043    
044    /**
045     * @version $Rev: 549825 $ $Date: 2007-06-22 10:17:31 -0400 (Fri, 22 Jun 2007) $
046     */
047    public class JettyContainerImpl implements JettyContainer, SoapHandler, GBeanLifecycle, StatisticsProvider {
048        private final Server server;
049        private final Map webServices = new HashMap();
050        private final String objectName;
051        private final WebManager manager;
052        private JettyWebContainerStatsImpl stats;
053        private final Map realms = new HashMap();
054        private HandlerCollection handlerCollection = new HandlerCollection();
055        private ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
056        private DefaultHandler defaultHandler = new DefaultHandler();
057        private RequestLogHandler requestLogHandler = new RequestLogHandler();
058    
059        public JettyContainerImpl(String objectName, WebManager manager) {
060            this.objectName = objectName;
061            server = new JettyServer();
062    
063            //set up the new jetty6 handler structure which is to have a HandlerCollection,
064            //each element of which is always tried on each request.
065            //The first element of the HandlerCollection is a
066            //ContextHandlerCollection, which is itself is a collection
067            //of Handlers. It's special property is that only of it's
068            //handlers will respond to a request.
069            //The second element of the HandlerCollection is a DefaultHandler
070            //which is responsible for serving static content or anything not
071            //handled by a Handler in the ContextHandlerCollection.
072            //The third element is the RequestLogHandler, which requires
073            //a RequestLog impl to be set.
074            Handler[] handlers = new Handler[3];
075            handlers[0] = contextHandlerCollection;
076            handlers[1] = defaultHandler;
077            handlers[2] = requestLogHandler;
078            handlerCollection.setHandlers(handlers);
079            server.setHandler(handlerCollection);
080    
081            stats = new JettyWebContainerStatsImpl();
082            this.manager = manager;
083        }
084    
085        public String getObjectName() {
086            return objectName;
087        }
088    
089        public boolean isStateManageable() {
090            return true;
091        }
092    
093        public boolean isStatisticsProvider() {
094            return true;
095        }
096    
097        public boolean isEventProvider() {
098            return true;
099        }
100    
101        public NetworkConnector[] getConnectors() {
102            return manager.getConnectorsForContainer(this);
103        }
104    
105        public NetworkConnector[] getConnectors(String protocol) {
106            return manager.getConnectorsForContainer(this, protocol);
107        }
108    
109        public void resetStatistics() {
110            //TODO: for jetty6
111        }
112    
113        public void setCollectStatistics(boolean on) {
114            //TODO: for jetty6
115        }
116    
117        public boolean getCollectStatistics() {
118            //TODO: for jetty6
119            return false;
120        }
121    
122        public long getCollectStatisticsStarted() {
123            //TODO: for jetty6
124            return 0L;
125        }
126    
127        public void resetStats() {
128            // TODO 
129        }
130    
131        public Stats getStats() {
132            if (getCollectStatistics()) {
133    
134                /* set active request count */
135    //            stats.getTotalRequestCountImpl().setCount(server.getRequests());
136    
137                /* set total connection count */
138    //            stats.getTotalConnectionCountImpl().setCount(server.getConnections());
139    
140                /* set total error count */
141    //            stats.getTotalErrorCountImpl().setCount(server.getErrors());
142    
143                /* set active request range values */
144    //            stats.getActiveRequestCountImpl().setCurrent(server.getRequestsActive());
145    //            stats.getActiveRequestCountImpl().setLowWaterMark(server.getRequestsActiveMin());
146    //            stats.getActiveRequestCountImpl().setHighWaterMark(server.getRequestsActiveMax());
147    
148                /* set connection requests range values */
149    //          stats.getConnectionRequestCountImpl().setCurrent(server.getConnectionsRequestsCurrent());    // temporarily removed until added by jetty6
150    //            stats.getConnectionRequestCountImpl().setCurrent(server.getConnectionsOpen());
151    //            stats.getConnectionRequestCountImpl().setLowWaterMark(server.getConnectionsRequestsMin());
152    //            stats.getConnectionRequestCountImpl().setHighWaterMark(server.getConnectionsRequestsMax());
153    
154                /* set open connection range values */
155    //            stats.getOpenConnectionCountImpl().setCurrent(server.getConnectionsOpen());
156    //            stats.getOpenConnectionCountImpl().setLowWaterMark(server.getConnectionsOpenMin());
157    //            stats.getOpenConnectionCountImpl().setHighWaterMark(server.getConnectionsOpenMax());
158    
159                /* set request duration time values */
160    //            stats.getRequestDurationImpl().setMinTime(server.getRequestsDurationMin());
161    //            stats.getRequestDurationImpl().setMaxTime(server.getRequestsDurationMax());
162    //          stats.getRequestDurationImpl().setCount(server.getRequestsDurationCount());     // temporarily removed until added by jetty6
163                stats.getRequestDurationImpl().setCount(stats.getTotalRequestCount().getCount());
164    //            stats.getRequestDurationImpl().setTotalTime(server.getRequestsDurationTotal());
165    
166                /* set connection duration Time values */
167    //            stats.getConnectionDurationImpl().setMinTime(server.getConnectionsDurationMin());
168    //            stats.getConnectionDurationImpl().setMaxTime(server.getConnectionsDurationMax());
169    //          stats.getConnectionDurationImpl().setCount(server.getConnectionsDurationCount());    // temporarily removed until added by jetty6
170                stats.getConnectionDurationImpl().setCount(stats.getTotalConnectionCount().getCount());
171    //            stats.getConnectionDurationImpl().setTotalTime(server.getConnectionsDurationTotal());
172    
173            } else {
174                // should probably set the stats object to all zero/null values to avoid unpredicable results
175            }
176            return stats;
177        }
178    
179        public void addListener(Connector listener) {
180            server.addConnector(listener);
181        }
182    
183        public void removeListener(Connector listener) {
184            server.removeConnector(listener);
185        }
186    
187        public void addContext(AbstractHandlerContainer context) {
188            contextHandlerCollection.addHandler(context);
189        }
190    
191        public void removeContext(AbstractHandlerContainer context) {
192            contextHandlerCollection.removeHandler(context);
193        }
194    
195        public InternalJAASJettyRealm addRealm(String realmName) {
196            InternalJAASJettyRealm realm = (InternalJAASJettyRealm) realms.get(realmName);
197            if (realm == null) {
198                realm = new InternalJAASJettyRealm(realmName);
199                realms.put(realmName, realm);
200            } else {
201                realm.addUse();
202            }
203            return realm;
204        }
205    
206        public void removeRealm(String realmName) {
207            InternalJAASJettyRealm realm = (InternalJAASJettyRealm) realms.get(realmName);
208            if (realm != null) {
209                if (realm.removeUse() == 0) {
210                    realms.remove(realmName);
211                }
212            }
213        }
214    
215        public void addWebService(String contextPath, String[] virtualHosts, WebServiceContainer webServiceContainer, String securityRealmName, String realmName, String transportGuarantee, String authMethod, ClassLoader classLoader) throws Exception {
216            InternalJAASJettyRealm internalJAASJettyRealm = securityRealmName == null ? null : addRealm(securityRealmName);
217            JettyEJBWebServiceContext webServiceContext = new JettyEJBWebServiceContext(contextPath, webServiceContainer, internalJAASJettyRealm, realmName, transportGuarantee, authMethod, classLoader);
218            webServiceContext.setVirtualHosts(virtualHosts);
219            addContext(webServiceContext);
220            webServiceContext.start();
221            webServices.put(contextPath, webServiceContext);
222        }
223    
224        public void removeWebService(String contextPath) {
225            JettyEJBWebServiceContext webServiceContext = (JettyEJBWebServiceContext) webServices.remove(contextPath);
226            String securityRealmName = webServiceContext.getSecurityRealmName();
227            if (securityRealmName != null) {
228                removeRealm(securityRealmName);
229            }
230            try {
231                removeContext(webServiceContext);
232            } catch (Exception e) {
233                throw new IllegalStateException(e.getMessage(), e);
234            }
235        }
236    
237        public void setRequestLog(RequestLog log) {
238            this.requestLogHandler.setRequestLog(log);
239        }
240    
241        /* ------------------------------------------------------------ */
242        public RequestLog getRequestLog() {
243            return this.requestLogHandler.getRequestLog();
244        }
245    
246        public void doStart() throws Exception {
247            server.start();
248        }
249    
250        public void doStop() {
251            try {
252                server.stop();
253            } catch (Exception e) {
254            }
255        }
256    
257        public void doFail() {
258            try {
259                server.stop();
260            } catch (Exception e) {
261                // continue
262            }
263        }
264    
265        public static final GBeanInfo GBEAN_INFO;
266    
267        static {
268            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic("Jetty Web Container", JettyContainerImpl.class);
269    //        infoBuilder.addAttribute("collectStatistics", Boolean.TYPE, true);
270    //        infoBuilder.addAttribute("collectStatisticsStarted", Long.TYPE, false);
271    //        infoBuilder.addOperation("resetStatistics");
272    
273    //        infoBuilder.addAttribute("requestLog", RequestLog.class, false, false);
274    
275    //        infoBuilder.addOperation("addListener", new Class[]{Connector.class});
276    //        infoBuilder.addOperation("removeListener", new Class[]{Connector.class});
277    //        infoBuilder.addOperation("addContext", new Class[]{ContextHandler.class});
278    //        infoBuilder.addOperation("removeContext", new Class[]{ContextHandler.class});
279    //        infoBuilder.addOperation("addRealm", new Class[]{String.class});
280    //        infoBuilder.addOperation("removeRealm", new Class[]{String.class});
281    
282            infoBuilder.addAttribute("objectName", String.class, false);
283            infoBuilder.addReference("WebManager", WebManager.class);
284    
285            infoBuilder.addInterface(SoapHandler.class);
286            infoBuilder.addInterface(JettyContainer.class);
287            infoBuilder.addInterface(StatisticsProvider.class);
288            infoBuilder.setConstructor(new String[]{"objectName", "WebManager"});
289    
290            GBEAN_INFO = infoBuilder.getBeanInfo();
291        }
292    
293        public static GBeanInfo getGBeanInfo() {
294            return GBEAN_INFO;
295        }
296    
297    }