001    /**
002     *
003     * Copyright 2003-2004 The Apache Software Foundation
004     *
005     *  Licensed under the Apache License, Version 2.0 (the "License");
006     *  you may not use this file except in compliance with the License.
007     *  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.jetty;
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.http.HttpContext;
034    import org.mortbay.http.HttpListener;
035    import org.mortbay.http.RequestLog;
036    import org.mortbay.jetty.Server;
037    
038    /**
039     * @version $Rev: 431706 $ $Date: 2006-08-15 14:19:27 -0700 (Tue, 15 Aug 2006) $
040     */
041    public class JettyContainerImpl implements JettyContainer, SoapHandler, GBeanLifecycle, StatisticsProvider {
042        private final Server server;
043        private final Map webServices = new HashMap();
044        private final String objectName;
045        private final WebManager manager;
046        private JettyWebContainerStatsImpl stats;
047        private final Map realms = new HashMap();
048    
049        public JettyContainerImpl(String objectName, WebManager manager) {
050            this.objectName = objectName;
051            server = new JettyServer();
052            stats = new JettyWebContainerStatsImpl();
053            this.manager = manager;
054        }
055    
056        public String getObjectName() {
057            return objectName;
058        }
059    
060        public boolean isStateManageable() {
061            return true;
062        }
063    
064        public boolean isStatisticsProvider() {
065            return true;
066        }
067    
068        public boolean isEventProvider() {
069            return true;
070        }
071    
072        public NetworkConnector[] getConnectors() {
073            return manager.getConnectorsForContainer(this);
074        }
075    
076        public NetworkConnector[] getConnectors(String protocol) {
077            return manager.getConnectorsForContainer(this, protocol);
078        }
079    
080        public void resetStatistics() {
081            server.statsReset();
082        }
083    
084        public void setCollectStatistics(boolean on) {
085            server.setStatsOn(on);
086            stats.setStatsOn(on);
087        }
088    
089        public boolean getCollectStatistics() {
090            return server.getStatsOn();
091        }
092    
093        public long getCollectStatisticsStarted() {
094            return server.getStatsOnMs();
095        }
096    
097        public Stats getStats() {
098            if (getCollectStatistics()) {
099    
100                /* set active request count */
101                stats.getTotalRequestCountImpl().setCount(server.getRequests());
102    
103                /* set total connection count */
104                stats.getTotalConnectionCountImpl().setCount(server.getConnections());
105    
106                /* set total error count */
107                stats.getTotalErrorCountImpl().setCount(server.getErrors());
108    
109                /* set active request range values */
110                stats.getActiveRequestCountImpl().setCurrent(server.getRequestsActive());
111                stats.getActiveRequestCountImpl().setLowWaterMark(server.getRequestsActiveMin());
112                stats.getActiveRequestCountImpl().setHighWaterMark(server.getRequestsActiveMax());
113    
114                /* set connection requests range values */
115    //          stats.getConnectionRequestCountImpl().setCurrent(server.getConnectionsRequestsCurrent());    // temporarily removed until added by jetty
116                stats.getConnectionRequestCountImpl().setCurrent(server.getConnectionsOpen());
117                stats.getConnectionRequestCountImpl().setLowWaterMark(server.getConnectionsRequestsMin());
118                stats.getConnectionRequestCountImpl().setHighWaterMark(server.getConnectionsRequestsMax());
119    
120                /* set open connection range values */
121                stats.getOpenConnectionCountImpl().setCurrent(server.getConnectionsOpen());
122                stats.getOpenConnectionCountImpl().setLowWaterMark(server.getConnectionsOpenMin());
123                stats.getOpenConnectionCountImpl().setHighWaterMark(server.getConnectionsOpenMax());
124    
125                /* set request duration time values */
126                stats.getRequestDurationImpl().setMinTime(server.getRequestsDurationMin());
127                stats.getRequestDurationImpl().setMaxTime(server.getRequestsDurationMax());
128    //          stats.getRequestDurationImpl().setCount(server.getRequestsDurationCount());     // temporarily removed until added by jetty
129                stats.getRequestDurationImpl().setCount(stats.getTotalRequestCount().getCount());
130                stats.getRequestDurationImpl().setTotalTime(server.getRequestsDurationTotal());
131    
132                /* set connection duration Time values */
133                stats.getConnectionDurationImpl().setMinTime(server.getConnectionsDurationMin());
134                stats.getConnectionDurationImpl().setMaxTime(server.getConnectionsDurationMax());
135    //          stats.getConnectionDurationImpl().setCount(server.getConnectionsDurationCount());    // temporarily removed until added by jetty
136                stats.getConnectionDurationImpl().setCount(stats.getTotalConnectionCount().getCount());
137                stats.getConnectionDurationImpl().setTotalTime(server.getConnectionsDurationTotal());
138    
139            } else {
140                // should probably set the stats object to all zero/null values to avoid unpredicable results
141            }
142            return stats;
143        }
144    
145        public void addListener(HttpListener listener) {
146            server.addListener(listener);
147        }
148    
149        public void removeListener(HttpListener listener) {
150            server.removeListener(listener);
151        }
152    
153        public void addContext(HttpContext context) {
154            server.addContext(context);
155        }
156    
157        public void removeContext(HttpContext context) {
158            server.removeContext(context);
159        }
160    
161        public InternalJAASJettyRealm addRealm(String realmName) {
162            InternalJAASJettyRealm realm = (InternalJAASJettyRealm) realms.get(realmName);
163            if (realm == null) {
164                realm = new InternalJAASJettyRealm(realmName);
165                realms.put(realmName, realm);
166            } else {
167                realm.addUse();
168            }
169            return realm;
170        }
171    
172        public void removeRealm(String realmName) {
173            InternalJAASJettyRealm realm = (InternalJAASJettyRealm) realms.get(realmName);
174            if (realm != null) {
175                if (realm.removeUse() == 0){
176                    realms.remove(realmName);
177                }
178            }
179        }
180    
181        public void addWebService(String contextPath, String[] virtualHosts, WebServiceContainer webServiceContainer, String securityRealmName, String realmName, String transportGuarantee, String authMethod, ClassLoader classLoader) throws Exception {
182            InternalJAASJettyRealm internalJAASJettyRealm = securityRealmName == null? null:addRealm(securityRealmName);
183            JettyEJBWebServiceContext webServiceContext = new JettyEJBWebServiceContext(contextPath, webServiceContainer, internalJAASJettyRealm, realmName, transportGuarantee, authMethod, classLoader);
184            webServiceContext.setHosts(virtualHosts);
185            addContext(webServiceContext);
186            webServiceContext.start();
187            webServices.put(contextPath, webServiceContext);
188         }
189    
190        public void removeWebService(String contextPath) {
191            JettyEJBWebServiceContext webServiceContext = (JettyEJBWebServiceContext) webServices.remove(contextPath);
192            String securityRealmName = webServiceContext.getSecurityRealmName();
193            if (securityRealmName != null) {
194                removeRealm(securityRealmName);
195            }
196            removeContext(webServiceContext);
197        }
198    
199        public void setRequestLog(RequestLog log) {
200            server.setRequestLog(log);
201        }
202    
203        /* ------------------------------------------------------------ */
204        public RequestLog getRequestLog() {
205            return server.getRequestLog();
206        }
207    
208        public void doStart() throws Exception {
209            server.start();
210        }
211    
212        public void doStop() {
213            try {
214                server.stop(true);
215            } catch (InterruptedException e) {
216            }
217        }
218    
219        public void doFail() {
220            try {
221                server.stop(false);
222            } catch (InterruptedException e) {
223                // continue
224            }
225        }
226    
227        public static final GBeanInfo GBEAN_INFO;
228    
229        static {
230            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic("Jetty Web Container", JettyContainerImpl.class);
231            infoBuilder.addAttribute("collectStatistics", Boolean.TYPE, true);
232            infoBuilder.addAttribute("collectStatisticsStarted", Long.TYPE, false);
233            infoBuilder.addOperation("resetStatistics");
234    
235            infoBuilder.addAttribute("requestLog", RequestLog.class, false, false);
236    
237            infoBuilder.addOperation("addListener", new Class[]{HttpListener.class});
238            infoBuilder.addOperation("removeListener", new Class[]{HttpListener.class});
239            infoBuilder.addOperation("addContext", new Class[]{HttpContext.class});
240            infoBuilder.addOperation("removeContext", new Class[]{HttpContext.class});
241            infoBuilder.addOperation("addRealm", new Class[]{String.class});
242            infoBuilder.addOperation("removeRealm", new Class[]{String.class});
243    
244            infoBuilder.addAttribute("objectName", String.class, false);
245            infoBuilder.addReference("WebManager", WebManager.class);
246    
247            infoBuilder.addInterface(SoapHandler.class);
248            infoBuilder.addInterface(JettyContainer.class);
249            infoBuilder.addInterface(StatisticsProvider.class);
250            infoBuilder.setConstructor(new String[]{"objectName", "WebManager"});
251    
252            GBEAN_INFO = infoBuilder.getBeanInfo();
253        }
254    
255        public static GBeanInfo getGBeanInfo() {
256            return GBEAN_INFO;
257        }
258    
259    }