/*
*
* Copyright (c) void.fm
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name void.fm nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
package etm.contrib.integration.web;
import etm.core.configuration.EtmConfigurationException;
import etm.core.configuration.EtmManager;
import etm.core.configuration.XmlEtmConfigurator;
import etm.core.monitor.EtmMonitor;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
/**
* The EtmMonitorContextListener configures and starts an EtmMonitor using
* an {@link XmlEtmConfigurator}. By default it assumes a file called
* <code>jetm-config.xml</code> in classpath. You enable performance monitoring
* by adding this code fragement to your web.xml file.
* <p/>
* <pre>
* <listener>
* <listener-class>etm.contrib.integration.web.EtmMonitorContextListener</listener-class>
* </listener>
* </pre>
* It is possible to override the name of the file using the web app init parameter
* <code>jetm.config.filename</code>. Example:
* <pre>
* <context-param>
* <param-name>jetm.config.filename</param-name>
* <param-value>custom-config.xml</param-value>
* </context-param>
* </pre>
* As an alternative the jetm config file may be loaded from file system. This feature can be enabled
* by specifying <config>jetm.config.filepath</config> as context parameter. In the example below
* the jetm config file is expected at <code>/etc/yourapp</code> under the name supplied with <code>
* jetm.config.filename</code>. If jetm.config.filename is unset, the default name <code>jetm-config.xml</code>
* will be used.
* <pre>
* <context-param>
* <param-name>jetm.config.filepath</param-name>
* <param-value>/etc/yourapp</param-value>
* </context-param>
* </pre>
* While this feaure sounds convinient a hard coded filepath within a web.xml descriptor is often considered
* a design or programming error. Therefore the path to a jetm config file can be specified using
* a system property. Just write <code>jetm.config.filepath</code> as ant style property and its
* value will be retrieved from {@link System#getProperty(String)} using the given name. Example:
* <p/>
* <pre>
* <context-param>
* <param-name>jetm.config.filepath</param-name>
* <param-value>${myapp.jetm.path}</param-value>
* </context-param>
* </pre>
*
* @author void.fm
* @version $Revision$
*/
public class EtmMonitorContextListener implements ServletContextListener {
private static final String DEFAULT_CONFIG_FILE = "jetm-config.xml";
private static final String CONTEXT_FILE_NAME = "jetm.config.filename";
private static final String CONTEXT_FILE_PATH = "jetm.config.filepath";
public void contextInitialized(ServletContextEvent servletContextEvent) {
ServletContext ctx = servletContextEvent.getServletContext();
String fileName = ctx.getInitParameter(CONTEXT_FILE_NAME);
String filePath = ctx.getInitParameter(CONTEXT_FILE_PATH);
if (filePath != null && filePath.startsWith("${") && filePath.endsWith("}")) {
String key = filePath.substring(2, filePath.length() - 1);
filePath = System.getProperty(key);
if (filePath == null) {
throw new EtmConfigurationException("Error reading jetm config filepath from System properties using name " + key);
}
}
if (fileName == null) {
fileName = DEFAULT_CONFIG_FILE;
}
if (filePath != null) {
File file = new File(filePath, fileName);
if (file.canRead()) {
try {
FileInputStream in = new FileInputStream(file);
XmlEtmConfigurator.configure(in);
} catch (Exception e) {
throw new EtmConfigurationException("Error reading JETM configuration file at " + file.getAbsolutePath() + ". Cause:" + e.getMessage());
}
} else {
throw new EtmConfigurationException("Unable to locate JETM configuration file at " + file.getAbsolutePath());
}
} else {
InputStream in = EtmMonitor.class.getClassLoader().getResourceAsStream(fileName);
if (in != null) {
try {
XmlEtmConfigurator.configure(in);
} catch (Exception e) {
throw new EtmConfigurationException("Error reading JETM configuration file " + fileName + " from classpath. Cause:" + e.getMessage());
}
} else {
throw new EtmConfigurationException("Unable to locate JETM configuration file " + fileName + " in classpath.");
}
}
EtmManager.getEtmMonitor().start();
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
EtmManager.getEtmMonitor().stop();
}
}