HQU Controllers Views
HQU plugins act in an MVC framework. The model is largely provided by the HQ server and backend. Views consist of HTML chunks combined with Groovy control elements. Controllers are the liaison between the rendered HTML and the backend data.
A request cycle looks like this:

Controllers
Controllers act on HTTP requests into the HQ server. Incoming request URIs are broken down like this:
http://localhost:7080/hqu/plugin_name/controller_name/action_name.hqu
For the purpose of example, assume a URL like: http://localhost:7080/hqu/pinger/madcast/execute.hqu
Where:
- pinger is the name of plugin. This is the name of the directory of plugins in the ui_plugin directory.
- madcast is the name of the controller in the plugin's /app directory. This part of the URL maps directly to the file ui_plugins/pinger/app/MadcastController.groovy
- execute is the name of the method in the controller to execute (also known as the action)
When the above URL is requested, MadcastController.execute() is invoked. If the following looks funny, read up on some of Groovy's features such as Property-accessor methods (s.getProp() == s.prop).
import org.hyperic.hq.hqu.rendit.BaseController
class MadcastController extends BaseController {
def execute(params) {
def timeout = params.getOne('timeout', 60 // default timeout if not in URL)
def resources = lookupAndValidateResources(timeout, params.ids)
def start = now
def errors = ExternalProgram.execute(timeout, resources)
log.info "Mastcasted to ${resources.size()} resources in ${now - start}ms"
render(locals:[
castTime:now - start,
isAdministrator: user.hasAdminPrivilege(),
errors: errors])
}
private getNow() {
System.currentTimeMillis()
}
private lookupAndValidateResources(timeout, ids) {
....
}
}
Request and Action
Controller methods are executed with a map of query-parameters coming from the HTTP request. In the case of a request like:
http://localhost:7080/hqu/pinger/madcast/execute.hqu?timeout=300&id=3&id=4
The execute method (the action) will be called with a map of the HTTP query parameters.
Each query parameter can exist multiple times (we can specify multiple id= keys), so the value of each key is a list of values. However, it is often convenient to just grab 1 value from the URL, so a convenience function called .getOne() is provided.
def lotsOfIds = params['id'] // = [3, 4]
def singleId = params.getOne('id']) // = 3
render() and GSPs
When a controller action executes, its default behaviour is to render a view by the same name of the action. For instance, if the controller at /app/SpeechController.groovy looked like:
def resetHardware() {
HardwareDevice.reset()
}
it would render the file /views/speech/chuckle.gsp automatically.
A GSP is a mixture of HTML (or XML, or any text) and Groovy code. Most-often, GSPs need to provide variables to the render() method, so they typically call it anyway and use the locals parameter to define which variables and values get passed into the template.
def chuckle() {
render(locals:[chuckleType:'chortle'])
Will create a variable called 'chuckleType' which is usable in .gsp (such as <p>I give a slight ${chuckleType}</p)
More documentation on the render() method can be found in RenderFrame Documentation
State
The controller object is instantiated only for the lifetime of the request. Each new request gets an entirely new instance of the controller. Any local variables within the controller only exist for the duration of the request.
Views
Views are organized by their controller name. When the execute() method is invoked in the MadcastController, we'd like to display a result page to the client. By default, this view is in:
/ui_plugins/pinger/views/madcast/execute.gsp
In addition, templates provide a way to re-use markup for different actions. These templates are stored in:
/ui_plugins/pinger/views/templates
The GSPs are similar to JSPs (Java Server Pages), except they execute Groovy script. See Groovy Server Pages. GSPs can include any markup, mingled with special GSP tags.
<p>
Executed cluster broadcast in ${castTime / 1000} seconds.
</p>
<% if (isAdministrator) { %>
<p>
<% for (p in errorPackets) { %>
Error: <%= p.error %><br/>
<% } %>
</p>
<% } %>
The special tags include:
- ${expression} Executes a Groovy expression and places the result into the HTML stream
- <% something %> Executes a block of Groovy code. Useful for placing conditionals and looping statements
- <%= expression %> Similar to ${expression}}, executes the expression and places the result into the stream