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 }