[
https://issues.apache.org/jira/browse/OODT-649?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13732985#comment-13732985
]
Ross Laidlaw edited comment on OODT-649 at 8/8/13 12:19 AM:
------------------------------------------------------------
Hi Rishi,
I've been doing some experimenting and contrary to what I said before, it seems
that my context parameters (in the context container) are being picked up
correctly by my Tomcat setup. I'm using a setup that's quite similar to the
one given for the PCS-OPSUI webapp in the quick start guide [1], which seems to
work really well.
I have a symbolic link named 'fmprod.xml' in my Catalina/localhost directory
that links to my actual context container file (also named 'fmprod.xml'), which
is stored in a separate directory (/usr/local/oodt/webapp/fmprod).
Here's what my context file looks like:
{code:xml|title=fmprod.xml|borderStyle=solid}
<?xml version='1.0' encoding='UTF-8'?>
<Context path="/fmprod"
docBase="/usr/local/oodt/webapp/fmprod/cas-product-0.7-SNAPSHOT.war"
debug="5" reloadable="true" crossContext="true">
<Valve className="org.apache.catalina.valves.AccessLogValve"
prefix="fmprod_access_log." suffix=".txt" pattern="common"/>
<Parameter name="filemgr.url"
value="http://localhost:9000" override="false"/>
<Parameter name="filemgr.working.dir"
value="/tmp" override="false"/>
<Parameter name="filemgr.rdfconf.file"
value="/usr/local/oodt/webapp/fmprod/rdfconf.xml" override="false"/>
<Parameter name="filemgr.rssconf.file"
value="/usr/local/oodt/webapp/fmprod/rssconf.xml" override="false"/>
<Parameter name="filemgr.rss-transfer-conf.file"
value="/usr/local/oodt/webapp/fmprod/rss-transfer-conf.xml"
override="false"/>
</Context>
{code}
Whenever I make a change to the file or copy in a new version of the WAR to the
/usr/local/oodt/webapp/fmprod directory, Tomcat automatically updates/redeploys
to pick up the changes. So all appears to be working well.
I also experimented with extending the default servlet
(CXFNonSpringJaxrsServlet) that we're using to manage our JAX-RS service
classes. I think we can initialize some objects (e.g. XmlRpcFileManagerClient)
in the init() method and then store these objects as ServletContext attributes
using ServletContext.setAttribute(String, Object). Here's an example
implementation with some logging/validation as well:
{code:title=CasProductCxfServlet.java|borderStyle=solid}
package org.apache.oodt.cas.product.service.servlets;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet;
import org.apache.oodt.cas.filemgr.structs.exceptions.ConnectionException;
import org.apache.oodt.cas.filemgr.system.XmlRpcFileManagerClient;
import org.apache.oodt.cas.metadata.util.PathUtils;
import org.apache.oodt.cas.product.service.responders.ZipResponder;
/**
* @author rlaidlaw
* @version $Revision$
*/
public class CasProductJaxrsServlet extends CXFNonSpringJaxrsServlet
{
private static final long serialVersionUID = 1L;
private static final Logger LOGGER =
Logger.getLogger(CasProductJaxrsServlet.class
.getName());
@Override
public void init(ServletConfig configuration) throws ServletException
{
super.init(configuration);
ServletContext context = configuration.getServletContext();
// Initialize the file manager client.
try
{
URL url = null;
String urlParameter = context.getInitParameter("filemgr.url");
if (urlParameter != null)
{
// Get the file manager URL from the context parameter.
url = new URL(PathUtils.replaceEnvVariables(urlParameter));
}
else
{
// Try the default URL for the file manager.
LOGGER.log(Level.WARNING, "No servlet context parameter was specified "
+ " for the file manager URL.");
url = new URL("http://localhost:9000");
}
// Attempt to connect the client to the file manager and if successful
// store the client as a context attribute for other objects to access.
XmlRpcFileManagerClient client = new XmlRpcFileManagerClient(url);
context.setAttribute("client", client);
}
catch (MalformedURLException e)
{
LOGGER.log(Level.SEVERE,
"Encountered a malformed URL for the file manager.", e);
throw new ServletException(e);
}
catch (ConnectionException e)
{
LOGGER.log(Level.SEVERE,
"Client could not establish a connection to the file manager.", e);
throw new ServletException(e);
}
// Initialize the file manager working directory.
String workingDirPath = context.getInitParameter("filemgr.working.dir");
if (workingDirPath != null)
{
// Validate the path.
File workingDir = new File(workingDirPath);
if (workingDir.exists() && workingDir.isDirectory())
{
context.setAttribute("workingDir", workingDir);
}
else
{
LOGGER.log(Level.SEVERE, "The working directory for the file manager "
+ "could not be located.");
}
}
else
{
String message = "No servlet context parameter was specified for the file"
+ " manager working directory path.";
LOGGER.log(Level.SEVERE, message);
throw new ServletException(message);
}
}
}
{code}
The servlet is configured in the web.xml file as follows:
{code:xml}
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.oodt.cas.product.service.servlets.CasProductJaxrsServlet
</servlet-class>
<init-param>
<param-name>jaxrs.serviceClasses</param-name>
<param-value>
org.apache.oodt.cas.product.service.resources.ReferenceResource,
org.apache.oodt.cas.product.service.resources.ProductResource,
org.apache.oodt.cas.product.service.resources.DatasetResource,
org.apache.oodt.cas.product.service.resources.TransferResource
</param-value>
</init-param>
<init-param>
<param-name>jaxrs.scope</param-name>
<param-value>prototype</param-value>
</init-param>
</servlet>
{code}
Where the jaxrs.scope prototype parameter specifies that new instances of the
resource classes are created per-request. Even if this is the case, with a new
instance per request, I think the CasProductJaxrsServlet instance may persist
for longer. The resource instances can access the objects that were
initialized in the servlet by calling ServletContext.getAttribute(String), e.g.
as follows:
{code}
@Context
private ServletContext context;
@GET
public Response getResponse()
{
...
Object object = context.getAttribute("client");
if (object != null && object instanceof XmlRpcFileManagerClient)
{
XmlRpcFileManagerClient client = (XmlRpcFileManagerClient) object;
}
...
}
{code}
[1] https://cwiki.apache.org/confluence/display/OODT/Quick+Start+for+PCS+OPSUI
was (Author: rlaidlaw):
Hi Rishi,
I've been doing some experimenting and contrary to what I said before, it seems
that my context parameters (in the context container) are being picked up
correctly by my Tomcat setup. I'm using a setup that's quite similar to the
one given for the PCS-OPSUI webapp in the quick start guide [1], which seems to
work really well.
I have a symbolic link named 'fmprod.xml' in my Catalina/localhost directory
that links to my context.xml file (also named 'fmprod.xml'), which is stored in
a separate directory (/usr/local/oodt/webapp/fmprod).
Here's what my context file looks like:
{code:xml|title=fmprod.xml|borderStyle=solid}
<?xml version='1.0' encoding='UTF-8'?>
<Context path="/fmprod"
docBase="/usr/local/oodt/webapp/fmprod/cas-product-0.7-SNAPSHOT.war"
debug="5" reloadable="true" crossContext="true">
<Valve className="org.apache.catalina.valves.AccessLogValve"
prefix="fmprod_access_log." suffix=".txt" pattern="common"/>
<Parameter name="filemgr.url"
value="http://localhost:9000" override="false"/>
<Parameter name="filemgr.working.dir"
value="/tmp" override="false"/>
<Parameter name="filemgr.rdfconf.file"
value="/usr/local/oodt/webapp/fmprod/rdfconf.xml" override="false"/>
<Parameter name="filemgr.rssconf.file"
value="/usr/local/oodt/webapp/fmprod/rssconf.xml" override="false"/>
<Parameter name="filemgr.rss-transfer-conf.file"
value="/usr/local/oodt/webapp/fmprod/rss-transfer-conf.xml"
override="false"/>
</Context>
{code}
Whenever I make a change to the file or copy in a new version of the WAR to the
/usr/local/oodt/webapp/fmprod directory, Tomcat automatically updates/redeploys
to pick up the changes. So all appears to be working well.
I also experimented with extending the default servlet
(CXFNonSpringJaxrsServlet) that we're using to manage our JAX-RS service
classes. I think we can initialize some objects (e.g. XmlRpcFileManagerClient)
in the init() method and then store these objects as ServletContext attributes
using ServletContext.setAttribute(String, Object). Here's an example
implementation with some logging/validation as well:
{code:title=CasProductCxfServlet.java|borderStyle=solid}
package org.apache.oodt.cas.product.service.servlets;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet;
import org.apache.oodt.cas.filemgr.structs.exceptions.ConnectionException;
import org.apache.oodt.cas.filemgr.system.XmlRpcFileManagerClient;
import org.apache.oodt.cas.metadata.util.PathUtils;
import org.apache.oodt.cas.product.service.responders.ZipResponder;
/**
* @author rlaidlaw
* @version $Revision$
*/
public class CasProductJaxrsServlet extends CXFNonSpringJaxrsServlet
{
private static final long serialVersionUID = 1L;
private static final Logger LOGGER =
Logger.getLogger(CasProductJaxrsServlet.class
.getName());
@Override
public void init(ServletConfig configuration) throws ServletException
{
super.init(configuration);
ServletContext context = configuration.getServletContext();
// Initialize the file manager client.
try
{
URL url = null;
String urlParameter = context.getInitParameter("filemgr.url");
if (urlParameter != null)
{
// Get the file manager URL from the context parameter.
url = new URL(PathUtils.replaceEnvVariables(urlParameter));
}
else
{
// Try the default URL for the file manager.
LOGGER.log(Level.WARNING, "No servlet context parameter was specified "
+ " for the file manager URL.");
url = new URL("http://localhost:9000");
}
// Attempt to connect the client to the file manager and if successful
// store the client as a context attribute for other objects to access.
XmlRpcFileManagerClient client = new XmlRpcFileManagerClient(url);
context.setAttribute("client", client);
}
catch (MalformedURLException e)
{
LOGGER.log(Level.SEVERE,
"Encountered a malformed URL for the file manager.", e);
throw new ServletException(e);
}
catch (ConnectionException e)
{
LOGGER.log(Level.SEVERE,
"Client could not establish a connection to the file manager.", e);
throw new ServletException(e);
}
// Initialize the file manager working directory.
String workingDirPath = context.getInitParameter("filemgr.working.dir");
if (workingDirPath != null)
{
// Validate the path.
File workingDir = new File(workingDirPath);
if (workingDir.exists() && workingDir.isDirectory())
{
context.setAttribute("workingDir", workingDir);
}
else
{
LOGGER.log(Level.SEVERE, "The working directory for the file manager "
+ "could not be located.");
}
}
else
{
String message = "No servlet context parameter was specified for the file"
+ " manager working directory path.";
LOGGER.log(Level.SEVERE, message);
throw new ServletException(message);
}
}
}
{code}
The servlet is configured in the web.xml file as follows:
{code:xml}
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.oodt.cas.product.service.servlets.CasProductJaxrsServlet
</servlet-class>
<init-param>
<param-name>jaxrs.serviceClasses</param-name>
<param-value>
org.apache.oodt.cas.product.service.resources.ReferenceResource,
org.apache.oodt.cas.product.service.resources.ProductResource,
org.apache.oodt.cas.product.service.resources.DatasetResource,
org.apache.oodt.cas.product.service.resources.TransferResource
</param-value>
</init-param>
<init-param>
<param-name>jaxrs.scope</param-name>
<param-value>prototype</param-value>
</init-param>
</servlet>
{code}
Where the jaxrs.scope prototype parameter specifies that new instances of the
resource classes are created per-request. Even if this is the case, with a new
instance per request, I think the CasProductJaxrsServlet instance may persist
for longer. The resource instances can access the objects that were
initialized in the servlet by calling ServletContext.getAttribute(String), e.g.
as follows:
{code}
@Context
private ServletContext context;
@GET
public Response getResponse()
{
...
Object object = context.getAttribute("client");
if (object != null && object instanceof XmlRpcFileManagerClient)
{
XmlRpcFileManagerClient client = (XmlRpcFileManagerClient) object;
}
...
}
{code}
[1] https://cwiki.apache.org/confluence/display/OODT/Quick+Start+for+PCS+OPSUI
> Add PathUtils.replaceEnvVariables() wrapper around retrieved context
> parameters
> -------------------------------------------------------------------------------
>
> Key: OODT-649
> URL: https://issues.apache.org/jira/browse/OODT-649
> Project: OODT
> Issue Type: Sub-task
> Components: product server
> Affects Versions: 0.7
> Reporter: Ross Laidlaw
> Assignee: Ross Laidlaw
> Priority: Minor
> Labels: gsoc
> Fix For: 0.7
>
> Attachments: OODT-649.rlaidlaw.2013-07-27.patch.txt
>
>
> Methods in several classes in the cas.product.service.resources package
> retrieve parameters from the servlet context using the
> context.getInitParameter(String parameterName) method call, for example as
> follows:
> {code}
> setWorkingDirPath(context.getInitParameter("filemgr.working.dir"));
> {code}
> But these parameters may contain environment variables such as [HOME] or
> [FMPROD_HOME], etc. Currently, these aren't processed properly and the
> getInitParameter call needs to be wrapped in a call to
> PathUtils.replaceEnvVariables() (from the cas-metadata module) to process the
> environment variables, for example as follows:
> {code}
> setWorkingDirPath(PathUtils.replaceEnvVariables(
> context.getInitParameter("filemgr.working.dir")));
> {code}
> This is already done in the original Data, RDF and RSS servlets but was
> accidentally omitted from the new resource classes in the
> cas.product.service.resources package.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira