Java tutorial
/* * Licensed under the GPL License. You may not use this file except in * compliance with the License. You may obtain a copy of the License at * * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ package com.googlecode.psiprobe.tools; import java.io.Serializable; import java.net.InetAddress; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.naming.NamingException; import javax.servlet.ServletContext; import javax.servlet.http.HttpSession; import net.sf.javainetlocator.InetAddressLocator; import org.apache.catalina.Container; import org.apache.catalina.Context; import org.apache.catalina.Session; import org.apache.catalina.Wrapper; import org.apache.catalina.core.StandardWrapper; import org.apache.catalina.deploy.ApplicationParameter; import org.apache.catalina.deploy.FilterDef; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.util.ClassUtils; import com.googlecode.psiprobe.beans.ContainerWrapperBean; import com.googlecode.psiprobe.beans.ResourceResolver; import com.googlecode.psiprobe.model.Application; import com.googlecode.psiprobe.model.ApplicationParam; import com.googlecode.psiprobe.model.ApplicationResource; import com.googlecode.psiprobe.model.ApplicationSession; import com.googlecode.psiprobe.model.Attribute; import com.googlecode.psiprobe.model.FilterInfo; import com.googlecode.psiprobe.model.ServletInfo; import com.googlecode.psiprobe.model.ServletMapping; /** * * @author Vlad Ilyushchenko * @author Andy Shapoval * @author Mark Lewis */ public class ApplicationUtils { private static Log logger = LogFactory.getLog(ApplicationUtils.class); public static Application getApplication(Context context, ContainerWrapperBean containerWrapper) { return getApplication(context, null, false, containerWrapper); } /** * Creates Application instance from Tomcat Context object. If ResourceResolver is passed the method will also collect additional information * about the application such as session count, session attribute count, application attribute count, servlet count, servlet stats summary and * datasource usage summary. Collecting additional information can be CPU intensive and time consuming so this should be avoided unless absolutely * required. Some datasource implementations (c3p0) are known to be prone to internal deadlocks, so this method can also hang is datasource usage * stats is to be collected. * * @param context * @param resourceResolver * @param calcSize * @return Application object */ public static Application getApplication(Context context, ResourceResolver resourceResolver, boolean calcSize, ContainerWrapperBean containerWrapper) { //ContainerWrapperBean containerWrapper logger.debug("Querying webapp: " + context.getName()); Application app = new Application(); app.setName(context.getName().length() > 0 ? context.getName() : "/"); app.setDocBase(context.getDocBase()); app.setDisplayName(context.getDisplayName()); app.setAvailable(containerWrapper.getTomcatContainer().getAvailable(context)); app.setDistributable(context.getDistributable()); app.setSessionTimeout(context.getSessionTimeout()); app.setServletVersion(context.getServletContext().getMajorVersion() + "." + context.getServletContext().getMinorVersion()); if (resourceResolver != null) { logger.debug("counting servlet attributes"); int ctxAttrCount = 0; for (Enumeration e = context.getServletContext().getAttributeNames(); e.hasMoreElements(); e .nextElement()) { ctxAttrCount++; } app.setContextAttributeCount(ctxAttrCount); if (app.isAvailable()) { logger.debug("collecting session information"); app.setSessionCount(context.getManager().findSessions().length); boolean serializable = true; int sessionAttributeCount = 0; long size = 0; Session[] sessions = context.getManager().findSessions(); for (int i = 0; i < sessions.length; i++) { ApplicationSession appSession = getApplicationSession(sessions[i], calcSize, false); if (appSession != null) { sessionAttributeCount += appSession.getObjectCount(); serializable = serializable && appSession.isSerializable(); size += appSession.getSize(); } } app.setSerializable(serializable); app.setSessionAttributeCount(sessionAttributeCount); app.setSize(size); } logger.debug("aggregating servlet stats"); collectApplicationServletStats(context, app); if (resourceResolver.supportsPrivateResources() && app.isAvailable()) { int[] scores = getApplicationDataSourceUsageScores(context, resourceResolver, containerWrapper); app.setDataSourceBusyScore(scores[0]); app.setDataSourceEstablishedScore(scores[1]); } } return app; } /** * Calculates Sum of requestCount, errorCount and processingTime for all servlets for the * give application. It also works out minimum value of minTime and maximum value for maxTime for * all servlets. * * @param context * @param app */ public static void collectApplicationServletStats(Context context, Application app) { int svltCount = 0; int reqCount = 0; int errCount = 0; long procTime = 0; long minTime = Long.MAX_VALUE; long maxTime = 0; Container[] cns = context.findChildren(); for (int i = 0; i < cns.length; i++) { if (cns[i] instanceof StandardWrapper) { StandardWrapper sw = (StandardWrapper) cns[i]; svltCount++; reqCount += sw.getRequestCount(); errCount += sw.getErrorCount(); procTime += sw.getProcessingTime(); if (sw.getRequestCount() > 0) { minTime = Math.min(minTime, sw.getMinTime()); } maxTime = Math.max(maxTime, sw.getMaxTime()); } } app.setServletCount(svltCount); app.setRequestCount(reqCount); app.setErrorCount(errCount); app.setProcessingTime(procTime); app.setMinTime(minTime == Long.MAX_VALUE ? 0 : minTime); app.setMaxTime(maxTime); } public static int[] getApplicationDataSourceUsageScores(Context context, ResourceResolver resolver, ContainerWrapperBean containerWrapper) { logger.debug("Calculating datasource usage score"); int[] scores = new int[] { 0, 0 }; List appResources; try { appResources = resolver.getApplicationResources(context, containerWrapper); } catch (NamingException e) { throw new RuntimeException(e); } for (Iterator it = appResources.iterator(); it.hasNext();) { ApplicationResource appResource = (ApplicationResource) it.next(); if (appResource.getDataSourceInfo() != null) { scores[0] = Math.max(scores[0], appResource.getDataSourceInfo().getBusyScore()); scores[1] = Math.max(scores[1], appResource.getDataSourceInfo().getEstablishedScore()); } } return scores; } public static ApplicationSession getApplicationSession(Session session, boolean calcSize, boolean addAttributes) { ApplicationSession sbean = null; if (session != null && session.isValid()) { sbean = new ApplicationSession(); sbean.setId(session.getId()); sbean.setCreationTime(new Date(session.getCreationTime())); sbean.setLastAccessTime(new Date(session.getLastAccessedTime())); sbean.setMaxIdleTime(session.getMaxInactiveInterval() * 1000); sbean.setManagerType(session.getManager().getClass().getName()); //sbean.setInfo(session.getInfo()); //TODO:fixmee boolean sessionSerializable = true; int attributeCount = 0; long size = 0; HttpSession httpSession = session.getSession(); Set processedObjects = new HashSet(1000); //Exclude references back to the session itself processedObjects.add(httpSession); try { for (Enumeration e = httpSession.getAttributeNames(); e.hasMoreElements();) { String name = (String) e.nextElement(); Object o = httpSession.getAttribute(name); sessionSerializable = sessionSerializable && o instanceof Serializable; long oSize = 0; if (calcSize) { try { oSize += Instruments.sizeOf(name, processedObjects); oSize += Instruments.sizeOf(o, processedObjects); } catch (Throwable th) { logger.error("Cannot estimate size of attribute \"" + name + "\"", th); // // make sure we always re-throw ThreadDeath // if (e instanceof ThreadDeath) { throw (ThreadDeath) e; } } } if (addAttributes) { Attribute saBean = new Attribute(); saBean.setName(name); saBean.setType(ClassUtils.getQualifiedName(o.getClass())); saBean.setValue(o); saBean.setSize(oSize); saBean.setSerializable(o instanceof Serializable); sbean.addAttribute(saBean); } attributeCount++; size += oSize; } String lastAccessedIP = (String) httpSession.getAttribute(ApplicationSession.LAST_ACCESSED_BY_IP); if (lastAccessedIP != null) { sbean.setLastAccessedIP(lastAccessedIP); } try { sbean.setLastAccessedIPLocale( InetAddressLocator.getLocale(InetAddress.getByName(lastAccessedIP).getAddress())); } catch (Throwable e) { logger.error("Cannot determine Locale of " + lastAccessedIP); // // make sure we always re-throw ThreadDeath // if (e instanceof ThreadDeath) { throw (ThreadDeath) e; } } } catch (IllegalStateException e) { logger.info("Session appears to be invalidated, ignore"); } sbean.setObjectCount(attributeCount); sbean.setSize(size); sbean.setSerializable(sessionSerializable); } return sbean; } public static List getApplicationAttributes(Context context) { List attrs = new ArrayList(); ServletContext servletCtx = context.getServletContext(); for (Enumeration e = servletCtx.getAttributeNames(); e.hasMoreElements();) { String attrName = (String) e.nextElement(); Object attrValue = servletCtx.getAttribute(attrName); Attribute attr = new Attribute(); attr.setName(attrName); attr.setValue(attrValue); attr.setType(ClassUtils.getQualifiedName(attrValue.getClass())); attrs.add(attr); } return attrs; } public static List getApplicationInitParams(Context context, ContainerWrapperBean containerWrapper) { return containerWrapper.getTomcatContainer().getApplicationInitParams(context); } public static ServletInfo getApplicationServlet(Context context, String servletName) { Container c = context.findChild(servletName); if (c instanceof Wrapper) { Wrapper w = (Wrapper) c; return getServletInfo(w, context.getName()); } else { return null; } } private static ServletInfo getServletInfo(Wrapper w, String contextName) { ServletInfo si = new ServletInfo(); si.setApplicationName(contextName.length() > 0 ? contextName : "/"); si.setServletName(w.getName()); si.setServletClass(w.getServletClass()); si.setAvailable(!w.isUnavailable()); si.setLoadOnStartup(w.getLoadOnStartup()); si.setRunAs(w.getRunAs()); String[] ms = w.findMappings(); for (int i = 0; i < ms.length; i++) { si.getMappings().add(ms[i]); } if (w instanceof StandardWrapper) { StandardWrapper sw = (StandardWrapper) w; si.setAllocationCount(sw.getCountAllocated()); si.setErrorCount(sw.getErrorCount()); si.setLoadTime(sw.getLoadTime()); si.setMaxInstances(sw.getMaxInstances()); si.setMaxTime(sw.getMaxTime()); si.setMinTime(sw.getMinTime() == Long.MAX_VALUE ? 0 : sw.getMinTime()); si.setProcessingTime(sw.getProcessingTime()); si.setRequestCount(sw.getRequestCount()); si.setSingleThreaded(sw.isSingleThreadModel()); } return si; } public static List getApplicationServlets(Context context) { Container[] cns = context.findChildren(); List servlets = new ArrayList(cns.length); for (int i = 0; i < cns.length; i++) { if (cns[i] instanceof Wrapper) { Wrapper w = (Wrapper) cns[i]; servlets.add(getServletInfo(w, context.getName())); } } return servlets; } public static List getApplicationServletMaps(Context context) { String[] sms = context.findServletMappings(); List servletMaps = new ArrayList(sms.length); for (int i = 0; i < sms.length; i++) { if (sms[i] != null) { String sn = context.findServletMapping(sms[i]); if (sn != null) { ServletMapping sm = new ServletMapping(); sm.setApplicationName(context.getName().length() > 0 ? context.getName() : "/"); sm.setUrl(sms[i]); sm.setServletName(sn); Container c = context.findChild(sn); if (c instanceof Wrapper) { Wrapper w = (Wrapper) c; sm.setServletClass(w.getServletClass()); sm.setAvailable(!w.isUnavailable()); } servletMaps.add(sm); } } } return servletMaps; } public static FilterInfo getApplicationFilter(Context context, String filterName) { FilterDef fd = context.findFilterDef(filterName); if (fd != null) { return getFilterInfo(fd); } else { return null; } } private static FilterInfo getFilterInfo(FilterDef fd) { FilterInfo fi = new FilterInfo(); fi.setFilterName(fd.getFilterName()); fi.setFilterClass(fd.getFilterClass()); fi.setFilterDesc(fd.getDescription()); return fi; } public static List getApplicationFilters(Context context, ContainerWrapperBean containerWrapper) { return containerWrapper.getTomcatContainer().getApplicationFilters(context); } }