Presentation is loading. Please wait.

Presentation is loading. Please wait.

Writing a Custom DispatchHandler

Similar presentations


Presentation on theme: "Writing a Custom DispatchHandler"— Presentation transcript:

1 Writing a Custom DispatchHandler
OLFS Extensions Writing a Custom DispatchHandler

2 Extending the OLFS Extension ‘modules’ written in Java
Jar files added to a directory within Tomcat and called out in the olfs.xml file. The new modules have complete access to the request information Both HTTP GET and POST requests There is some significant processing done before the handler is called: Conditional GET Requests (Handler is called on to provide last modified dates) Authorization & Authentication

3 OLFS Dispatch Handlers
The OLFS uses an ordered list of Dispatch Handlers to handle requests. Each handler on the list is asked if it can handle the incoming request. The first handler on the list that claims the request gets to handle it. List order is important, as some handlers (for example THREDDS) may claim to handle requests that could (should) be handled by a different handler. Handlers are free to do anything they need to handle a request: Contact a remote system/process, read files, spawn threads, et cetera. HTTP GET and POST requests are serviced by handlers that implement the same DispatchHandler interface. It is certainly possible to write a DispatchHandler that could service both types of requests.

4 DispatchHandler Interface
Dispatch Handlers must implement the DispatchHandler interface: public interface DispatchHandler { public void init(DispatchServlet servlet, Element config) throws Exception; public boolean requestCanBeHandled(HttpServletRequest request) public void handleRequest(HttpServletRequest request, HttpServletResponse response) public long getLastModified(HttpServletRequest req); public void destroy(); }

5 Dispatch Handler Interface: init() method
Declaration: public void init(DispatchServlet servlet, Element config) throws Exception; Parameters: servlet: This will be the DispatchServlet that creates the instance of DispatchHandler that is being initialized. DispatchServlet is a child of HttpServlet. config: A JDOM Element object containing the XML Element that announced which implementation of DispatchHandler to use. It may (or may not) contain additional confguration information. Exceptions: Throws an Exception when the bad things happen. Since a constructor cannot be defined for an interface there needs to be a way to initialize the objects state. The init() method is that way. The DispatchServlet that creates an instance of DispatchHandler will pass itself into it along with the XML element that declared the DispatchHandler in the configuration file (usually olfs.xml). The contents of this XML Element are not restricted and may (should?) contain any required information for configuration not available by interogating the DispatchServlet’s methods.

6 Dispatch Handler Interface: requestCanBeHandled() method
Declaration: public boolean requestCanBeHandled(HttpServletRequest request) throws Exception; Parameters: request: The request to be handled. Return: True if the DispatchHandler can service the request, false otherwise. Exceptions: Throws an Exception when the bad things happen.

7 Dispatch Handler Interface: handleRequest() method
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception; Parameters: request: The request to be handled. response: The response object thru which the response information will placed/written. Exceptions: Throws an Exception when the bad things happen.

8 Dispatch Handler Interface: getLastModified() method
Declaration: public long getLastModified(HttpServletRequest request); Parameters: request: The request for which we need to get a last modified date. Return: The last modified date of the URI referenced in the request. If the date cannot be determined then return -1. Exceptions: May not throw an Exception.

9 Dispatch Handler Interface: destroy() method
Declaration: public void destroy(); Parameters: None Return: None. Exceptions: May not throw an Exception. Destroy() is called when the servlet is shutdown. Here is where to take care of any housekeeping chores, clean up open connections, etc.

10 DispatchHandler: A Simple Example
For a simple example we can leave the init() and destroy() methods empty

11 requestCanBeHandled() method:
public boolean requestCanBeHandled(HttpServletRequest request) throws Exception{ String sName = ReqInfo.getFullSourceName(request); return sName.startsWith("/helloWorld"); } This simple test will cause our example DispatchHandler to claim all requests that begin with “/helloWorld” For a simple example we can leave the init() and destroy() methods empty

12 handleRequest() method:
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception{ response.setContentType("text/html"); response.setStatus(HttpServletResponse.SC_OK); String msg = "<html><body><br><br><br><br>"; msg += "<center><h1>HELLO WORLD!</h1></center>"; msg += "</body></html>"; response.getWriter().print(msg); } Provides a simple “Hello World” response.

13 getLastModified() method:
public long getLastModified(HttpServletRequest request) { return -1; } Returning a negative one will cause the page to always reload. Since the Last Modfied time is meaningless for this example we punt and return -1 and force a reload.

14 Installing your Handler
Edit the olfs.xml file in $CATALINA_HOME/content/opendap Add your new DispatchHandler implementation to the list of handlers by inserting XML element: <Handler className="bom.tutorial.ExampleDispatchHandler" /> Immediately after the BESManager handler. Restart Tomcat. Since the Last Modfied time is meaningless for this example we punt and return -1 and force a reload.

15 Testing your Handler Point your browser at: Since the Last Modfied time is meaningless for this example we punt and return -1 and force a reload.

16 Experiment Edit the olfs.xml file in $CATALINA_HOME/content/opendap
Move the element that defines your handler to the end of the handler list and restart Tomcat. Try other permutations of the Handler list (be sure to restart Tomcat after each change). This will probably break Hyrax :) Since the Last Modfied time is meaningless for this example we punt and return -1 and force a reload.

17 DispatchHandler: A File Service

