IBM's Innovation Engineering team is involved in innovation projects in IBM's Green Innovation Data Center (GIDC) in Southbury, CT, USA, looking at both the monitoring and reporting of energy efficiency metrics, and the leveraging of cloud computing techniques to maximize the transactional workload that can be squeezed out of every kilowatt of power that enters the data center. It is from these projects and experiments that the examples presented in this article series are drawn. Part 1 of this series examines a dashboard framework the team built using IBM WebSphere sMash to help show the energy efficiency of the GIDC. Part 2 will show how WebSphere sMash can be used to wrap external systems management tools to provide easy to use APIs, and Part 3 will conclude with a description of how the simplified workflow capabilities of WebSphere sMash can be used to manage automated and manual process steps.
So, let's begin.
Overview of the dashboard project
As a living-lab showcase of leading edge energy efficient infrastructure technology that hosts many internal applications used throughout IBM, the GIDC is a highly instrumented environment. The challenge lies in aggregating and displaying relevant data for various stakeholder profiles: system administrators and owners, business analysts and executives.
The goal of the dashboard project was two-fold:
- To rapidly deliver a dashboard prototype that demonstrates real-time efficiency metrics of the data center to complement the IBM Tivoli solutions deployed in the GIDC.
- To build an API for dashboard data and widgets that could be re-assembled in a variety of ways.
The prototype included a dashboard that visually displayed GIDC efficiency metrics. In addition, we produced a graphical heatmap prototype for showing temperature readings in the machine rooms, including a version optimized for mobile use.
This article explains how we created our dashboards with basic Dojo charting widgets, and why WebSphere sMash was an ideal tool for this scenario. In choosing the run time environment for this prototype project, we noted the following functional and non-functional requirements and how WebSphere sMash might be ideally suited to provide the solution:
- A visually rich dashboard containing dynamic graphs and charts could be rendered using the native Dojo support.
- A composition model of reusable components enabling us to expose the data that we aggregate could be aided through the RESTful API smarts.
- Desire for lightweight configuration is a core philosophy of the WebSphere sMash approach, which works well "out of the box" but provides ample room for configuration.
- Flexibility to start quickly and adapt our requirements along the way, which WebSphere sMash can support through its relatively low to moderate learning curve, helpful online support, and rapid development features.
Let’s walk through the design of our dashboard application and learn how we leveraged some of the rich features of WebSphere sMash to create it.
Dashboards by their very nature tend to be data centric, so quick and easy ways to gather the data that we wanted to present would provide us good productivity benefits.
The GIDC’s historic and real-time data from the data center’s sensors are aggregated into an external monitoring component. This monitoring component exposes the data through a RESTful API as JSON objects. WebSphere sMash includes libraries for making outbound RESTful calls and processing JSON objects, making it an ideal choice for building the dashboards we required.
One of our design choices was to use composition techniques to build up the dashboards in a nested style. This is the nested structure we chose:
- Obtain and expose data as JSON strings from the monitoring component.
- Create and expose widgets that visually illustrate the data points from step 1, obtained using asynchronous (Ajax-style) techniques to support real-time changes in the data.
- Compose a dashboard based on combinations of widgets from step 2.
- Repeat step 3 as necessary to compose dashboards suited to various stakeholders
Figure 1. Overall architecture
Given that the objective of the project was to develop the dashboards, why bother exposing the JSON data and widgets described in steps 1 and 2? Three reasons:
- Exposing these resources as building blocks is ideally suited to an environment where rapid prototyping is taking place. The final design of specific dashboards (or even the widgets) isn’t necessarily known at the outset of the project, so having the flexibility to rewire building blocks together over a short project cycle is important.
- Exposing these resources as building blocks is ideally suited to an environment where rapid prototyping is taking place. The final design of specific dashboards (or even the widgets) isn’t necessarily known at the outset of the project, so having the flexibility to rewire building blocks together over a short project cycle is important.
- There is a technical reason for exposing the data internally. Generally, we want to take advantage of Ajax to asynchronously grab real-time monitoring data and update our dashboard charts without the Web page fully reloading. If we were to try to access this data directly from JavaScript™ in our Web pages, we would run into security problems caused by what is known as "cross-site scripting." This is a security feature of Web browsers that prevents JavaScript from making calls to anything other than the original server domain that served the Web page. By creating a RESTful API local to our project that, on demand, retrieves the monitoring data on the server side, we avoid the need for the retrieval of data from an external server from the client, and therefore avoid the cross-site scripting security constraints.
Let’s now take a look at how using WebSphere sMash made implementing this design so much more straightforward. In this example, we will be describing a widget that shows the power usage effectiveness (PUE) of a data center. PUE is a metric used to indicate the energy efficiency of a data center, and it is calculated by dividing the entire amount of power used by a data center by the power used to run only the computer infrastructure (and not the facilities infrastructure, such as cooling machinery) within it.
Following the composition approach described above, let’s examine each of the steps and take a detailed look at the implementation choices that were made.
As mentioned earlier, the data for the dashboards comes from a variety of sources in the GIDC. The dashboard application exposes the aggregated data it collects in JSON format so that it can be consumed by its own widgets while avoiding cross-site scripting, but also by other prospective consumers of the data. The WebSphere sMash Groovy resource handlers made this process painless. Groovy files with minimal structure placed in WebSphere sMash’s resources directory are automatically exposed as RESTful resources. From a developer’s perspective, the focus is on the application’s business logic -- not on metadata or configuration.
Also, because of the simplicity of the file-based resource handlers, it is easy to create stub data sources while testing. The resources directory in a WebSphere sMash application treats Groovy files in a unique way. When you create a Groovy file in that directory, there are methods in that file that are automatically understood to provide a RESTful API, as is shown in Listing 1.
Listing 1. Default methods in RESTful handlers
def onList() def onCreate() def onRetrieve() def onUpdate() def onDelete() |
So, to write a handler that exposes JSON data describing the change in PUE in the lab, we would first create a file whose function is to expose that data in JSON form, and provide a RESTful interface to call. We’ll call the file pue-trend-data.groovy and it will be placed, by convention, in the WebSphere sMash /app/resources directory.
We then add Groovy code to the file to create the method, onList() that will retrieve and return data points for all PUE trend by making an asynchronous call to the monitoring framework to retrieve the data. This is shown in Listing 2.
Listing 2. Sample code for onList handler in file pue-trend-data.groovy
def onList() {
// get the raw data from the Data Center’s monitoring framework,
which returns a JSON object
// servername is the external monitoring server’s url
def uri = servername +”/rawData”
response = Connection.doGET(uri);
def jsonData = response.getResponseBodyAsString();
decodedJson = Json.decode(jsonData);
def retArray = new ArrayList();
//do some additional scrubbing on the data so that it can be
better consumed by third party users and our widgets. This is
the scrubbed data that our application is exposing internally and
externally.
def retArray = scrubAndProcessData(decodedJson);
//return the scrubbed data in JSON format
request.json.output= retArray;
request.view="JSON";
render();
}
|
In this example, we captured the response data using response.getResponseBodyAsString(), but more options are available from the WebSphere sMash Connections API. For example, response.getResponseBodyInputStream(), is a more generic method for handling response of various content types and sizes.
A complementary method to onList() is onRetrieve(). While onList() returns an array of datapoints, onRetrieve() returns data for a specific object, based on the parameter provided. In this case, the parameter is the timestamp for which the consumer wants to retrieve the PUE value.
Remember, these methods are automatically triggered by the WebSphere sMash framework when the corresponding URL is requested by a user or a programmatic request of the service. No additional configuration is required; the framework knows to call these methods when an HTTP GET request is received on the corresponding URL.
Listing 3 shows the URL request and the JSON string that is returned by the onList() method. The JSON results contain the PUE calculation for each time interval.
Listing 3. URL and returned JSON to retrieve power trend data
Request URL:
http://localhost:8080/resources/pue-trend-data
JSON Response:
[
{"pue":1.222445,"timestamp":"2010-01-30-1200-AM"},
{"pue":1.322445,"timestamp":"2010-01-30-0100-AM"},
{"pue":1.422445,"timestamp":"2010-01-30-0200-AM"},
...
]
|
Code to handle the case of retrieving data for a single time point would be
similar. In this case, we would use the onRetrieve() method in the
handler, and the result would be for one timestamp, say 2010-01-30-0200-AM, not the whole list.
When a user issues one of the two requests, WebSphere sMash will automatically forward the request to the appropriate handler, onList() or onRetrieve(), depending on whether or not a URL parameter has been supplied. Both will be HTTP GET requests. No manual configuration is required! Listing 4 shows the request URL and sample JSON response for onRetrieve().
Listing 4. URL and returned JSON to retrieve the PUE value for 2010-01-30 at 02:00 AM
Request URL:
http://localhost:8080//resources/pue-trend-data/2010-01-30-0200-AM
JSON Response:
{"pue":1.422445,"timestamp":"2010-01-30-0200-AM "}
|
Below is the simple WebSphere sMash construct that is used in onRetrieve() to extract the passed in parameter. The method call params.pue-trend-dataId[] automatically retrieves the parameter from the URL. This is a WebSphere sMash convention.
String pueValue = request.params.pue-trend-dataId[]
See Resources for more information behind some of the concepts covered so far.
Next, a look at how we turned the numeric data into charts.
Displaying the data in a widget
The previous step looked at managing the data layer. Now, let’s look at how we built widgets to illustrate the data.
You have already seen how we exposed the data through an API. For the widgets, we followed a similar pattern. In other words, not only is the data exposed RESTfully by the application, but the chart widgets are exposed with the same pattern, but with distinct endpoint URLs.
The widgets are built out of two primary ingredients that we already have: Dojo toolkit constructs and the data. Our task is to wire those to elements together.
Each widget is comprised of a Groovy template (.gt file) and supporting JavaScript. Groovy templates are essentially HTML with embedded Groovy snippets, analogous to a JSP file in a J2EE application. The .gt file is responsible for building the layout of the widget, and provides <div> elements that act as anchors for the insertion of the Dojo widgets. The complimentary JavaScript code defines the specifics of the Dojo charts.
Groovy templates, by WebSphere sMash convention, live in the /app/views directory. JavaScript, CSS files and any other images live under the /public directory structure. Listing 6 shows sample code for a widget that illustrates server power. We will name the file that contains the widget code pue_trend_widget.gt.
Listing 6. Sample Code for pue_trend_widget.gt
<%= invokeTemplate(getRelativeUri("widgetheader.gt")) %>
<script src="scripts/pue-trend.js"></script>
<script language="JavaScript">
/*
* Function called when the page is finished loading
*/
Dojo.addOnLoad(function() {
initPueTrendChart();
});
</script>
<!-- Build a pane that will contain puePowerChart -->
<div id=”pueTrendChartPane" jsId="pueTrendChartPane"
dojoType="dojox.layout.ContentPane" class="widget-wrapper"
executeScripts="true" parseWidgets="true" adjustPaths="true"
renderStyles="true">
<div class="widget-header">
<h3 >PUE Trend </h3>
</div>
<!-- the following <div> is intentionally empty.
The JavaScript will embed the Dojo chart there.
-->
<div id="pueTrendChart"></div>
</div>
|
The JavaScript file pue-trend.js, referenced by the .gt file in Listing 6, lives in /public/scripts and is shown in Listing 7. It makes an asynchronous call to the data that we exposed RESTfully in the previous step.
Listing 7. Sample code for pue-trend.js
var pueTrendChart;
function initPueTrendChart () {
//Initialize the pue compare chart
pueTrendChart = new dojox.charting.Chart2D("pueTrendChart");
pueTrendChart.addPlot("default", {type: "Lines", vMajorLines:
true,labels:true,htmlLabels: true,markers: true ,tension:3,
shadows: {dx: 2, dy: 2, dw: 2} });
//calling getData helper, method to get data from resource and build chart here
getData("pue-trend-data", updateChart, pueTrendChart);
var anim_c = new dojox.charting.action2d.Tooltip(pueTrendChart, "default");
}
function getData (resourceExtension, helperMethod, chartName) {
//this function gets Data from the local RESTful API we exposed in the previous
step. It passes JSON response to updateChart
dojo.xhrGet({
url: "/resources/" + resourceExtension,
load: function(response, ioArgs) {
var respJson = dojo.fromJson(response);
//calling updateChart function here
helperMethod(chartName, respJson);
chartName.resize(dojo.byId(serverPowerChart).clientWidth-100, 400);
},
// the following is necessary. if you leave out the error clause,
if an error happens within the load clause, you won’t know about it
error: function (response) {
console.error('Error: ', response);
}
});
}
unction updateChart(id, values) {
//this function adds the data to the power chart and renders it.
id.addAxis("x",{labels: values[1],minorLabels: true
,majorLabels: true,majorTickStep: 2});
id.addAxis("y", {vertical: true,includeZero: true, min:0,
max:3,majorTickStep: .25});
id.addSeries("series1",values[0]);
replaceChartTitle(values[2],values[3]);
id.render();
id.resize(dojo.byId('pueTrendChartPane').clientWidth-10,
PUE_TRENDS_CHART_HEIGHT);
}
}
|
Finally, the .gt file must be referenced by some URL. We use the same "resource" pattern described for exposing data. In the resources directory, we placed a file named pue-true-chart.groovy. Instead of it returning JSON, as in the case of our data resource, we will have the resource return a reference to a view. Listing 8 shows the contents of the resource handler that exposes the widget view we created.
Listing 8. pue-trend-widget.groovy resource handler
def onList () {
request.view="/pue_trend_widget.gt"
render()
}
|
Keep in mind that using the /resources folder is not the only way to implement a RESTful pattern in WebSphere sMash, but doing so makes life a little easier in situations where you want to use the default handlers.
Putting it all together, you get a widget that looks like that shown in Figure 2, ready for inclusion on an HTML page.
Figure 2. PUE trends sample widget
Be aware that in order for the widget to load, the containing HTML page must contain the tags to bootstrap Dojo, as well as import the required Dojo libraries. The required snippets are included in Listing 9. For this reason, attempting to load the widget directly from the browser bar at address http://localhost:8080//resources/pue-trend-widget will fail; the widget needs to be loaded in the context of an HTML page with the correct Dojo libraries bootstrapped.
There is, however, no need to load the Dojo library files themselves manually into your WebSphere sMash application. The next section describes how to use WebSphere sMash to add them to your project in one step using the WebSphere sMash dependency management functions.
Listing 9. Example loading of Dojo libraries
<script type="text/JavaScript" src="dojo/dojo.js"
djConfig="parseOnLoad: true">
</script>
<script type="text/JavaScript">
dojo.require("dojo.parser");
dojo.require("dojox.charting.Chart2D");
… //add additional required Dojo libraries here
</script>
|
Before leaving this section, let’s just briefly mention some other choices that WebSphere sMash affords you when building Web widgets. We chose to expose our widgets in the resources directory to facilitate RESTful access to them. WebSphere sMash provides an alternative optional convention for organizing your custom Dojo widgets:
- Widget source files are placed under the /app/zwidgets/ folder to simplify tooling integration. This convention can be used, for example, to add your widgets to the palette in the visual page editor.
- Another approach supported in WebSphere sMash is to use iWidgets. The iWidget standard lets you create standardized widgets that can be composed in mashup frameworks such as those found in products like IBM Lotus Mashups and IBM WebSphere Portal. While our first iteration of the dashboards project did not leverage iWidgets, we have plans to experiment with iWidgets in the future.
- Yet another technique involves using the Zero Resource Model implementation of the Dojo Store extension. This helps provide a simplified interaction between RESTful data and JavaScript and Dojo widgets
See Resources for more information.
Rendering the widgets in a dashboard Web page
The final part of the composition is to create a dashboard Web page.
Listing 10 showed the Groovy file, trends.groovy in the /public directory, which included code that refers to the view for the dashboard. As in the case of the widget, we use a .gt file to enable us to easily embed Groovy snippets in our HTML.
Next, Listing 11 shows the view that builds the page that contains our widget. Listing 9 showed how we load the required Dojo libraries onto the page. From that starting point, let’s add in what we need to load the widget, leaving out other HTML details on the page to keep the example simple.
Since Dojo lets you assign a target URL to a div container, we create a div that will reference our widget that we exposed as a resource. In this case, we instruct Dojo to load the widget that we exposed at the path resources/pue-trend-widget.
As you build additional widgets, you can add them to the same or new dashboard views using this technique.
Listing 11. The public reference to the dashboard, trends.groovy
def onGET () {
request.view="/dashboard_layout/trends.gt"
render()
}
|
Listing 12. The view that builds the dashboard, trends-dashboard.gt
<html>
<head>
<script type="text/JavaScript" src="dojo/dojo.js"
djConfig="parseOnLoad: true">
</script>
<script type="text/JavaScript">
dojo.require("dojo.parser");
dojo.require("dojox.charting.Chart2D");
... //add additional required Dojo libraries here
</script>
...
</head>
<body>
...
<div id="trendsPueChartParentPane" jsId="trendsPueChartParentPane"
dojoType="dojox.layout.ContentPane" href="resources/pue-trend-widget"
closable="false" resizeable="false" maxable="false" dockable="false" ></div>
...
</body>
</html>
|
Figure 3 illustrates what the final dashboard looks like after putting all this together. Adding more widgets to the view is a simple matter of embedding additional div elements to reference each widget that is to be included.
Figure 3. GIDC dashboard WebSphere sMash application
The graphs in the widgets leverage the Dojo charting API to create interactive components. For example, the user can hover over a datapoint to learn the specific PUE at that point in time.
The way WebSphere sMash includes Dojo libraries facilitated a quick start in the environment. There were no additional packages that we needed to manually download and then manually configure. Instead, the necessary Dojo components are downloaded as required from a Project Zero repository, automatically, as part of WebSphere sMash’s internal dependency-management system. To enable your application to use Dojo, add zero.dojo as a dependency to your application. You can do this on the Dependency tab from within the WebSphere sMash browser-based AppBuilder interactive development environment. This even includes a visual editor for getting started with designing Dojo-rich pages quickly. You’ll find quickly that some comfort with JavaScript is useful for wiring widgets to actions. See Resources for more information to help you get started with Dojo in WebSphere sMash.
One final piece of useful information when considering deploying your WebSphere sMash based Dojo application: Dojo, when used for development tasks, is not optimized for performance. As a result, during page loads, numerous sequential synchronous Ajax calls are made to load JavaScript snippets to support the Dojo widgets.
Tools such as the Firebug plug-in for Firefox are useful for seeing these loads in action. To improve performance, create a custom build of the Dojo libraries that you need so that JavaScript resources are combined and compressed, resulting in fewer required loads.
Using this custom build, you will likely see the number of JavaScript loads decrease dramatically. In one case, we reduced the number of calls from 100 to 7 with this technique and substantially improved page load performance.
Part 1 of this article series explained how a visually rich Web application can be built using solid SOA principles, using the conventions behind the WebSphere sMash programming model and tooling. In Part 2, you will see how WebSphere sMash can be used to build a RESTful API wrapper around some legacy Java™ tools used to wrap external systems management tools, and examine more ways in which the conventions of the WebSphere sMash programming model can be used to support rapid application development.
Thanks to Heather Smith, Software Engineer, IBM, for contributing code toward the examples provided here.
Learn
-
Project Zero documentation:
- HTTP REST API
- Client programming with Dojo
- Using Dojo with the Zero Resource Model
- Quick Dojo tutorial
-
Introducing IBM WebSphere sMash, Part 1: Build RESTful services for your Web application
-
Groovy: An agile dynamic language for the Java Platform
-
dojox.charting
documentation
-
The Official Dojo Documentation
-
IBM
Green Innovation Data Center helps developers build green technology
-
Project
Zero
-
IBM developerWorks
WebSphere sMash zone
-
IBM developerWorks
WebSphere
Get products and technologies
-
Download WebSphere sMash Developers
Edition (free of charge)
Aaron Kasman is a software engineer in IBM Software Services for WebSphere where he has worked with WebSphere Commerce, specializing in Eclipse rich client application development. He is also a collaborative-technology enthusiast.
Andy Bravery is a Senior Technical Staff Member, Executive IT Architect and Manager of the Innovation Engineering team in the IBM CIO Office. Mr Bravery has a rich background of experience working in the emerging technology field. His recent work has been around exploiting cloud technologies to support situational applications in the enterprise. Mr. Bravery is a member of the British Computer Society & an Open Group Certified Master IT Architect and holds an honours degree in Physics from the University of Birmingham, UK.




