By tgardner on Jun 19, 2009
SLAMD3 uses a model-view-controller paradigm to separate the view from the internal database action and action processing. The diagram above depicts the flow of browser requests and the SLAMD response, with emphasis on the Struts2 interceptor framework. The operator issues a request via the SLAMD administrative interface which passes through the interceptor stack (from left to right) until it reaches the Action. The Action is selected by the Struts framework based on the URL from the browser request. For example, the URL http://host:port/slamd/ScheduleJob.action results in Struts2 selecting the Action named "ScheduleJob". Actions are comprised of Java code which executes to satisfy the browser request. When the Action completes, it returns a result (in Struts2 the result is a string such as "success" or "failure") which passes back through the interceptor stack, this time from right to left. The result code string determines which JSP is used to generate the HTML that is displayed in the browser.
Interceptors are used to examine the request in a specific order of interception. Interceptors can be grouped together into a "stack", e.g., the "slamdStack". An arbitrary number of interceptors and interceptor stack groupings can be defined in the configuration file struts.xml, which like other configuration files, must be in the CLASSPATH. SLAMD stores the struts.xml file, the slamd.conf file, and the logging configuration file at the root of the CLASSPATH slamd/WEB-INF/classes.
The interceptors in request order are:
- the timer interceptor (source: xwork) times the execution of the request flow from the invocation of the timer interceptor until the timer result is returned.
- the HTTP create session interceptor (source: Struts2) creates an HTTP session if one does not already exist, and instantiates a session map of type Map<String,Object>. The default interceptor stack will make this session map available to Actions that are SessionAware.
- the cookie interceptor (source: Struts2) inserts the value of cookies based on parameters in the struts.xml file.
- the default stack (source: Struts2) is a group of interceptors defined by Struts that perform various useful functions associated with the request - more about this stack in another blog post
- the history interceptor (source: SLAMD) creates a breadcrumb trail string that is displayed in the browser. The breadcrumbs are implemented as a Map<Session,String> object, allowing each session to have its own breadcrumb trail. Breadcrumbs are useful in tracking the operations performed by the SLAMD administrative interface. The depth of the breadcrumb stack is limited by an interceptor parameter.
- the configuration interceptor (source: SLAMD) reads the configuration file slamd.conf and injects a configuration object into the singleton Config object. SLAMD uses Apache commons configuration, which allows developers to use a number of different configuration source types, for example, properties file, XML file, URL, database, LDAP, and others. Apache commons configuration supports auto-save, so CRUD operations are easily managed, and also supports configuration event creation and notification. The configuration interceptor must execute before any of the SLAMD specific Actions that require configuration parameters defined in the slamd.conf file. Understanding the operation of the configuration interceptor is critical if one wishes to understand the internals of SLAMD.
- the SLAMD cookies interceptor (source: SLAMD) creates certain cookies used by the administrative interface in the event those cookies do not exist. The SLAMD cookies are used to track operator preferences, current folder name, and other user-specific data.
- the authentication interceptor (source: SLAMD) authenticates users if access control is enabled. The authenticator mechanism is controlled by an Authenticator class, defined in the struts.xml file. This version of SLAMD only supports XML-file based authentication with an ELF hash for passwords, very similar to the Tomcat authentication mechanism.
- the database interceptor (source: SLAMD) ensures that the database is created and ready for use. An important enhancement to this version of SLAMD is the ability to use a database at a user-defined location - but that database must still be a SLAMD database!
- the SLAMD server interceptor (source: SLAMD) ensures that the SLAMD server is running.
- the SLAMD scheduler (source: SLAMD) ensures that the SLAMD scheduler is running if the SLAMD server is running.
- the security interceptor (source: SLAMD) is deprecated and will be removed.
- the request info interceptor (source: SLAMD) is deprecated and will be removed
- the job interceptor (source: SLAMD) ensures that job information such as the job class name and job class object are available to Actions.
- the job parameter interceptor (source: SLAMD) creates the dynamic job parameters used by SLAMD and makes those parameters available to Actions.
An Action executes Java code to fulfill the request from the SLAMD administrative interface. Action objects, for example, com.slamd.struts2.actions.JobActions, are created for each request before the interceptor stack executes, therefore, Action initialization cannot rely on any data that would be manipulated by the interceptor stack. Since Actions are created before the interceptor stack executes, interceptors can query actions for data and objects that might be needed for execution of the interceptor. The order of execution of interceptors is vital in determining what data is available to an Action.
Actions not only contain methods that are invoked to perform the task associated with the request, they also interact with JSPs via the ValueStack. Any getter or setter in an Action is accessed via the ValueStack and the results of a get() or set() is available to the JSP that generates HTML. This maintains separation between the Model (Action) and the View (HTML generated by JSPs) and allows changes to either to be made in isolation.
JavaServer Pages are used to generate HTML for display in the browser. JSPs make heavy use of the ValueStack (for access to data in the Action), beans (certain features that do not require SLAMD or the request to be in a certain state), and Struts tags. JSPs are a powerful programming resource that allow the use of dynamic HTML generation by supporting all basic programming constructs (loops, if-then-else) and page generation encapsulation (XML, HTML, character set encoding). Struts tags allow for the automatic conversion of data types such as Maps, Collections, and basic primitive data types to relieve the developer of the burden of the tedious tasks of doing the conversion by hand with special code. The price to pay for this functionality is a somewhat arcane syntax, and that is indeed a small price to pay to ensure isolation and separation of data and views.
Dynamic page generation is used to great effect in SLAMD. Every aspect of page generation is dynamic, for example, page titles, internationalization, CSS inclusion, meta keyword generation, and debugging. Actions can and do influence the title, keywords, CSS media type, and all other aspects of HTML generation.