18 FileService: init() method
public void init(DispatchServlet s, Element config) throws Exception { if(initialized) return; String dir; Element dv = config.getChild("TopDir"); if(dv!=null){ dir = dv.getTextTrim(); if(dir!=null) { File f = new File(dir); if (f.exists() && f.isDirectory()) fileRoot = dir; else fileRoot = s.getServletContext().getRealPath("docs"); } while(fileRoot.endsWith("/")) fileRoot = fileRoot.substring(0,fileRoot.length()-1); log.info("fileRoot: " + fileRoot); initialized = true; Doesn’t allow multiple initialization. Checks configuration for passed state information.

19 FileService: init() method
public void init(DispatchServlet s, Element config) throws Exception { if(initialized) return; String dir; Element dv = config.getChild("TopDir"); if(dv!=null){ dir = dv.getTextTrim(); if(dir!=null) { File f = new File(dir); if (f.exists() && f.isDirectory()) fileRoot = dir; else fileRoot = s.getServletContext().getRealPath("docs"); } while(fileRoot.endsWith("/")) fileRoot = fileRoot.substring(0,fileRoot.length()-1); log.info("fileRoot: " + fileRoot); initialized = true; Doesn’t allow multiple initialization. Checks configuration for passed state information.

20 FileService: requestCanBeHandled() and handleRequest() methods
public boolean requestCanBeHandled(HttpServletRequest request) throws Exception{ return fileService(request,null,false); } public void handleRequest(HttpServletRequest request, HttpServletResponse response) fileService(request,response,true); Both of these methods call on the fileService() method to perform both the handling evaluation and the response evaluation. The code for determining what to do is reused via a simple boolean switch. This way there is only decision tree to maintain.

21 FileService: fileService() method
private boolean fileService(HttpServletRequest request, HttpServletResponse response, boolean sendResponse) throws Exception{ String path = getPath(request); boolean isFileRequest = false; if(path!=null){ isFileRequest = true; if(sendResponse){ File file = new File(path); if(file.exists()){ if(file.isDirectory()) sendDirPage(file,request, response); else if(file.isFile()) sendFile(file,response); else sendFileNotFound(response); } else { } return isFileRequest; Claims the request, and if required send the appropriate response.

22 FileService: getPath() method
private String getPath(HttpServletRequest req){ String sName = ReqInfo.getFullSourceName(req); String path = null; if(sName.startsWith(urlPrefix)){ path = sName.substring(urlPrefix.length(),sName.length()); if( ! path.startsWith("/")) path = "/" + path; path = fileRoot + path; } return path; Checking for the leading urlPrefix (which was set in the init() method via the configuration file) is h mechanism by which the FileService determines it’s “claim” to a request.

23 FileService: getLastModifed() method
public long getLastModified(HttpServletRequest req){ String path = getPath(req); if(path!=null){ File file = new File(path); if(file.exists()) return file.lastModified(); } return -1; Utilizes the getPath() method. Ignores a bad return (that will be handled later with a 404 page). Interacts directly with the file system to ascertain the last modified date of the file/directory. The implementation of getLastModified() will always be very closely coupled to the back end sdat store. In this case the file system.

24 Installing your Handler
Edit the olfs.xml file in $CATALINA_HOME/content/opendap Add your new DispatchHandler implementation to the list of handlers by inserting XML element: <Handler className="bom.tutorial.FileService> <TopDir>/path/of/dir/to/access</TopDir> </Handler> Immediately after the BESManager handler. Restart Tomcat. Since the Last Modfied time is meaningless for this example we punt and return -1 and force a reload.

25 FileDispatchHandler: A Hyrax DispatchHandler.
Hyrax will serve files that it does not recognize as data. It is also possible to configure Hyrax to allow users to directly download the source data files. For a simple example we can leave the init() and destroy() methods empty

26 FileDispatchHandler: init() method
public void init(DispatchServlet servlet,Element config) throwsException { if(initialized) return; Element dv = config.getChild("AllowDirectDataSourceAccess"); if(dv!=null){ allowDirectDataSourceAccess = true; } log.info("Intialized. Direct Data Source Access: ” + (allowDirectDataSourceAccess?"Enabled":"Disabled") ); initialized = true; Doesn’t allow multiple initialization. Checks configuration for passed state information.

27 FileDispatchHandler: requestCanBeHandled() and handleRequest() methods
public boolean requestCanBeHandled(HttpServletRequest request) throws Exception { return fileDispatch(request, null, false); } public void handleRequest(HttpServletRequest request, HttpServletResponse response) if(!fileDispatch(request, response, true)) log.debug("FileDispatch request failed inexplicably!"); public boolean fileDispatch(HttpServletRequest request, HttpServletResponse response, boolean sendResponse) throws Exception; The code for determining what to do is reused via a simple boolean switch. This way there is only decision tree to maintain.

28 FileDispatchHandler: fileDispatch() method
public boolean fileDispatch(HttpServletRequest request, HttpServletResponse response, boolean sendResponse) throws Exception { DataSourceInfo dsi = new BESDataSource(ReqInfo.getFullSourceName(request)); boolean isFileResponse = false; if (dsi.sourceExists()) { if (!dsi.isCollection()) { isFileResponse = true; if (sendResponse) { if (!dsi.isDataset() || allowDirectDataSourceAccess) { sendFile(request, response); } else { sendDirectAccessDenied(request, response); } return isFileResponse; The code for determining what to do is reused via a simple boolean switch. This way there is only decision tree to maintain. This handler interrogates the BES to get information about the requested item.

29 Summary DispatchHandler implementations are free to conduct business using any available tools Sockets JDBC File Systems Etc. Care should be taken in ordering them in the olfs.xml configuration file. Improper ordering can create unintended results, including disabling of desired functionality.


Download ppt "Writing a Custom DispatchHandler"

Similar presentations


Ads by Google