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 }