Innovative uses for WebSphere sMash, Part 1: Building a flexible, practical dashboard framework

When new technologies emerge -- programming languages and models in particular -- there typically follows a period where many useful "how to" articles appear to help developers get themselves started. As time passes, the guidance works its way deeper into the more advanced concepts, but it is not often that the implementation details behind an actual application of the technology is revealed. "Hello World" examples are fine for basic lessons, but as you reach the point of wanting to build something yourself, there is nothing like a real example to help provide the inspiration for that next killer application project.

This article series presents three actual examples where IBM® WebSphere® sMash was selected and used to perform innovative and valuable tasks. These examples are all related to the operations of IBM's Green Innovation Data Center (GIDC), which has been set up both as a client briefing center and a living lab, where some of IBM's latest energy efficient hardware, software, and operational practices are being tested and developed. In Part 1, you'll see how WebSphere sMash was used to build a flexible framework for constructing data center dashboards. This content is part of the IBM WebSphere Developer Technical Journal.

Share:

Aaron Kasman (akasman@us.ibm.com), Advisory Software Engineer, IBM

Aaron Kasman is an advisory software engineer in the Innovation Engineering team in the IBM CIO Office where he focuses on internal Platform-as-a-Service (PaaS) offerings, with an interest toward supporting innovators and situational application development. Prior to this role, he was part of the IBM Software Services for WebSphere team developing IBM.com’s e-commerce presence. His interests include WebSphere sMash, Platform and Software-as-a-Service technologies, content and community management with Drupal and CiviCRM, and visual design.



Andrew J. F. Bravery (abravery@us.ibm.com), Senior Technical Staff Member, Executive IT Architect, IBM

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.



26 May 2010

Introduction

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.


Architecture and design

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:

  1. Obtain and expose data as JSON strings from the monitoring component.
  2. 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.
  3. Compose a dashboard based on combinations of widgets from step 2.
  4. Repeat step 3 as necessary to compose dashboards suited to various stakeholders
Figure 1. Overall architecture
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.


Implementation details

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.

Exposing the data

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
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
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.


Conclusion

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.


Acknowledgements

Thanks to Heather Smith, Software Engineer, IBM, for contributing code toward the examples provided here.

Resources

Learn

Get products and technologies

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere, Web development
ArticleID=482474
ArticleTitle=Innovative uses for WebSphere sMash, Part 1: Building a flexible, practical dashboard framework
publish-date=05262010