<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Opsview Labs &#187; Frameworks</title>
	<atom:link href="http://labs.opsview.com/frameworks/feed/" rel="self" type="application/rss+xml" />
	<link>http://labs.opsview.com</link>
	<description>Opsview&#039;s Engineering Blog</description>
	<lastBuildDate>Fri, 20 Jan 2012 09:32:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>10 Ways to Make Your Monitoring System Scale</title>
		<link>http://labs.opsview.com/2011/09/10-ways-to-make-your-monitoring-system-scale/</link>
		<comments>http://labs.opsview.com/2011/09/10-ways-to-make-your-monitoring-system-scale/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 09:00:27 +0000</pubDate>
		<dc:creator>tcallway</dc:creator>
				<category><![CDATA[Forked software]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[MSPs]]></category>
		<category><![CDATA[Nagios]]></category>
		<category><![CDATA[Opsview]]></category>
		<category><![CDATA[SNMP]]></category>
		<category><![CDATA[System Management]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[business systems]]></category>
		<category><![CDATA[icinga]]></category>
		<category><![CDATA[multi-tenancy]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[network monitoring]]></category>
		<category><![CDATA[open source monitoring]]></category>

		<guid isPermaLink="false">http://labs.opsview.com/?p=1009</guid>
		<description><![CDATA[
			
				
			
		
Freeware IT monitoring tools are used by thousands of organisation worldwide however using them to monitor complex network, server and application installations can be quite a challenge.  This blog post takes the basic capabilities of one such tool, Nagios® Core, and shows how you can scale it with Opsview for use in enterprise environments.

Distributed [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flabs.opsview.com%2F2011%2F09%2F10-ways-to-make-your-monitoring-system-scale%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flabs.opsview.com%2F2011%2F09%2F10-ways-to-make-your-monitoring-system-scale%2F&amp;style=normal&amp;b=2" height="61" width="50" />
			</a>
		</div><p><a href="http://labs.opsview.com/wp-content/uploads/2011/09/hyper-scalability_2.jpg"><img class="alignleft size-full wp-image-1012" style="margin-bottom: 8px; margin-right: 10px;" title="hyper scalability_2" src="http://labs.opsview.com/wp-content/uploads/2011/09/hyper-scalability_2.jpg" alt="" width="104" height="127" /></a></p>
<p>Freeware IT monitoring tools are used by thousands of organisation worldwide however using them to monitor complex network, server and application installations can be quite a challenge.  This blog post takes the basic capabilities of one such tool, <a href="http://www.opsview.com/company/legal/trademarks#NagiosTrademarkStatement">Nagios® Core</a>, and shows how you can scale it with Opsview for use in enterprise environments.</p>
<p><span id="more-1009"></span></p>
<h2>Distributed monitoring</h2>
<p>Building and managing a complex<a href="http://www.opsview.com/learn"> distributed monitoring</a> environment with Nagios Core is no mean feat. With Opsview you get distributed monitoring that’s easy to setup and simple to maintain.  You can monitor your devices and applications from a central location and grow the system without growing the monitoring complexity.</p>
<h2>Slave server clustering</h2>
<p>Opsview can automatically load-balance across multiple slaves and reallocate monitoring duties if a slave server fails, giving you high availability and scalability without additional overhead.</p>
<div id="attachment_1050" class="wp-caption alignright" style="width: 208px"><a href="http://labs.opsview.com/wp-content/uploads/2011/09/Clustering_diagram550px.png"><img class="size-full wp-image-1050   " style="margin-bottom: 8px; margin-left: 10px; border: 1px solid #ccc;" title="Clustering_diagram550px" src="http://labs.opsview.com/wp-content/uploads/2011/09/Clustering_diagram550px.png" alt="" width="198" height="152" /></a><p class="wp-caption-text">Example Clustering Model</p></div>
<h2>Master server clustering</h2>
<p>Management of Opsview is performed on a single master server, however master servers can be clustered giving you the high availability and redundancy needed for mission critical monitoring.</p>
<h2>Separate database server</h2>
<p>Opsview can be run on a separate database server so you can move intensive reporting activity to a dedicated machine and fine tune the server for better performance.</p>
<h2>Efficient configuration UI</h2>
<p>Nagios Core is capable of monitoring thousands of devices, but maintaining configuration on expanding systems can quickly become a problem. Opsview handles this with an easy to use interface and middleware layer which tackles the complexity of configuring individual software components.</p>
<h2>‘Single pane of glass’ monitoring</h2>
<p>Unlike Nagios Core where data may be gathered from a number of systems and presented in different ways, Opsview’s intuitive web interface displays all your monitoring information in one place, with a top down view on system status.  Devices and applications can be easily grouped by business process and their status displayed using simple &#8216;traffic lights&#8217; so you can easily see the health of critical and non-critical groups. This makes monitoring and maintaining large, complex systems less time consuming and more efficient with a scalable architecture to cover all your systems and locations.</p>
<div id="attachment_1031" class="wp-caption aligncenter" style="width: 560px"><a href="http://labs.opsview.com/wp-content/uploads/2011/09/configurationUI550px.png"><img class="size-full wp-image-1031" style="border: 1px solid #ccc;" title="configurationUI550px" src="http://labs.opsview.com/wp-content/uploads/2011/09/configurationUI550px.png" alt="" width="550" height="248" /></a><p class="wp-caption-text">Opsview&#39;s Host Group Hierarchy View</p></div>
<p style="text-align: center;">
<h2>Distributed alerting</h2>
<p>Slave servers monitored by Opsview can handle their own notifications, allowing autonomy if communication is lost between master and slave servers. Alerts can be sent by the Master server or slave server by email / sms so you’re always in touch with the health of your system, no matter the location or your systems.</p>
<h2>Automated APIs</h2>
<p>Opsview APIs speed up system configuration by automatically populating and updating host information saving you time and effort as your system grows.</p>
<div id="attachment_1048" class="wp-caption aligncenter" style="width: 560px"><a href="http://labs.opsview.com/wp-content/uploads/2011/09/API_diagram_Opsview550px1.jpg"><img class="size-full wp-image-1048" title="API_diagram_Opsview550px" src="http://labs.opsview.com/wp-content/uploads/2011/09/API_diagram_Opsview550px1.jpg" alt="" width="550" height="285" /></a><p class="wp-caption-text">Example use cases for Opsview&#39;s RESTful API</p></div>
<h2>SNMP trap processing</h2>
<p>Nagios Core has no native support for SNMP trap processing. Opsview’s SNMP engine accepts incoming traps, analyses the data and decides how to handle them. In-built SNMP discovery allows SNMP objects to be detected and monitored easily and rules can be configured through the management UI.</p>
<h2>Notification profiles</h2>
<p>With Nagios Core you can be inundated with monitoring information, not all of it useful. In Opsview you can set-up notification profiles so the right people get the right information at the right time. Only want to know about email server status during business hours? No problem. Need SMS alerts about your webstore? It’s covered. Notification profiles can also combined with Opsview’s service desk module to automatically assign support tasks to engineers, helping streamline incident management.</p>
<div style="border: 1px solid #ccc; background-color: #e6e6e6; padding: 6px;"><strong>IMPORTANT LEGAL NOTICE: No affiliation, partnership, joint-venture or any other commercial relationship exists between Opsera Ltd, the makers of Opsview, and Nagios Enterprises LLC, the trademark holders of Nagios.</strong></div>
]]></content:encoded>
			<wfw:commentRss>http://labs.opsview.com/2011/09/10-ways-to-make-your-monitoring-system-scale/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to improve your web site&#8217;s performance and conversion rates using monitoring</title>
		<link>http://labs.opsview.com/2011/05/how-to-improve-your-web-sites-performance-and-conversion-rates-using-monitoring/</link>
		<comments>http://labs.opsview.com/2011/05/how-to-improve-your-web-sites-performance-and-conversion-rates-using-monitoring/#comments</comments>
		<pubDate>Fri, 06 May 2011 14:50:23 +0000</pubDate>
		<dc:creator>tcallway</dc:creator>
				<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Opsview]]></category>
		<category><![CDATA[Selenium]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[online conversion rate]]></category>
		<category><![CDATA[user experience]]></category>
		<category><![CDATA[web performance]]></category>

		<guid isPermaLink="false">http://labs.opsview.com/?p=880</guid>
		<description><![CDATA[
			
				
			
		If you&#8217;re managing any web sites or web applications Selenium can be used with Opsview&#8217;s monitoring platform to ensure your customers get the very best user experience and increase your online conversion rates.
What is Selenium?
Selenium is a suite of tools to automate web application testing, it is also the 34th element in the periodic table. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flabs.opsview.com%2F2011%2F05%2Fhow-to-improve-your-web-sites-performance-and-conversion-rates-using-monitoring%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flabs.opsview.com%2F2011%2F05%2Fhow-to-improve-your-web-sites-performance-and-conversion-rates-using-monitoring%2F&amp;style=normal&amp;b=2" height="61" width="50" />
			</a>
		</div><p><a class="lightbox" title="Selenium - Periodic Table" href="http://labs.opsview.com/wp-content/uploads/2011/05/SeLogo.jpg"><img class="alignleft size-full wp-image-907" style="padding-right: 10px;" title="SeLogo" src="http://labs.opsview.com/wp-content/uploads/2011/05/SeLogo.jpg" alt="" width="79" height="100" /></a>If you&#8217;re managing any web sites or web applications Selenium can be used with Opsview&#8217;s monitoring platform to ensure your customers get the very best user experience and increase your online conversion rates.<span id="more-880"></span></p>
<h2>What is Selenium?</h2>
<p><a title="Selenium Website" href="http://seleniumhq.org/">Selenium</a> is a suite of tools to automate web application testing, it is also the 34th element in the periodic table. You can use the Selenium IDE to record web browser actions in the form of test cases. These test cases can be saved in a number of different formats and replayed when needed. The Selenium IDE is implemented as a Firefox extension.</p>
<h2>What is Opsview?</h2>
<p>Opsview provides comprehensive monitoring and management capabilities for a very wide range of web applications. Our Community Edition is free, easy to install and simple to use. More advanced features are available with Opsview Enterprise. <a href="http://www.opsview.com/learn/demos-tutorials">Check out our screencasts</a></p>
<h2>User Experience monitoring</h2>
<p>In 2001, Zona Research reported that 30% of surfers would abandon a Web site if it took more than 8 seconds to load, creating the widely-quoted ´8-second´ standard. Ten years later, with wide adoption of broadband services users become frustrated if sites take more than a couple of seconds to load.</p>
<p>Monitoring your web applications from an user&#8217;s perspective is vital for ensuring they get the best experience and allows you to get early warning of any application performance issues. You can use the Selenium IDE to record common paths through your web applications and the have Opsview replay these paths on a regular basis. Opsview will alert if any URLs fail to load in a pre-defined timescale or if the entire path takes too long to complete. These checks can be replayed from multiple locations (Opsview Slaves) to give you a complete picture of how your customers are experiencing the applications.</p>
<h2>End-to-end testing</h2>
<p>Using Selenium to perform end-to-end web application testing ensures that the whole system is being monitored in concert. This can be combined with individual component checks to provide a coherent overview of system performance and health. The Selenium IDE can be used to record transactions performed through the web applications. These are then replayed on a regular cycle to ensure the transaction completes successfully in a given timeframe. By replaying key transactions all components and sub-systems that comprise the application are exercised to ensure correct operation.</p>
<div id="attachment_885" class="wp-caption aligncenter" style="width: 310px"><a class="lightbox" title="selenium1" href="http://labs.opsview.com/wp-content/uploads/2011/05/selenium1.png"><img class="size-medium wp-image-885" title="selenium1" src="http://labs.opsview.com/wp-content/uploads/2011/05/selenium1-300x187.png" alt="Selenium in action" width="300" height="187" /></a><p class="wp-caption-text">Selenium in action</p></div>
<h2>Ten uses for Selenium with Opsview</h2>
<ol>
<li>Measure how your applications are performing for end-users</li>
<li>Keep tabs on your shopping cart / order processing application</li>
<li>Check that your landing page forms are working correctly</li>
<li>Confirm that web site authentication is working</li>
<li>Check that you&#8217;re not getting any pesky database errors</li>
<li>Track your cloud hosting provider&#8217;s performance against their SLA</li>
<li>Make sure your boss can get to his web mail account</li>
<li>Be the first to know that Opsview&#8217;s web UI is offline</li>
<li>Ensure your load balancer is working correctly</li>
<li>Get alerted if your homepage has been hacked</li>
</ol>
<h2>What next?</h2>
<p>Installation and configuration instructions can be found in Opsview&#8217;s <a href="http://docs.opsview.com/doku.php?id=thirdparty:selenium">documentation</a> along with instructions for downloading the selenium plugin.</p>
<p>Our recommended approach is to configure Selenium on an Opsview slave server, either by updating an existing slave or by deploying a new one. Selenium can place an appreciable load on your server so we recommend allocating another 1GB RAM. For heavy Selenium usage you should consider allocating an additional CPU core.</p>
<h2>Thanks</h2>
<p>Thanks to Alan Wijntje @ <a href="http://www.ziggo.nl/">Ziggo</a>, Rohit Deshmukh @ <a href="http://www.opsview.com/">Opsview</a> and Steve Burt @<a href="http://www.opsview.com"> Opsview</a> for their work on the Selenium plugin for Opsview and related documentation.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.opsview.com/2011/05/how-to-improve-your-web-sites-performance-and-conversion-rates-using-monitoring/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Managing security permissions for large teams in Opsview</title>
		<link>http://labs.opsview.com/2011/04/managing-security-permissions-for-large-teams-in-opsview/</link>
		<comments>http://labs.opsview.com/2011/04/managing-security-permissions-for-large-teams-in-opsview/#comments</comments>
		<pubDate>Thu, 14 Apr 2011 10:34:10 +0000</pubDate>
		<dc:creator>tonvoon</dc:creator>
				<category><![CDATA[Catalyst]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[MSPs]]></category>
		<category><![CDATA[Nagios]]></category>
		<category><![CDATA[Opsview]]></category>
		<category><![CDATA[System Management]]></category>
		<category><![CDATA[Unix / Linux]]></category>
		<category><![CDATA[business systems]]></category>
		<category><![CDATA[multi-tenancy]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://labs.opsview.com/?p=819</guid>
		<description><![CDATA[
			
				
			
		Hindsight is a wonderful thing.
In hindsight, Opsview would have always had access controls for objects at the role level &#8211; since roles also define which parts of the Opsview application you can get to, it would make sense to also put all the host and service objects into this definition.
(In our defence, we wanted to [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flabs.opsview.com%2F2011%2F04%2Fmanaging-security-permissions-for-large-teams-in-opsview%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flabs.opsview.com%2F2011%2F04%2Fmanaging-security-permissions-for-large-teams-in-opsview%2F&amp;style=normal&amp;b=2" height="61" width="50" />
			</a>
		</div><p><a class="lightbox" title="img-secure" href="http://labs.opsview.com/wp-content/uploads/2011/04/img-secure.png"><img class="alignleft size-full wp-image-832" title="img-secure" src="http://labs.opsview.com/wp-content/uploads/2011/04/img-secure.png" alt="" width="168" height="168" /></a>Hindsight is a wonderful thing.</p>
<p>In hindsight, Opsview would have always had <a href="http://docs.opsview.com/doku.php?id=opsview3.12:access">access controls</a> for objects at the <a href="http://docs.opsview.com/doku.php?id=opsview3.12:role">role level</a> &#8211; since roles also define which parts of the Opsview application you can get to, it would make sense to also put all the host and service objects into this definition.</p>
<p>(In our defence, we wanted to make it as obvious as possible for a contact when you were changing access information.)</p>
<p>The downside of our design decision many years ago is that Opsview administrators who have lots of their users – or <a href="http://docs.opsview.com/doku.php?id=opsview3.12:contact">contacts</a> in Opsview terms – with the same sort of access and were having to change each user individually. This was painful and error prone if you had 40 &#8220;similar&#8221; users.<span id="more-819"></span></p>
<p>So <a href="http://www.opsview.com/products/opsview-enterprise">Opsview Enterprise 3.12.0</a> now has access information in the role definition. You change access at the role level and it automatically affects all users of that role. Even better, we ensure that a user&#8217;s notification profile only has references to the objects they are allowed &#8211; change the role definitions and object references will be <a href="http://docs.opsview.com/doku.php?id=opsview3.12:role#authorised_for_host_groups">automatically removed</a> from all aspects of that contact.</p>
<p>Now you can administer users in a much simpler way.</p>
<p>Hindsight &#8211; we wish we had more of it.</p>
<p>But the next best thing to hindsight &#8211; migratability.</p>
<h2>Migratability?</h2>
<p>The Opsview configuration database is <a href="http://www.ibm.com/developerworks/web/library/wa-dbdsgn2.html">normalised</a> and models the data as it is. Some application designers like to use key-value pairs to describe their data, which is nice from an expandable point of view, but rubbish when it comes to actually accessing that data in a meaningful way. When it comes to modelling our data, we model it &#8211; we don&#8217;t &#8220;meta-model&#8221; it.</p>
<p>We care a lot about people&#8217;s data because we build up a trust with our users that they can upgrade and bring their platform right up to date with the latest versions of Opsview. So we spend a lot of time getting the upgrade scripts just right.</p>
<p>If you are upgrading to Opsview 3.12, here&#8217;s what the upgrade scripts do:</p>
<ul>
<li>for each contact, it will see if this contact&#8217;s role has access information applied</li>
<li>if it hasn&#8217;t, it will use this contact&#8217;s access information to populate the role</li>
<li>if the role already has access information (from another contact), then it will compare all the current roles with their access information and if there is a match, this role is used</li>
<li>if it isn&#8217;t exactly the same, then a new role is created called &#8220;old role name &#8211; contact&#8221;</li>
</ul>
<p>So for example, let&#8217;s say you have 4 contacts &#8211; John, Paul, George and Ringo &#8211; all using the &#8220;Liverpool administrators&#8221; role.</p>
<p style="text-align: center;"><a class="lightbox" title="contact_list_preupgrade" href="http://labs.opsview.com/wp-content/uploads/2011/03/contact_list_preupgrade1.png"><img class="size-medium wp-image-821 aligncenter" title="contact_list_preupgrade" src="http://labs.opsview.com/wp-content/uploads/2011/03/contact_list_preupgrade1-300x129.png" alt="" width="300" height="129" /></a></p>
<p>The first three have their access information the same, but Ringo has missed out the <em>Production &#8211; Slicehost Servers</em> host group he should have had access to.</p>
<p style="text-align: center;"><a class="lightbox" title="ringo_config" href="http://labs.opsview.com/wp-content/uploads/2011/03/ringo_config.png"><img class="size-medium wp-image-818 aligncenter" title="ringo_config" src="http://labs.opsview.com/wp-content/uploads/2011/03/ringo_config-300x221.png" alt="" width="300" height="221" /></a></p>
<p>After the upgrade, the first three would still have the role of <em>Liverpool administrators</em>, but Ringo would have the role of a newly created <em>Liverpool administrators &#8211; ringo</em>. You could easily tell from this that Ringo should belong to the Liverpool administrators, so you can set him to this. Otherwise, maybe he is different after all, so you can rename the role to <em>Liverpool drummers</em>.</p>
<p style="text-align: center;"><a class="lightbox" title="contact_list_postupgrade" href="http://labs.opsview.com/wp-content/uploads/2011/03/contact_list_postupgrade.png"><img class="size-medium wp-image-822 aligncenter" title="contact_list_postupgrade" src="http://labs.opsview.com/wp-content/uploads/2011/03/contact_list_postupgrade-300x129.png" alt="" width="300" height="129" /></a></p>
<p>This means that most of the configuration for this new functionality is done for you automatically and you can think of your users in their role groups, rather than individually. Another step to making Opsview easier to use.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.opsview.com/2011/04/managing-security-permissions-for-large-teams-in-opsview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Internationalising Catalyst, Part 2</title>
		<link>http://labs.opsview.com/2010/12/internationalising-catalyst-part-2/</link>
		<comments>http://labs.opsview.com/2010/12/internationalising-catalyst-part-2/#comments</comments>
		<pubDate>Tue, 21 Dec 2010 09:17:41 +0000</pubDate>
		<dc:creator>tonvoon</dc:creator>
				<category><![CDATA[Catalyst]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Frameworks]]></category>

		<guid isPermaLink="false">http://labs.opsview.com/?p=699</guid>
		<description><![CDATA[
			
				
			
		We present the 2nd part to our Catalyst advent calendar entry about internationalising your Catalyst application, complete with some really neat scripts such as automatically translating your string using Google! See it here. Enjoy!
]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flabs.opsview.com%2F2010%2F12%2Finternationalising-catalyst-part-2%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flabs.opsview.com%2F2010%2F12%2Finternationalising-catalyst-part-2%2F&amp;style=normal&amp;b=2" height="61" width="50" />
			</a>
		</div><p><a class="lightbox" title="catalyst_logo" href="http://labs.opsview.com/wp-content/uploads/2010/12/catalyst_logo.png"><img class="alignleft size-full wp-image-696" style="margin: 0pt 10px 5px 0pt;" title="catalyst_logo" src="http://labs.opsview.com/wp-content/uploads/2010/12/catalyst_logo.png" alt="" width="103" height="146" /></a>We present the <a href="http://bit.ly/eECIOH">2nd part</a> to our <a href="http://catalystframework.org">Catalyst</a> advent calendar entry about <a href="http://bit.ly/g2SzQb">internationalising your Catalyst application</a>, complete with some really neat scripts such as automatically translating your string using Google! See it <a href="http://bit.ly/eECIOH">here</a>. Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.opsview.com/2010/12/internationalising-catalyst-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Catalyst community contributions</title>
		<link>http://labs.opsview.com/2010/12/catalyst-community-contributions/</link>
		<comments>http://labs.opsview.com/2010/12/catalyst-community-contributions/#comments</comments>
		<pubDate>Thu, 09 Dec 2010 15:18:00 +0000</pubDate>
		<dc:creator>tonvoon</dc:creator>
				<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Opsview]]></category>

		<guid isPermaLink="false">http://labs.opsview.com/?p=692</guid>
		<description><![CDATA[
			
				
			
		We love Catalyst. This perl-based web application framework is at the heart of Opsview&#8217;s web interface and is crucial for the REST API we&#8217;ve developed. So it is with great pleasure that we&#8217;ve written a Catalyst Advent Calendar entry about internationalising your Catalyst application. See it here!
]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flabs.opsview.com%2F2010%2F12%2Fcatalyst-community-contributions%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flabs.opsview.com%2F2010%2F12%2Fcatalyst-community-contributions%2F&amp;style=normal&amp;b=2" height="61" width="50" />
			</a>
		</div><p><a class="lightbox" title="catalyst_logo" href="http://labs.opsview.com/wp-content/uploads/2010/12/catalyst_logo.png"><img class="alignleft size-full wp-image-696" style="margin: 0pt 10px 5px 0pt;" title="catalyst_logo" src="http://labs.opsview.com/wp-content/uploads/2010/12/catalyst_logo.png" alt="" width="103" height="146" /></a>We love <a href="http://catalystframework.org">Catalyst</a>. This perl-based web application framework is at the heart of Opsview&#8217;s web interface and is crucial for the REST API we&#8217;ve developed. So it is with great pleasure that we&#8217;ve written a Catalyst Advent Calendar entry about internationalising your Catalyst application. See it <a href="http://bit.ly/g2SzQb">here</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.opsview.com/2010/12/catalyst-community-contributions/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JNRPE &amp; check_jmx on 64-bit JVMs</title>
		<link>http://labs.opsview.com/2010/12/jnrpe-check_jmx-on-64-bit-jvms/</link>
		<comments>http://labs.opsview.com/2010/12/jnrpe-check_jmx-on-64-bit-jvms/#comments</comments>
		<pubDate>Tue, 07 Dec 2010 14:47:57 +0000</pubDate>
		<dc:creator>rbramley</dc:creator>
				<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[JMX]]></category>
		<category><![CDATA[Nagios]]></category>
		<category><![CDATA[Opsview]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://labs.opsview.com/?p=675</guid>
		<description><![CDATA[
			
				
			
		The JNRPE server provides an open source Java implementation of the Nagios Remote Plugin Executor (NRPE). This is much more efficient for performing JMX checks than regular NRPE as you only need to start one JVM rather than a JVM instantiation per check (as performed by check_jmx invoking java -jar JMXQuery.jar).

However this efficiency gain comes [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flabs.opsview.com%2F2010%2F12%2Fjnrpe-check_jmx-on-64-bit-jvms%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flabs.opsview.com%2F2010%2F12%2Fjnrpe-check_jmx-on-64-bit-jvms%2F&amp;style=normal&amp;b=2" height="61" width="50" />
			</a>
		</div><p><a class="lightbox"  title ="java-logo-small" href="http://labs.opsview.com/wp-content/uploads/2010/12/java-logo-small.png"><img src="http://labs.opsview.com/wp-content/uploads/2010/12/java-logo-small.png" alt="" title="java-logo-small" width="125" height="166" class="alignleft size-full wp-image-690" /></a>The JNRPE server provides an open source Java implementation of the Nagios Remote Plugin Executor (NRPE). This is much more efficient for performing JMX checks than regular NRPE as you only need to start one JVM rather than a JVM instantiation per check (as performed by check_jmx invoking java -jar JMXQuery.jar).</p>
<p><span id="more-675"></span></p>
<p>However this efficiency gain comes with a few compromises, it doesn’t handle composite data as well as other variants of check_jmx and doesn’t support performance data. It would be nice to see some community action to produce a definitive check_jmx.</p>
<p>Luckily with <a href="http://www.opsview.com">Opsview</a>, you can work around the lack of performance data using the map.local file so you can get performance graphs to assist with correlation or view rate of change over time.</p>
<p>In JNRPE version 0.6.3 there is also an integer overflow bug in the check_jmx base plugin.</p>
<p>The maximum value for a Java Integer is 2^31 – 1 (or 2,147,483,647) – if a number exceeds this, as an Integer is a signed number, it will wrap around to a negative number. For example on a JVM set with a 5GB heap, we saw the following output:</p>
<p><code>JMX OK - HeapMemoryUsage.used is -2037300184</code></p>
<p>Amusingly with the initial warning/critical threshold values set too low, this caused the state to flap between OK (when the heap was larger than a 32 bit number and hence negative) and CRITICAL after garbage collection had brought it beneath 2GB.</p>
<p>This has been raised with the JNRPE project as issue <a href="http://sourceforge.net/tracker/?func=detail&amp;aid=3131380&amp;group_id=204486&amp;atid=989804">3131380</a> – though unfortunately having raised it without signing in, I now can’t attach the following simple patch to the parseData method.</p>
<p><code>Index: CCheckJMX.java</code><br />
<code>=================================================================== </code><br />
<code>--- CCheckJMX.java (revision 243)</code><br />
<code>+++ CCheckJMX.java (working copy)</code><br />
<code>@@ -334,7 +334,7 @@</code><br />
<code>- private int parseData(Object o)</code><br />
<code>+ private long parseData(Object o)</code><br />
<code>{</code><br />
<code>if (o instanceof Number)</code><br />
<code>- return ((Number) o).intValue();</code><br />
<code>+ return ((Number) o).longValue();</code><br />
<code>else</code><br />
<code>- return Integer.parseInt(o.toString());</code><br />
<code>+ return Long.parseLong(o.toString());</code><br />
<code>}</code></p>
]]></content:encoded>
			<wfw:commentRss>http://labs.opsview.com/2010/12/jnrpe-check_jmx-on-64-bit-jvms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grails &amp; Hudson Part 3: Testing</title>
		<link>http://labs.opsview.com/2010/09/grails-hudson-part-3-testing/</link>
		<comments>http://labs.opsview.com/2010/09/grails-hudson-part-3-testing/#comments</comments>
		<pubDate>Fri, 10 Sep 2010 16:04:02 +0000</pubDate>
		<dc:creator>tcallway</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Hudson]]></category>
		<category><![CDATA[Unix / Linux]]></category>

		<guid isPermaLink="false">http://labs.opsview.com/?p=528</guid>
		<description><![CDATA[
			
				
			
		Since Grails incorporated the testing plugin into core it provides good unit &#38; integration testing support (via the test-app script). There are also additional plugins to support BDD tools (e.g. EasyB) and functional testing (e.g. Canoo WebTest).
One of the useful roles that Hudson fulfils is helping to manage quality. Consequently it has plugins available for [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flabs.opsview.com%2F2010%2F09%2Fgrails-hudson-part-3-testing%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flabs.opsview.com%2F2010%2F09%2Fgrails-hudson-part-3-testing%2F&amp;style=normal&amp;b=2" height="61" width="50" />
			</a>
		</div><p><a title="grails" href="http://labs.opsview.com/wp-content/uploads/2010/08/grails.png"><img class="alignleft" title="grails" src="http://labs.opsview.com/wp-content/uploads/2010/08/grails.png" alt="" width="176" height="53" /></a>Since Grails incorporated the testing plugin into core it provides good unit &amp; integration testing support (via the test-app script). There are also additional plugins to support BDD tools (e.g. EasyB) and functional testing (e.g. Canoo WebTest).</p>
<p><span id="more-528"></span>One of the useful roles that Hudson fulfils is helping to manage quality. Consequently it has plugins available for most of the popular testing tools (we saw an example of the Violations plugin in <a href="http://labs.opsview.com/2010/08/grails-hudson-part-1-codenarc/">part 1</a> of this series).</p>
<p>We’ll start with the standard unit &amp; integration tests, then add in test coverage and functional tests.</p>
<p><strong>Unit tests</strong>
Assuming you already have unit/integration tests in your Grails project – we need to add the targets into the Grails builder options.
<code>clean compile "test-app -unit -integration"</code></p>
<p style="text-align: center;"><img class="alignnone" src="http://leanjavaengineering.files.wordpress.com/2010/09/grails-builder-test-app.png?w=453&amp;h=152" alt="" width="453" height="152" /></p>
<p style="text-align: left;">Notice how the server port has been set to prevent port collision with the servlet container running Hudson.
<em> </em></p>
<p style="text-align: left;"><em>Tip:</em> you’ll need to set this differently on each job too.</p>
<p style="text-align: left;">Then set the post-build action:</p>
<p style="text-align: center;"><img class="alignnone" src="http://leanjavaengineering.files.wordpress.com/2010/09/post-build_junit_small.png?w=418&amp;h=86" alt="" width="418" height="86" /></p>
<p style="text-align: left;">After a couple of builds (so that there is a trend), Hudson will show:</p>
<p style="text-align: center;"><a href="http://leanjavaengineering.files.wordpress.com/2010/08/test_trend.png"><img class="alignnone" src="http://leanjavaengineering.files.wordpress.com/2010/08/test_trend.png?w=150&amp;h=136" alt="" width="150" height="136" /></a></p>
<p>With blue for tests that passed and red for failed tests.
You can also drill into the test results just as with the standard HTML junit reports.</p>
<p><strong>Test coverage</strong>
As we’re looking to use Hudson to help ensure the quality of the software project, we’ll also inspect the level of test coverage as one of our quality metrics.</p>
<p><em>Warning</em>: determining test coverage isn’t foolproof and high levels of coverage don’t guarantee good code or good tests. It is possible to achieve a high percentage with poor tests (I’m writing a separate post on this topic).</p>
<p>For this post, we’ll be using Cobertura to check the code coverage. There are other options, but we’ll be using Cobertura because:</p>
<ol>
<li>There is a <a href="http://www.grails.org/plugin/code-coverage">Grails plugin</a></li>
<li>There is a <a href="http://wiki.hudson-ci.org/display/HUDSON/Cobertura+Plugin">Hudson plugin</a> too.</li>
</ol>
<p><strong>Install the Grails code-coverage plugin</strong>
<code>grails install-plugin code-coverage</code></p>
<p>You may want to configure additional exclusions in BuildConfig.groovy, e.g. to avoid testing 3rd party code such as a plugin taglib that isn’t used. (the plugin scripts/_Events.groovy includes a default list)</p>
<p style="text-align: center;"><img class="alignnone" src="http://leanjavaengineering.files.wordpress.com/2010/09/buildconfig_cobertura_exclusions.png?w=247&amp;h=160" alt="" width="247" height="160" /></p>
<p><strong>Install the Hudson Cobertura plugin</strong>
This follows the same process that we covered in <a href="http://leanjavaengineering.wordpress.com/2010/08/31/grails-hudson-basics/">part 2</a> of this series (we’ll omit the screenshots this time):</p>
<ol>
<li>From the main Hudson dashboard, click on the “Manage Hudson” menu item</li>
<li>Click on “Manage plugins”</li>
<li>Go to the available tab, find &amp; select Cobertura, click on the install button.</li>
<li>When the plugin has downloaded and installed, you will need to restart Hudson (you can use the button provided).</li>
</ol>
<p><strong>Configure your Hudson job</strong>
There are 2 things that need to be done here:</p>
<ol>
<li>Set up the Grails build action</li>
<li>Enable the post-build action for Cobertura</li>
</ol>
<p>1. This is a case of adding “-coverage -xml” into the build targets within the test-app double quoted section.
2. Enable the Cobertura post-build processing, tell it where the XML report is and set thresholds:</p>
<p style="text-align: center;"><a href="http://leanjavaengineering.files.wordpress.com/2010/09/post-build_cobertura_config.png"><img class="aligncenter" src="http://leanjavaengineering.files.wordpress.com/2010/09/post-build_cobertura_config.png?w=300&amp;h=93" alt="" width="300" height="93" /></a></p>
<p style="text-align: left;"><strong>Leverage the information</strong></p>
<p style="text-align: left;">Watch the trends:</p>
<p style="text-align: center;"><a href="http://leanjavaengineering.files.wordpress.com/2010/09/cobertura_summary_report.png"><img class="aligncenter" src="http://leanjavaengineering.files.wordpress.com/2010/09/cobertura_summary_report.png?w=300&amp;h=266" alt="" width="300" height="266" /></a></p>
<p style="text-align: left;">and drill down to see the in-context coverage:</p>
<p style="text-align: center;"><img class="alignnone" src="http://leanjavaengineering.files.wordpress.com/2010/09/cobertura_in_context.png?w=443&amp;h=76" alt="" width="443" height="76" /></p>
<p>When you have the insight as to where you are missing coverage, then you can take the appropriate action to remedy the situation…</p>
<p><strong>Functional tests</strong>
There are a number of options for functional testing your application. We’ll cover <a href="http://webtest.canoo.com/">Canoo WebTest</a> in this post for the following reasons:</p>
<ol>
<li>WebTest is <a href="http://htmlunit.sourceforge.net/">htmlunit</a> based – portable across different environments</li>
<li>Canoo have written a <a href="http://webtestrecorder.canoo.com/">Firefox WebTest Recorder add-on</a> – allowing less technical users to create the basis of the tests</li>
<li>There is also a <a href="http://wiki.hudson-ci.org/display/HUDSON/WebTest+Presenter+Plugin">WebTest Presenter plugin</a> for Hudson.</li>
</ol>
<p>Note that as WebTest isn’t browser-based, you may encounter some issues with JavaScript on particular test scenarios.</p>
<p><strong>Install the Grails webtest plugin</strong>
<code>grails install-plugin webtest</code>
If you are using older versions of Grails, you may need to do an interactive plugin install on the Hudson server (the plugin used to download a WebTest bundle, rather than having it as a managed dependency).</p>
<p><strong>Install the Firefox WebTest Recorder add-on</strong>
You can install the WebTest Recorder in Firefox from:
<a href="https://www.canoo.com/webtestrecorder-dist/webtestrecorder.xpi">https://www.canoo.com/webtestrecorder-dist/webtestrecorder.xpi</a></p>
<p><strong>Create some web tests</strong>
<em>You can come back to this bit later</em></p>
<p>The process we’ll follow here uses the WebTest Recorder to create the initial test steps.</p>
<p>1. Run “grails create-webtest <em>name</em>” e.g.
<code>grails create-webtest HomepageLogin</code></p>
<p>This plugin script will create us the placeholder test file under test/webtest.</p>
<p>2. <code>grails run-app</code></p>
<p>3. Bring up Firefox
4. Navigate to the starting page for your test scenario.
5. Enable the WebTest Recorder Sidebar (Tools &gt; Webtest Recorder Sidebar)
6. Click on the Groovy tab.</p>
<p>This should already contain “invoke http://localhost:8080/YourGrailsApp/” (you’ll probably want to trim this down to just a relative path e.g. /YourGrailsApp/)</p>
<p>Using the Webtest Recorder Sidebar, you can click around the site and also easily add verification of content on pages (as a test isn’t a test if you don’t verify that the output is correct for the given input). This can then be placed into a method in the groovy file we created earlier (note: you may need to trim some instructions e.g. where the recorder has created different versions for the same input field).
For more information using Webtest, see the <a href="http://webtest.canoo.com/webtest/manual/manualOverview.html">manual</a>.</p>
<p style="text-align: center;"><img class="alignnone" src="http://leanjavaengineering.files.wordpress.com/2010/09/webtest_recorder.png?w=300&amp;h=241" alt="" width="300" height="241" /></p>
<p>I’d strongly advise you to run your tests locally first before checking them in – in the interests of time/space we’ll assume you’ve done that using:
<code>grails test-app -functional</code></p>
<p><strong>Install the Hudson WebTest presenter plugin</strong>
This follows the same process as the Cobertura plugin above (see <a href="http://leanjavaengineering.wordpress.com/2010/08/31/grails-hudson-basics/">part 2</a> of this series for screenshots):</p>
<ol>
<li>From the main Hudson dashboard, click on the “Manage Hudson” menu item</li>
<li>Click on “Manage plugins”</li>
<li>Go to the available tab, find &amp; select WebTest Presenter, click on the install button.</li>
<li>When the plugin has downloaded and installed, you will need to restart Hudson (you can use the button provided).</li>
</ol>
<p><strong>Configure your Hudson job</strong>
There are 2 things that need to be done here:</p>
<ol>
<li>Set up the Grails build action</li>
<li>Enable the post-build action for the WebTest Presenter</li>
</ol>
<p>1. This is a case of adding “-functional -headless” into the build targets within the test-app double quoted section (The headless option tells Webtest to not run the test monitor nor to load the test results into the browser).</p>
<p>2. The Webtest Presenter post-build action needs enabling and telling where to find the results</p>
<p style="text-align: center;"><img class="alignnone" src="http://leanjavaengineering.files.wordpress.com/2010/09/webtest_presenter_config.png?w=473&amp;h=58" alt="" width="473" height="58" /></p>
<p>After the Hudson job has executed your webtests, you’ll see that these have been included in your overall test count (and may even have improved your test coverage if you’ve followed the Cobertura section above).</p>
<p>If you click onto an individual build, the left hand menu will now have “Webtest Results”</p>
<p style="text-align: center;"><img class="alignnone" src="http://leanjavaengineering.files.wordpress.com/2010/09/job_webtest_results_menu_item.png?w=161&amp;h=305" alt="" width="161" height="305" /></p>
<p style="text-align: left;">This will give you an overview report:</p>
<p style="text-align: center;"><a href="http://leanjavaengineering.files.wordpress.com/2010/09/webtest_report.png"><img class="aligncenter" src="http://leanjavaengineering.files.wordpress.com/2010/09/webtest_report.png?w=300&amp;h=112" alt="" width="300" height="112" /></a></p>
<p style="text-align: left;">and a detailed step-by-step report for each test (including resulting pages and any errors):</p>
<p style="text-align: center;"><a href="http://leanjavaengineering.files.wordpress.com/2010/09/webtest_test_step_report.png"><img class="aligncenter" src="http://leanjavaengineering.files.wordpress.com/2010/09/webtest_test_step_report.png?w=300&amp;h=228" alt="" width="300" height="228" /></a></p>
<p style="text-align: left;">So there you go, a whistle stop tour of setting up test execution, coverage analysis and result reporting with trends.</p>
<p style="text-align: left;">Next in the series, we move into using Hudson for continuous deployment of Grails projects.</p>
<div></div>
]]></content:encoded>
			<wfw:commentRss>http://labs.opsview.com/2010/09/grails-hudson-part-3-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grails &amp; Hudson Part 1: CodeNarc</title>
		<link>http://labs.opsview.com/2010/08/grails-hudson-part-1-codenarc/</link>
		<comments>http://labs.opsview.com/2010/08/grails-hudson-part-1-codenarc/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 13:25:43 +0000</pubDate>
		<dc:creator>rbramley</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Hudson]]></category>
		<category><![CDATA[Opsview]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[CodeNarc]]></category>

		<guid isPermaLink="false">http://labs.opsview.com/?p=483</guid>
		<description><![CDATA[
			
				
			
		The first part of a series of posts on Grails and Hudson leading up to a presentation at the London Groovy &#38; Grails User Group. Subsequent instalments will include testing (unit, integration, functional), test coverage, automatic war deployment and monitoring Hudson with Opsview Enterprise.

Grails has a rich plugin eco-system with over 400 hundred plugins – so it’s [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flabs.opsview.com%2F2010%2F08%2Fgrails-hudson-part-1-codenarc%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flabs.opsview.com%2F2010%2F08%2Fgrails-hudson-part-1-codenarc%2F&amp;style=normal&amp;b=2" height="61" width="50" />
			</a>
		</div><p><a class="lightbox" title="grails" href="http://labs.opsview.com/wp-content/uploads/2010/08/grails.png"><img class="alignleft size-full wp-image-501" style="margin-bottom: 8px; margin-right: 10px;" title="grails" src="http://labs.opsview.com/wp-content/uploads/2010/08/grails.png" alt="" width="176" height="53" /></a>The first part of a series of posts on <a href="http://en.wikipedia.org/wiki/Grails_(framework)">Grails</a> and <a href="http://en.wikipedia.org/wiki/Hudson_(software)">Hudson</a> leading up to a presentation at the London Groovy &amp; Grails User Group. Subsequent instalments will include testing (unit, integration, functional), test coverage, automatic war deployment and monitoring Hudson with <a href="https://www.opsview.com/products/opsview-enterprise">Opsview Enterprise</a>.</p>
<div><span id="more-483"></span></div>
<p>Grails has a rich plugin eco-system with over 400 hundred plugins – so it’s easy to miss something useful. If you’re serious about software craftsmanship, then using static code analysis tools should be part of your quality regime as it gives further insight into the code base (and if you insist, yes it’ll help with your Technical Debt management).</p>
<p><a title="CodeNarc" href="http://codenarc.sourceforge.net/">CodeNarc</a> provides static code analysis for Groovy and the <a title="CodeNarc plugin" href="http://www.grails.org/plugin/codenarc/">CodeNarc plugin for Grails</a> allows you to perform this analysis with the “grails codenarc” script. Behind the scenes this uses the CodeNarc ant task and settings from grails-app/conf/Config.groovy and produces an HTML report by default.</p>
<p>Until recently, if you used the codenarc target within a continuous integration server such as <a title="Hudson CI" href="http://hudson-ci.org/">Hudson</a> – then the HTML report would be generated and sit in the workspace waiting for a diligent developer to check it. You can imagine how often that happens in practice with all the other demands of a project!</p>
<p>However, I’ve now integrated the CodeNarc XML output with the <a title="Violations plugin" href="http://wiki.hudson-ci.org/display/HUDSON/Violations">Hudson Violations plugin </a>so that an overview trend line is shown against the Hudson job. Then the team quickly fixed the violations…</p>
<p><a class="lightbox" title="1" href="http://labs.opsview.com/wp-content/uploads/2010/08/1.png"><img class="aligncenter size-full wp-image-484" title="1" src="http://labs.opsview.com/wp-content/uploads/2010/08/1.png" alt="" width="300" height="169" /></a>You can also get a breakdown by priority:</p>
<p><a class="lightbox" title="2" href="http://labs.opsview.com/wp-content/uploads/2010/08/2.png"><img class="aligncenter size-full wp-image-485" title="2" src="http://labs.opsview.com/wp-content/uploads/2010/08/2.png" alt="" width="300" height="259" /></a>And in-context views of the violations so you know what to fix:</p>
<p><a class="lightbox" title="3" href="http://labs.opsview.com/wp-content/uploads/2010/08/3.png"><img class="aligncenter size-full wp-image-486" title="3" src="http://labs.opsview.com/wp-content/uploads/2010/08/3.png" alt="" width="300" height="143" /></a></p>
<p>This is how you do it…</p>
<p>Grails <strong>config.groovy</strong>
<code>codenarc {
reportName = 'target/test-reports/CodeNarcReport.xml'
reportType = 'xml'
// any further settings like maxPriority1Violations=0
}</code></p>
<h3>Hudson</h3>
<p>Set up your Grails build step – normally you’d add the ‘codenarc’ target:</p>
<p><a class="lightbox" title="4" href="http://labs.opsview.com/wp-content/uploads/2010/08/4.png"><img class="aligncenter size-full wp-image-487" title="4" src="http://labs.opsview.com/wp-content/uploads/2010/08/4.png" alt="" width="519" height="459" /></a></p>
<p><em>The <a title="CodeNarc rule configuration" href="http://codenarc.sourceforge.net/codenarc-configuring-rules.html#Configuring_Rules_Using_a_Properties_File">codenarc.properties</a> file can be used to configure specific exclusions, the location of this file can be passed in as a system property (shown above).</em></p>
<p>You need to have installed the violations plugin (Manage Hudson &gt; Manage Plugins &gt; Available and search for Violations). As this is a recent addition, I’m using a patched version of the Violations plugin, though the patch has been integrated into trunk (I’ll update when it is released). Configure violations:</p>
<p><a class="lightbox" title="5" href="http://labs.opsview.com/wp-content/uploads/2010/08/5.png"><img class="aligncenter size-full wp-image-488" title="5" src="http://labs.opsview.com/wp-content/uploads/2010/08/5.png" alt="" width="526" height="515" /></a></p>
<p><em>Note the ‘Faux project path’ – you may need to set this to get an in-context view working properly due to path (e.g. if your code is checked out to workspace/trunk)</em></p>
<p>I also had a contribution to CodeNarc accepted at the weekend to add an<em>inlineXml</em> report type – this will, with a minor tweak to the CodeNarc parser, allow the Hudson Violations plugin to give the rule description on the pop-up message.</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.opsview.com/2010/08/grails-hudson-part-1-codenarc/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>GWT/GXT dashboard primer</title>
		<link>http://labs.opsview.com/2010/05/gwtgxt-dashboard-primer/</link>
		<comments>http://labs.opsview.com/2010/05/gwtgxt-dashboard-primer/#comments</comments>
		<pubDate>Wed, 19 May 2010 13:03:20 +0000</pubDate>
		<dc:creator>tcallway</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[GXT]]></category>
		<category><![CDATA[Google Web Toolkit]]></category>
		<category><![CDATA[Opsview]]></category>
		<category><![CDATA[System Management]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[next-gen]]></category>
		<category><![CDATA[opsview enterprise]]></category>
		<category><![CDATA[research]]></category>

		<guid isPermaLink="false">http://labs.opsview.com/?p=369</guid>
		<description><![CDATA[
			
				
			
		This post is based on research we’ve undertaken to develop a pilot mash-up style, charting dashboard for our monitoring solution, Opsview Enterprise. However the concepts we discuss could be used when building a dashboard that displays information from many other enterprise solutions. The assumption we make is that the reader is familiar with Java and [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Flabs.opsview.com%2F2010%2F05%2Fgwtgxt-dashboard-primer%2F">
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Flabs.opsview.com%2F2010%2F05%2Fgwtgxt-dashboard-primer%2F&amp;style=normal&amp;b=2" height="61" width="50" />
			</a>
		</div><p>This post is based on research we’ve undertaken to develop a pilot mash-up style, charting dashboard for our monitoring solution, Opsview Enterprise. However the concepts we discuss could be used when building a dashboard that displays information from many other enterprise solutions. The assumption we make is that the reader is familiar with Java and the Google Web Toolkit (GWT). For more information about GWT and the other libraries used in this blog please see the Resources section at the end.
<span id="more-369"></span></p>
<h4>Introduction</h4>
<p>The Opsview Enterprise platform is very flexible and allows us to extract monitoring information via a REST based API. This API returns monitoring data as JSON objects or XML so it is easy to integrate with many UI frameworks. In this example we will develop a mini portal-like application that displays status for different host groups in one of its portlets.</p>
<p>The client will be using the <a href="http://www.extjs.com/products/gwt/">‘GXT’ framework</a> that is based on GWT for the user interface and some Java libraries for HTTP communication and JSON parsing.</p>
<h4>Using the REST based API to talk to Opsview Enterprise</h4>
<p>Let’s first have a look at how you can call Opsview Enterprise from a browser to collect monitoring data. In this case we can use the following URL to fetch host groups:</p>
<p><code>http://&lt;hostname&gt;/opsview/api/status/hostgroup</code></p>
<p>If we try using this URL directly from a browser it will not work, a 403 access denied will be returned even if we login with correct credentials. A couple of extra headers are needed for the authentication to work; we will look at them later on.</p>
<p>To get around this problem we must first login to Opsview Enterprise the normal way via the Opsview Enterprise UI and then hit the URL:</p>
<p><code>https://&lt;hostname&gt;/opsview/status/hostgroup</code> </p>
<p>This is basically the first URL you get to. Now you will have a session in the browser so you can test the API URL again.</p>
<p>It will return JSON looking something like this:</p>
<pre><code>{"hostgroup":{
"summary":{"handled":782,"unhandled":60,"total":842,
   "service":{"ok":558,"critical":206,"handled":747,"unknown":29,
"unhandled":58,"warning":12,"total":805},
  		   "host":{"handled":35,"unhandled":2,"down":7,"up":30,"total":37}},
"list":[
        {
            "hostgroup_id":"7",
            "hosts":{ "handled":2, "unhandled":0, "down":{"handled":1},
"up":{"handled":1}, "total":2},
"services":{"ok":{"handled":24},"critical":{"handled":21,"unhandled":3},
"handled":50,"highest":"critical","unknown":{"handled":5}, "unhandled":3,"total":53},
            "name":"ProjectX",
            "downtime":null
        },
        {
            "hostgroup_id":"13",
            "hosts":{"handled":2,"unhandled":1,"down":{"handled":2,"unhandled":1},"total":3},
            "services":{"critical":{"handled":73},"handled":86,"highest":"critical",
			"unknown":{"handled":13},"unhandled":0,"total":86},
            "name":"Internal",
            "downtime":"2"
        },
        {
            "hostgroup_id":"14",
            "hosts":{"handled":31,"unhandled":1,"down":{"handled":2,"unhandled":1},
"up":{"handled":29},"total":32},
            "services":{"ok":{"handled":534},"critical":{"handled":66,"unhandled":43},
"handled":611,"highest":"critical","unknown":{"handled":9,
"unhandled":2},"unhandled":55,"warning":{"handled":2,"unhandled":10},
"total":666},
            "name":"Hosting",
            "downtime":"2"
        }
    ]}}</code></pre>
<p>So we can see by looking at it that it is nested JSON and in this case it returned the current status for 3 host groups: ProjectX, Internal, and Hosting.</p>
<p>Because the JSON is nested we will benefit from doing some processing on it before giving it to the UI routines that in GXT which only handles flat JSON.</p>
<h4>The Architecture for the Mini-Dashboard Application</h4>
<p>The following picture shows an overview of the architecture and the different components that will be used in this solution:</p>
<p><a class="lightbox" title="DashboardAppArchitecture" href="http://labs.opsview.com/wp-content/uploads/2010/05/DashboardAppArchitecture.png"><img class="aligncenter size-full wp-image-371" title="DashboardAppArchitecture" src="http://labs.opsview.com/wp-content/uploads/2010/05/DashboardAppArchitecture.png" alt="" width="400" /></a></p>
<p>The GXT client will not call the Opsview Enterprise server directly but instead go via a proxy server. This has the benefit that the JSON response from the Opsview Enterprise server can be processed and converted into <code>Serializable</code> Java objects. In this case the JSON is turned into a Java object called <code>HostGroup</code>, which in turn contains a <code>HostStatus</code> object. The <code>HostGroup</code> object will contain enough information to be able to draw a pie chart showing the status for the different host groups.</p>
<p>The <code>HostStatus</code> object will be used when the user clicks on one of the host group pie slices and wants to drill down to see more detailed status for a particular host group. Because we send the <code>HostStatus</code> object at the same time as the <code>HostGroup</code> object we do not have to make another remote call when the user drills down to see individual host group status.</p>
<p>Another benefit of having the proxy server is that it enables us to have the Mini Dashboard client web app and the Opsview Enterprise server web app on different hosts in different domains. If we did not have the proxy server it would not be possible to access content in Opsview Enterprise as for security reasons you cannot open URL connections to a different  host to the host from where the client is downloaded. Instead, you would have to install the Dashboard web app on the same host as Opsview Enterprise is running on.</p>
<h4>The Mini-Dashboard Proxy Server</h4>
<p>Let’s start implementing the proxy server using the Apache Commons HTTP Client and the Jackson JSON parser. For the remote calls between the Mini-Dashboard client and the proxy server (i.e. AJAX based client calls) we will implement a <code>com.google.gwt.user.client.rpc. RemoteService</code> as provided by Google Web Toolkit. It will handle all marshalling of calls for us.</p>
<p>Here is a UML Diagram giving you an overview of the involved proxy server classes:
<a class="lightbox" title="ServerImplUMLDiagram" href="http://labs.opsview.com/wp-content/uploads/2010/05/ServerImplUMLDiagram.png"><img class="aligncenter size-full wp-image-384" title="ServerImplUMLDiagram" src="http://labs.opsview.com/wp-content/uploads/2010/05/ServerImplUMLDiagram.png" alt="" width="400" /></a></p>
<p>First setup the OpsviewServerProxyService interface as follows:</p>
<pre><code>/**
  *
  * The client side stub for the Opsview Proxy Service RPC service.
  * @author Martin Bergljung, Opsera Ltd.
  */
@RemoteServiceRelativePath("opsviewproxy")
public interface OpsviewServerProxyService extends RemoteService {
    public static final String SERVICE_NAME = "OpsviewServerProxyService";

    public List getHostGroups();
}</code></pre>
<p>The <code>RemoteServiceRelativePath</code> annotation associates a <code>RemoteService</code> with a relative path. This annotation will cause the client-side proxy to automatically invoke the <code>ServiceDefTarget.setServiceEntryPoint</code> method with
<code>GWT.getModuleBaseURL() + value()</code> as its argument. Subsequent calls to <code>ServiceDefTarget.setServiceEntryPoint</code> will override this default path.</p>
<p>We define one method called <code>getHostGroups</code> that will return a list of <code>HostGroup</code> objects. Create a <code>HostGroup</code> object as follows:</p>
<pre><code>/**
 * Host Group (method level javadoc omitted for simplicity).
 *  
 *  {
 *   "hostgroup_id":"14",
 *   "hosts":{"handled":31,"unhandled":1,"down":{"handled":2,"unhandled":1},
 *            "up":{"handled":29},"total":32},
 *   "services":{"ok":{"handled":534},"critical":{"handled":66,"unhandled":43},
 *              "handled":611,"highest":"critical","unknown":{"handled":9,"unhandled":2},
 *              "unhandled":55,"warning":{"handled":2,"unhandled":10},"total":666},
 *   "name":"Internal",
 *   "downtime":"2"
 *   }
 * 
 * @author Martin Bergljung, Opsera Ltd.
 */
public class HostGroup implements Serializable {
    private int m_downtime;
    private String m_hostgroupId;
    private HostStatus m_hostStatus;
    private String m_name;
    private String m_services; // not used

    public HostGroup() {}

    //Getters, Setters, equals, hashCode, and toString have intentionally been left out to save space 

}
</code></pre>
<p>Next step is to create an asynchronous version of the interface as AJAX calls are asynchronous by nature.  This is the actual interface that the client will come in contact with:</p>
<pre><code>/**
 * The async counterpart of <code>OpsviewServerProxyService</code>.
 */
public interface OpsviewServerProxyServiceAsync {
    public void getHostGroups(AsyncCallback
&gt; callback);
}       </code></pre>
<p>The extra element here is the callback parameter that the client will have to implement. Now let’s move on to the actual implementation of this interface. Create the following class that implements the <code>getHostGroups</code> method:</p>
<pre><code>/**
 * The server side implementation of the Opsview Proxy Server RPC service.
*/
public class OpsviewServerProxyServiceImpl extends RemoteServiceServlet
implements OpsviewServerProxyService {
   public static final String OPSVIEW_API_BASE_URI =
            "https:///opsview/api";
   public static final String OPSVIEW_API_HOSTGROUP_STATUS_URI =
            OPSVIEW_API_BASE_URI + "/status/hostgroup";

   public List getHostGroups() {
        String json = callOpsview(OPSVIEW_API_HOSTGROUP_STATUS_URI);

        if (json != null &amp;&amp; json.length() &gt; 0) {
            return readHostGroupsJSON(json);
        }

        return new ArrayList();
   }
</code></pre>
<p>Here you need to update the hostname in the OPSVIEW_API_BASE_URI constant to reflect your installation. Also, if you are not using SSL then change to http.</p>
<p>Then add the <code>readHostGroupsJSON</code> method that takes JSON returned from Opsview Enterprise and turns it into a list of <code>HostGroup</code> objects:</p>
<pre><code>    private List readHostGroupsJSON(String json) {
        List hostGroups = new ArrayList();

        try {
            ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
            JsonNode rootNode = mapper.readValue(json, JsonNode.class);
            JsonNode hostGroupNode = rootNode.path("hostgroup");
            JsonNode listNode = hostGroupNode.path("list");

            for (JsonNode hostGroup : listNode) {
                HostGroup hg = new HostGroup();
                hg.setName(hostGroup.path("name").getTextValue());
                hg.setDowntime(hostGroup.path("downtime").getIntValue());
                String hostGroupId = hostGroup.path("hostgroup_id").getTextValue();
                hg.setHostGroupId(hostGroupId);
                hg.setServices("0"); // not used at the moment

                JsonNode hostStatus = hostGroup.path("hosts");
                HostStatus hs = new HostStatus();
                hs.setHostGroupId(hostGroupId);
                hs.setHandled(hostStatus.path("handled").getIntValue());
                hs.setUnhandled(hostStatus.path("unhandled").getIntValue());
                hs.setTotal(hostStatus.path("total").getIntValue()); // only one needed now

                JsonNode down = hostStatus.path("down");
                JsonNode up = hostStatus.path("up");
                hs.setDownHandled(down.path("handled").getIntValue());
                hs.setDownUnhandled(down.path("unhandled").getIntValue());
                hs.setUpHandled(up.path("handled").getIntValue());
                hs.setUpUnhandled(up.path("unhandled").getIntValue());

                hg.setHosts(hs);
                hostGroups.add(hg);
            }
        } catch (IOException e) {
            System.err.println("Fatal JSON Parsing error: " + e.getMessage());
            e.printStackTrace();
        }

        return hostGroups;
    }</code></pre>
<p>What we do here is use Jackson JSON parser (org.codehaus.jackson) to first lookup the hostgroup node in the JSON response and then with this node we go on to lookup the list node. When we have the list node we can step through all the host groups and setup corresponding HostGroup objects. The HostStatus object is also setup by looking up the hosts node for each hostgroup node.</p>
<p>Here is a snippet of the JSON structure that we are talking about:</p>
<pre><code>{"hostgroup":{
...
"list":[
        {
            "hostgroup_id":"7",
            "hosts":{
</code></pre>
<p>Finally we also need to implement the callOpsview method that will use Apache Commons HTTPClient to call Opsview Enterprise. Here is how that is done:</p>
<pre><code>private String callOpsview(String url) {
        String username = ;
        String password =
;

        HttpClient client = new HttpClient();
	// Apache is adding basic authentication in Opsera’s installation so
// the following 2 lines are necessary
        Credentials defaultcreds = new UsernamePasswordCredentials(username, password);
        client.getState().setCredentials(AuthScope.ANY, defaultcreds);
        GetMethod getMethod = new GetMethod(url);
        getMethod.setRequestHeader("X-Username", username);
        getMethod.setRequestHeader("X-Password", password);
        getMethod.setRequestHeader("Accept", "application/json");

        try {
            int statusCode = client.executeMethod(getMethod);
            if (statusCode == HttpStatus.SC_OK) {
                String contents = getMethod.getResponseBodyAsString();
                System.out.println(contents);
                return contents;
            } else {
                System.err.println("Got Error " + statusCode +
                        " when calling Opsview API: " +url);
            }
        } catch (Exception e) {
            System.err.println("Fatal transport error: " + e.getMessage());
            e.printStackTrace();
        } finally {
            // Release the connection.
            getMethod.releaseConnection();
        }

        return "";
    }</code></pre>
<p>When you implement this the username and password need to be specified according to the user account in your Opsview Enterprise installation. Here we can also see that we are setting the following headers:</p>
<ul>
<li><strong>X-Username</strong> – Username for Opsview user account</li>
<li><strong>X-Password</strong> – Password for Opsview user account</li>
<li><strong>Accept</strong> – indicates that we will accept and handle JSON responses (can also be set to accept XML)</li>
</ul>
<p>The Opsview Enterprise proxy server implementation also needs to be registered to a URL. We do this in the GWT module definition file as follows for testing purposes:</p>
<pre><code>  &lt;!— Setup the Opsview Server Proxy Service for hosted mode testing --&gt;
    &lt;servlet path="/opsviewproxy" class= 
			"com.<your package path>.server.OpsviewServerProxyServiceImpl" /&gt;</code></pre>
<p>And as follows for the real web application, open up web.xml and add:</p>
<pre><code>      &lt;servlet&gt;
      &lt;servlet-name&gt;opsviewServerProxyServiceServlet&lt;/servlet-name&gt;
      &lt;servlet-class&gt;com.&lt;your package&gt;.server.OpsviewServerProxyServiceImpl&lt;/servlet-class&gt;
    &lt;/servlet&gt;

    &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;opsviewServerProxyServiceServlet&lt;/servlet-name&gt;
      &lt;url-pattern>/dashboardApp/opsviewproxy&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;</code></pre>
<h4>The Mini-Dashboard Client</h4>
<p>The client is implemented as Google Web Toolkit application. So first create the main entry point / class for the application:</p>
<pre><code>public class DashboardApp implements EntryPoint {

    public void onModuleLoad() {
        OpsviewServerProxyServiceAsync service = (OpsviewServerProxyServiceAsync)
                GWT.create(OpsviewServerProxyService.class);
        Registry.register(OpsviewServerProxyService.SERVICE_NAME, service);

        LayoutContainer container = new LayoutContainer();
        final BorderLayout layout = new BorderLayout();
        container.setLayout(layout);
        container.setWidth(1024);
        container.setHeight(768);
        container.add(createMainMenuAndToolbarPanel(), createMainMenuAndToolbarLayoutData());
        container.add(new Dashboard(2), createDashboardLayoutData());
        container.add(createBottomStatusBar(), createBottomStatusBarLayoutData());

        RootPanel.get().add(container);
    }</code></pre>
<p>This creates the stub that handles communication with the Opsview Enterprise proxy server and registers this stub object locally. Then the layout for the GXT application is setup. Now create the individual panels and layout data:</p>
<pre><code>    private ContentPanel createMainMenuAndToolbarPanel() {
        ContentPanel mainMenuAndToolbarPanel = new ContentPanel();
        mainMenuAndToolbarPanel.setTopComponent(new MainMenu());
        mainMenuAndToolbarPanel.setHeading("Opsview Dashboard...");
        return mainMenuAndToolbarPanel;
    }

    private ContentPanel createBottomStatusBar() {
        ContentPanel panel = new ContentPanel();
        ToolBar toolbar = new ToolBar();
        panel.setHeaderVisible(false);
        Label opsviewVersion = new Label();
        opsviewVersion.setStyleName("Arial");
        opsviewVersion.setText("Opsview Dashboard Example");
        Label loggedInInfo = new Label();
        loggedInInfo.setText("Logged in as Opsview Admin");
        toolbar.add(opsviewVersion);
        toolbar.add(new FillToolItem());
        toolbar.add(loggedInInfo);
        toolbar.setHeight(25);
        panel.add(toolbar);
        return panel;
    }

    private BorderLayoutData createMainMenuAndToolbarLayoutData() {
        BorderLayoutData breadcrumbsLayoutData =
new BorderLayoutData(Style.LayoutRegion.NORTH, 50);
        breadcrumbsLayoutData.setHideCollapseTool(true);
        breadcrumbsLayoutData.setMargins(new Margins(5, 5, 0, 5));
        return breadcrumbsLayoutData;
    }

    private BorderLayoutData createDashboardLayoutData() {
        BorderLayoutData data = new BorderLayoutData(Style.LayoutRegion.CENTER);
        data.setMargins(new Margins(0, 5, 0, 5));
        return data;
    }

    private BorderLayoutData createBottomStatusBarLayoutData() {
        BorderLayoutData breadcrumbsLayoutData =
new BorderLayoutData(Style.LayoutRegion.SOUTH, 25);
        breadcrumbsLayoutData.setHideCollapseTool(true);
        breadcrumbsLayoutData.setMargins(new Margins(0, 5, 0, 5));
        return breadcrumbsLayoutData;
    }</code></pre>
<p>We are also going to need a menu and you can implement it if you like as it is not going to be used in this example. Here is a starting point:</p>
<pre><code>public class MainMenu extends ToolBar {
   public MainMenu() {....
   }
}</code></pre>
<p>Last thing we need for the client is the actual Dashboard class that will call the Opsview Enterprise proxy and draw the pie chart with host group status:</p>
<pre><code>public class Dashboard extends Portal {
   public static final String OFC_FLASH_LOCATION = "dashboardApp/chart/open-flash-chart.swf";

   private Chart m_hostGroupsChart;
   private List m_currentHostGroups;

   public Dashboard(int columns) {
        super(columns);
        setBorders(true);
        setStyleAttribute("backgroundColor", "white");
        setColumnWidth(0, .50);
        setColumnWidth(1, .50);

        add(createHostGroupsChartPortlet(), 1);
        loadHostGroupsChartPortlet();
   }</code></pre>
<p>Here we start off by implementing the Dashboard as a GXT Portal. We add one Portlet that will show the Host Group status pie chart. Then we call a method that will load the pie chart.</p>
<p>Next implement the method that creates the Host Group chart portlet as follows:</p>
<pre><code>   private Portlet createHostGroupsChartPortlet() {
        Portlet portlet = new Portlet();
        portlet.setHeading("Status - Host Groups Hierarchy");
        portlet.setLayout(new FitLayout());
        portlet.setHeight(400);

        String url = !isExplorer() ? "../../" : "";
        url += OFC_FLASH_LOCATION;
        m_hostGroupsChart = new Chart(url);
        m_hostGroupsChart.setBorders(true);

        //portlet.setIcon(ICONS.hostgroup());
        portlet.setTopComponent(createChartPortletToolBar());
        portlet.add(m_hostGroupsChart);

        configurePortlet(portlet);

        return portlet;
    }</code></pre>
<p>First we create the portlet and set its layout and heading etc. We then create a chart component and add it to the portlet. The chart component uses Flash to draw the chart so we need to supply the chart component with the URL for the Flash component. We also create a little toolbar for the portlet to show that you could implement configuration of what you want to see this way:</p>
<pre><code>    private ToolBar createChartPortletToolBar() {
        ToolBar toolbar = new ToolBar();

        Button searchButton = new Button("Config");
        //searchButton.setIcon(ICONS.properties());
        searchButton.setBorders(true);
        searchButton.setToolTip("Click here to configure the host group status chart");

        toolbar.setBorders(true);
        toolbar.setHeight(25);
        toolbar.add(new FillToolItem());
        toolbar.add(searchButton);

        return toolbar;
    }</code></pre>
<p>The loading of the Chart Portlet is done as follows by calling the getHostGroups method of the Opsview Enterprise proxy server stub and implementing the onSuccess and onFailure methods:</p>
<pre><code>    private void loadHostGroupsChartPortlet() {
        // Get the Opsview Server Proxy Service from the Registry
        final OpsviewServerProxyServiceAsync opsviewServerProxyService =
		(OpsviewServerProxyServiceAsync)
                Registry.get(OpsviewServerProxyService.SERVICE_NAME);

        // Make sure we got the service
        if (opsviewServerProxyService == null) {
            showInfoMsg("Opsview Server Proxy service could not be detected!");
        } else {
            opsviewServerProxyService.getHostGroups(new AsyncCallback
&gt;() {
                public void onSuccess(List hostGroups) {
                    m_currentHostGroups = hostGroups;

                    ChartModel cm = new ChartModel("Hosts by Host Group",
                            "font-size: 14px; font-family: Verdana; text-align: center;");
                    cm.setBackgroundColour("#fffff5");

                    PieChart pie = new PieChart();
                    pie.addChartListener(listener);
                    pie.setAlpha(0.5f);
                    pie.setTooltip("#label#
#percent#");
                    pie.setColours("#ff0000", "#00aa00", "#0000ff", "#ff9900", "#ff00ff");

                    for (HostGroup hostGroup : hostGroups) {
                        int totalHosts = hostGroup.getHosts().getTotal();
                        String name = hostGroup.getName();
                        pie.addSlices(new PieChart.Slice(totalHosts, name + " (" +
totalHosts + ")", name));
                    }

                    cm.addChartConfig(pie);

                    m_hostGroupsChart.setChartModel(cm);
                }

                public void onFailure(Throwable throwable) {
			throw new RuntimeException(throwable);
                    showInfoMsg("Opsview Server Proxy
getHostGroups call failed: " + throwable.getMessage());
                }
            });
        }
    }</code></pre>
<p>When the Opsview Enterprise server proxy responds we store the current host groups in a global variable so we can access it later on when the user clicks on one of the slices. We then do not have to call the server proxy as we have the HostStatus for the clicked on host group slice. We then create the PieChart and add a slice for each host group that was returned. A listener is also set for the pie chart and it will load the host status pie chart. The listener implementation looks like this:</p>
<pre><code>    private ChartListener listener = new ChartListener() {
        public void chartClick(ChartEvent ce) {
            PieChart.Slice hostGroup = (PieChart.Slice) ce.getDataType();
            loadHostStatusChartPortlet(hostGroup.getText());
            Info.display("Chart Clicked", "You selected {0}.", "" + ce.getValue() +
", " + hostGroup.getLabel());
        }
    };</code></pre>
<p>The Host Status Chart is loaded like this:</p>
<pre><code>    private void loadHostStatusChartPortlet(String hostGroupName) {
        ChartModel cm = new ChartModel("Host Status for Host Group " + hostGroupName,
                "font-size: 14px; font-family: Verdana; text-align: center;");
        cm.setBackgroundColour("#fffff5");

        PieChart pie = new PieChart();
        pie.addChartListener(listener);
        pie.setAlpha(0.5f);
        pie.setTooltip("#label#
#percent#");
        pie.setColours("#ff0000", "#00aa00", "#0000ff", "#ff9900", "#ff00ff");

        for (HostGroup hostGroup : m_currentHostGroups) {
            if (hostGroupName.equals(hostGroup.getName())) {
                HostStatus hostStatus = hostGroup.getHosts();
                pie.addSlices(new PieChart.Slice(hostStatus.getDownUnhandled(),
"Down - unhandled (" + hostStatus.getDownUnhandled() + ")", "Down - unhandled"));
                pie.addSlices(new PieChart.Slice(hostStatus.getUpHandled(),
"Up - handled (" + hostStatus.getUpHandled() + ")", "Up - handled"));
                pie.addSlices(new PieChart.Slice(hostStatus.getDownHandled(),
"Down - handled (" + hostStatus.getDownHandled() + ")", "Down - handled"));
                pie.addSlices(new PieChart.Slice(hostStatus.getUpUnhandled(),
"Up - unhandled (" + hostStatus.getUpUnhandled() + ")", "Up - unhandled"));
            }
        }

        cm.addChartConfig(pie);

        m_hostGroupsChart.setChartModel(cm);
    }</code></pre>
<p>When the Host Status chart is loaded it is not possible to go back to the Host Groups chart. There is no menu item for that or any implemented code to do that. If you like go ahead and implement this solution by yourself.</p>
<p>The little toolbar in the Chart Portlet is implemented like this:</p>
<pre><code>    private void configurePortlet(final ContentPanel panel) {
        panel.setCollapsible(true);
        panel.setAnimCollapse(false);
        panel.getHeader().addTool(new ToolButton("x-tool-gear"));
        panel.getHeader().addTool(
                new ToolButton("x-tool-close", new SelectionListener() {
                    @Override
                    public void componentSelected(IconButtonEvent ce) {
                        panel.removeFromParent();
                    }
                }));
    }</code></pre>
<p>The last couple of methods are helpers:</p>
<pre><code>    public static boolean isExplorer() {
        String test = Window.Location.getPath();
        if (test.indexOf("pages") != -1) {
            return false;
        }
        return true;
    }

    public static void showInfoMsg(String msg) {
        MessageBox box = new MessageBox();
        box.setButtons(MessageBox.OK);
        box.setIcon(MessageBox.INFO);
        box.setTitle("Information");
        box.setMessage(msg);
        box.show();
    }
}</code></pre>
<h4>Running the Mini-Dashboard Client</h4>
<p>To run this application after installing it under for example Tomcat we use a URL like this:</p>
<p><code>http://localhost:8080/opsviewui/dashboardApp.html</code></p>
<p>When we run this we should see a Host Groups Chart looking something like this:</p>
<p><a class="lightbox" title="HostGroupsPieChart" href="http://labs.opsview.com/wp-content/uploads/2010/05/HostGroupsPieChart.png"><img class="aligncenter size-full wp-image-372" title="HostGroupsPieChart" src="http://labs.opsview.com/wp-content/uploads/2010/05/HostGroupsPieChart.png" alt="" width="400" /></a></p>
<p>Clicking on one of the Host Groups will show Host status as follows:</p>
<p><a class="lightbox" title="HostStatusPieChart" href="http://labs.opsview.com/wp-content/uploads/2010/05/HostStatusPieChart.png"><img class="aligncenter size-full wp-image-373" title="HostStatusPieChart" src="http://labs.opsview.com/wp-content/uploads/2010/05/HostStatusPieChart.png" alt="" width="400" /></a></p>
<h4>Resources</h4>
<p>The Java libraries that were used in this example can be found here:</p>
<ul>
<li>GWT &#8211; <a href="http://code.google.com/webtoolkit/">http://code.google.com/webtoolkit/</a></li>
<li>GXT &#8211; <a href="http://www.extjs.com/products/gwt/">http://www.extjs.com/products/gwt/</a></li>
<li>Apache Commons HTTP Client – <a href="http://www.extjs.com/products/gwt/">http://hc.apache.org/httpclient-3.x/</a></li>
<li>Jackson JSON Parser &#8211; <a href="http://jackson.codehaus.org/">http://jackson.codehaus.org/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://labs.opsview.com/2010/05/gwtgxt-dashboard-primer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

