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: */package org.apache.geronimo.jetty6;
017:
018: import java.io.File;
019: import java.util.HashMap;
020: import java.util.Map;
021:
022: import javax.management.j2ee.statistics.Stats;
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.management.LazyStatisticsProvider;
028: import org.apache.geronimo.management.geronimo.NetworkConnector;
029: import org.apache.geronimo.management.geronimo.WebManager;
030: import org.apache.geronimo.management.geronimo.stats.JettyWebContainerStatsImpl;
031: import org.apache.geronimo.system.serverinfo.ServerInfo;
032: import org.apache.geronimo.webservices.SoapHandler;
033: import org.apache.geronimo.webservices.WebServiceContainer;
034: import org.mortbay.jetty.Connector;
035: import org.mortbay.jetty.Handler;
036: import org.mortbay.jetty.RequestLog;
037: import org.mortbay.jetty.Server;
038: import org.mortbay.jetty.handler.ContextHandler;
039: import org.mortbay.jetty.handler.ContextHandlerCollection;
040: import org.mortbay.jetty.handler.DefaultHandler;
041: import org.mortbay.jetty.handler.HandlerCollection;
042: import org.mortbay.jetty.handler.RequestLogHandler;
043: import org.mortbay.jetty.handler.StatisticsHandler;
044: import org.mortbay.jetty.handler.AbstractHandlerContainer;
045:
046: /**
047: * @version $Rev: 605403 $ $Date: 2007-12-18 19:27:20 -0800 (Tue, 18 Dec 2007) $
048: */
049: public class JettyContainerImpl implements JettyContainer, SoapHandler,
050: GBeanLifecycle, LazyStatisticsProvider {
051: /**
052: * The default value of JETTY_HOME variable
053: */
054: private static final String DEFAULT_JETTY_HOME = "var/jetty";
055:
056: private final Server server;
057: private final Map webServices = new HashMap();
058: private final String objectName;
059: private final WebManager manager;
060: private final String jettyHome;
061: private final ServerInfo serverInfo;
062: private File jettyHomeDir;
063: private JettyWebContainerStatsImpl stats;
064: private final Map realms = new HashMap();
065: // list of handlers
066: private StatisticsHandler statsHandler = new StatisticsHandler();
067: private HandlerCollection handlerCollection = new HandlerCollection();
068: private ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
069: private DefaultHandler defaultHandler = new DefaultHandler();
070: private RequestLogHandler requestLogHandler = new RequestLogHandler();
071: private boolean statsHandlerInPlace = false;
072: private boolean statsOn = false;
073:
074: public JettyContainerImpl(String objectName, WebManager manager,
075: String jettyHome, ServerInfo serverInfo) {
076: this .objectName = objectName;
077: this .jettyHome = jettyHome;
078: this .serverInfo = serverInfo;
079:
080: server = new JettyServer();
081:
082: //set up the new jetty6 handler structure which is to have a HandlerCollection,
083: //each element of which is always tried on each request.
084: //The first element of the HandlerCollection is a
085: //ContextHandlerCollection, which is itself is a collection
086: //of Handlers. It's special property is that only of it's
087: //handlers will respond to a request.
088: //The second element of the HandlerCollection is a DefaultHandler
089: //which is responsible for serving static content or anything not
090: //handled by a Handler in the ContextHandlerCollection.
091: //The third element is the RequestLogHandler, which requires
092: //a RequestLog impl to be set.
093: Handler[] handlers = new Handler[3];
094: handlers[0] = contextHandlerCollection;
095: handlers[1] = defaultHandler;
096: handlers[2] = requestLogHandler;
097: handlerCollection.setHandlers(handlers);
098: server.setHandler(handlerCollection);
099:
100: stats = new JettyWebContainerStatsImpl();
101: this .manager = manager;
102: }
103:
104: public String getObjectName() {
105: return objectName;
106: }
107:
108: public boolean isStateManageable() {
109: return true;
110: }
111:
112: public boolean isStatisticsProvider() {
113: return true;
114: }
115:
116: public boolean isEventProvider() {
117: return true;
118: }
119:
120: public NetworkConnector[] getConnectors() {
121: return manager.getConnectorsForContainer(this );
122: }
123:
124: public NetworkConnector[] getConnectors(String protocol) {
125: return manager.getConnectorsForContainer(this , protocol);
126: }
127:
128: public void resetStats() {
129: statsHandler.statsReset();
130: stats.setStartTime();
131: }
132:
133: public long getCollectStatisticsStarted() {
134: return statsHandler.getStatsOnMs();
135: }
136:
137: public boolean isStatsOn() {
138: return statsOn;
139: }
140:
141: public void setStatsOn(boolean on) {
142: try {
143: if (on) {
144: // set the statistics handler if not already done so
145: if (!statsHandlerInPlace) {
146: handlerCollection.addHandler(statsHandler);
147: statsHandlerInPlace = true;
148: }
149: // clear previous data and set start time
150: resetStats();
151: // start the handler
152: statsHandler.start();
153: } else {
154: statsHandler.stop();
155: // hack because stats collection really doesn't really stop when statsHandler.stop() is invoked
156: if (statsHandlerInPlace) {
157: handlerCollection.removeHandler(statsHandler);
158: statsHandlerInPlace = false;
159: }
160: }
161: statsOn = on;
162: } catch (Exception e) {
163: e.printStackTrace();
164: }
165: }
166:
167: public Stats getStats() {
168: if (isStatsOn()) {
169: stats.setLastSampleTime();
170:
171: /* set active request range values */
172: stats.getActiveRequestCountImpl().setCurrent(
173: (long) statsHandler.getRequestsActive());
174: stats.getActiveRequestCountImpl().setLowWaterMark(
175: (long) statsHandler.getRequestsActiveMin());
176: stats.getActiveRequestCountImpl().setHighWaterMark(
177: (long) statsHandler.getRequestsActiveMax());
178:
179: /* set request duration time values, avg = Totaltime/Count */
180: /* set active request count */
181: stats.getRequestDurationImpl().setCount(
182: (long) statsHandler.getRequests());
183: stats.getRequestDurationImpl().setMaxTime(
184: (long) statsHandler.getRequestsDurationMax());
185: stats.getRequestDurationImpl().setMinTime(
186: (long) statsHandler.getRequestsDurationMin());
187: stats.getRequestDurationImpl().setTotalTime(
188: (long) statsHandler.getRequestsDurationTotal());
189:
190: /* set request count values*/
191: stats.getResponses1xxImpl().setCount(
192: (long) statsHandler.getResponses1xx());
193: stats.getResponses2xxImpl().setCount(
194: (long) statsHandler.getResponses2xx());
195: stats.getResponses3xxImpl().setCount(
196: (long) statsHandler.getResponses3xx());
197: stats.getResponses4xxImpl().setCount(
198: (long) statsHandler.getResponses4xx());
199: stats.getResponses5xxImpl().setCount(
200: (long) statsHandler.getResponses5xx());
201:
202: /* set elapsed time for stats collection */
203: stats.getStatsOnMsImpl().setCount(
204: (long) statsHandler.getStatsOnMs());
205: }
206: return stats;
207: }
208:
209: public void addListener(Connector listener) {
210: server.addConnector(listener);
211: }
212:
213: public void removeListener(Connector listener) {
214: server.removeConnector(listener);
215: }
216:
217: public void addContext(AbstractHandlerContainer context) {
218: contextHandlerCollection.addHandler(context);
219: }
220:
221: public void removeContext(AbstractHandlerContainer context) {
222: contextHandlerCollection.removeHandler(context);
223: }
224:
225: public InternalJAASJettyRealm addRealm(String realmName) {
226: InternalJAASJettyRealm realm = (InternalJAASJettyRealm) realms
227: .get(realmName);
228: if (realm == null) {
229: realm = new InternalJAASJettyRealm(realmName);
230: realms.put(realmName, realm);
231: } else {
232: realm.addUse();
233: }
234: return realm;
235: }
236:
237: public void removeRealm(String realmName) {
238: InternalJAASJettyRealm realm = (InternalJAASJettyRealm) realms
239: .get(realmName);
240: if (realm != null) {
241: if (realm.removeUse() == 0) {
242: realms.remove(realmName);
243: }
244: }
245: }
246:
247: public void addWebService(String contextPath,
248: String[] virtualHosts,
249: WebServiceContainer webServiceContainer,
250: String securityRealmName, String realmName,
251: String transportGuarantee, String authMethod,
252: ClassLoader classLoader) throws Exception {
253: InternalJAASJettyRealm internalJAASJettyRealm = securityRealmName == null ? null
254: : addRealm(securityRealmName);
255: JettyEJBWebServiceContext webServiceContext = new JettyEJBWebServiceContext(
256: contextPath, webServiceContainer,
257: internalJAASJettyRealm, realmName, transportGuarantee,
258: authMethod, classLoader);
259: webServiceContext.setVirtualHosts(virtualHosts);
260: addContext(webServiceContext);
261: webServiceContext.start();
262: webServices.put(contextPath, webServiceContext);
263: }
264:
265: public void removeWebService(String contextPath) {
266: JettyEJBWebServiceContext webServiceContext = (JettyEJBWebServiceContext) webServices
267: .remove(contextPath);
268: String securityRealmName = webServiceContext
269: .getSecurityRealmName();
270: if (securityRealmName != null) {
271: removeRealm(securityRealmName);
272: }
273: try {
274: removeContext(webServiceContext);
275: } catch (Exception e) {
276: throw new IllegalStateException(e.getMessage(), e);
277: }
278: }
279:
280: public void setRequestLog(RequestLog log) {
281: this .requestLogHandler.setRequestLog(log);
282: }
283:
284: public File resolveToJettyHome(String workDir) {
285: if (workDir == null) {
286: return null;
287: }
288: return new File(jettyHomeDir, workDir);
289: }
290:
291: public RequestLog getRequestLog() {
292: return this .requestLogHandler.getRequestLog();
293: }
294:
295: public void doStart() throws Exception {
296: jettyHomeDir = new File(serverInfo
297: .resolveServerPath(jettyHome != null ? jettyHome
298: : DEFAULT_JETTY_HOME));
299: if (!jettyHomeDir.exists()) {
300: jettyHomeDir.mkdirs();
301: }
302: // start the server
303: server.start();
304: }
305:
306: public void doStop() {
307: try {
308: server.stop();
309: } catch (Exception e) {
310: }
311: }
312:
313: public void doFail() {
314: try {
315: server.stop();
316: } catch (Exception e) {
317: // continue
318: }
319: }
320:
321: public static final GBeanInfo GBEAN_INFO;
322:
323: static {
324: GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(
325: "Jetty Web Container", JettyContainerImpl.class);
326: infoBuilder.addAttribute("statsOn", Boolean.TYPE, true);
327: infoBuilder.addAttribute("collectStatisticsStarted", Long.TYPE,
328: false);
329: infoBuilder.addAttribute("objectName", String.class, false);
330: infoBuilder.addAttribute("jettyHome", String.class, true);
331:
332: infoBuilder.addReference("WebManager", WebManager.class);
333: infoBuilder.addReference("ServerInfo", ServerInfo.class,
334: "GBean");
335:
336: // this is needed because the getters/setters are not added automatically
337: infoBuilder.addOperation("setStatsOn",
338: new Class[] { boolean.class }, "void");
339: infoBuilder.addOperation("resetStats");
340:
341: infoBuilder.addInterface(SoapHandler.class);
342: infoBuilder.addInterface(JettyContainer.class);
343: infoBuilder.addInterface(LazyStatisticsProvider.class);
344:
345: infoBuilder.setConstructor(new String[] { "objectName",
346: "WebManager", "jettyHome", "ServerInfo" });
347:
348: GBEAN_INFO = infoBuilder.getBeanInfo();
349: }
350:
351: public static GBeanInfo getGBeanInfo() {
352: return GBEAN_INFO;
353: }
354:
355: }
|