Hacking the webapp

From OpenNMS
Jump to: navigation, search

Architecture

Webapp is short for "web application"; we also refer to it as the webUI, short for "web user interface". This represents the main interface for users to OpenNMS. It is a Java servlet application with many individual servlets and JSP pages. We are migrating from plain servlets and JSP pages to use Spring MVC, Vaadin, and eventually Javascript frameworks built over our REST interface. This page will discuss the old style of web code, which we will call legacy, and the new style with Spring MVC, but first we will start with configuration.

Note: all of the references to files in this page are relative to the opennms-webapp directory in the source distribution.

You might want to read up on Spring MVC a bit. This article might help out.

Configuration

The webapp as a whole is driven the web.xml file in src/main/webapps/WEB-INF/web.xml. This is meant to be a file that should not need to be edited by users. Any localized configuration for users should be done in configuration.properties. This is in src/main/web-filtered/WEB-INF/configuration.properties in the source, and ends up sitting right next to the web.xml file in WEB-INF in the generated webapp.

web.xml

Documentation of web.xml options can be found here

To set the login timeout to zero, add:

<session-config>
    <session-timeout>-1</session-timeout>
</session-config>

For a 15 minute timeout the line would read:

<session-config>
    <session-timeout>15</session-timeout>
</session-config>

Important.png Important note

If you set the timeout to -1, you risk causing a session object leak. Instead consider using a "AddRefresh" entry in web.xml for the path that is giving you timeouts

configuration.properties

Spring MVC applications

Layout

  • opennms-webapp/
    • src/
      • main/
        • webapp/
          • WEB-INF/
            • dispatcher-servlet.xml
            • jsp/
        • java/
          • org/
            • opennms/
              • web/
                • command/
                • controller/
                • svclayer/
                • validator/

Descriptions

  • Controller in org.opennms.web.controller, which returns a ModelAndView (usually). That will get to your JSP, with the "model" trivially available
    • To generate your model, often use classes in org.opennms.web.svclayer to create it.
    • The controller should be very simple since it is difficult to unit test. All of the work should be in the service layer.
  • Create your JSP in opennms-webapp/src/main/webapp/WEB-INF/jsp/<whatever>
    • This should be very simple, not major logic in it
    • In your JSP, you can use ${} syntax to access the model

Request flow

Here is the example request flow for a Spring MVC 2.0-style request. Assume the URL is something like "/opennms/foo.htm".

  1. A request comes in over HTTP to the Jetty servlet container.
  2. The request URL begins with /opennms/ and is sent to the servlet context for /opennms.
  3. The request URL ends with ".htm", so it is identified to be sent to the "dispatcher" servlet. This is configured with a "servlet-mapping" in web.xml.
  4. The "dispatcher" servlet is set to org.springframework.web.servlet.DispatcherServlet. This servlet has "load-on-startup" enabled so it is loaded when the servlet context loads. Its configuration file is dispatcher-servlet.xml and it inherits the root web application context loaded by Spring's ContextLoaderListener. This servlet is configured in web.xml.
  5. The relative request URL (relative to the context root) is matched against controller beans listed in dispatcher-servlet.xml.
  6. The request controller is invoked.
  7. Depending on which abstract Spring controller class is extended (if any) and how the controller is configured, a command object may be created and validated.
  8. XXX more stuff

Application Context

The root web application context is loaded by Spring's ContextLoaderListener. It is the last listener configured in web.xml. Its configuration is loaded from the bean files listed in the contextConfigLocation "context-param". Specific servlets like the "dispatcher" servlet (org.springframework.web.servlet.DispatcherServlet), "mapDispatcher" (org.springframework.web.servlet.DispatcherServlet), "Resources Servlet" (org.springframework.js.resource.ResourceServlet) and the "opennmsRestWebServices" servlet (com.sun.jersey.spi.spring.container.servlet.SpringServlet).

Vaadin applications

Vaadin is a UI framework that is built on top of the Google Web Toolkit (GWT) where almost all UI code is written in pure Java. If additional UI controls are required, they can be written as GWT components and integrated into the main application.

We have several projects now that use Vaadin as the UI technology including the Topology Maps (features/topology-map), the Geographical Maps (features/vaadin-node-maps), the JMX Configuration UI (features/jmx-config-generator-webui), and the Dashlets (features/vaadin-dashlets).

Legacy applications

Sending events to the OpenNMS daemon

Use Util.createEventProxy() to get an EventProxy instead of creating a TcpEventProxy directly. Util.createEventProxy() will use a default hostname and port of localhost:5817 to communicate with eventd in the daemon, but this can be overridden by the opennms.rtc.event.proxy.host and opennms.rtc.event.proxy.port properties in configuration.properties.

Debugging

Seeing what attributes are accessible in a page

Include opennms-webapp/src/main/webabpp/WEB-INF/jspf/showRequestDetail.jspf to get a set of tables showing the data that is available in the JSP page in the following sets of data:

  • Request attributes
  • Session attributes
  • Servlet init parameters
  • Servlet context attributes

To use this in a JSP page, add this to a part of the page that will be displayed:

<%@ include file="/WEB-INF/jspf/showRequestDetail.jspf" %>

Note: this exposes some juicy bits like encrypted passwords, so don't ever commit a page containing this.