Plugin to view All latest project statistics on a server.
[email protected] Fri, 30 Dec 2011 09:16:32 -0500
| Newsgroups | gmane.comp.java.cruise-control.devel |
|---|---|
| Message-ID | <OFCF0534BD.66F3F9D0-ON85257976.004C5A05-85257976.004E6C10@bnymellon.com> |
Contribution for CuriseControl.Net - A plugin to display last statistics
for all Projects on a server with Project Statistics.
Configuration:
<serverPlugins>
<serverReportServerPlugin />
<!-- Add your plugin here -->
<serverStatisticsPlugin />
</serverPlugins>
Link: Server Statistics
Limits:
- All projects on that server have to have the same statistics
columns configured.
- Has not been tested on a server with no project statistics
configured.
- I am new to CruseControl.Net - suggestions are welcome.
---------- ServerStatistics.cs Plugin -----------
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using Exortech.NetReflector;
using ThoughtWorks.CruiseControl.Core.Reporting.Dashboard.Navigation;
using ThoughtWorks.CruiseControl.Core.Util;
using ThoughtWorks.CruiseControl.Remote;
using ThoughtWorks.CruiseControl.WebDashboard.Dashboard;
using ThoughtWorks.CruiseControl.WebDashboard.IO;
using ThoughtWorks.CruiseControl.WebDashboard.MVC;
using ThoughtWorks.CruiseControl.WebDashboard.MVC.Cruise;
using ThoughtWorks.CruiseControl.WebDashboard.MVC.View;
using ThoughtWorks.CruiseControl.WebDashboard.Plugins.Statistics;
using ThoughtWorks.CruiseControl.WebDashboard.ServerConnection;
namespace ThoughtWorks.CruiseControl.WebDashboard.Plugins.ServerStatistics
{
/// <summary>
/// Purpose:
/// Gives an overview of all projects statistics on this server.
/// Names the Link for the Server web site
/// Provides the Action Class that handles the request when
requested
///
/// Important: This plugin depends upon your configuring and using
the
/// ProjectStatisticsPlugin - since it uses the results.xml file
/// that it producedes.
///
/// First configure ProjectStatisticsPlugin, then configure this
plugin
/// to view all project statistics on the server.
/// <para>
/// LinkDescription : "Server Statistics".
/// </para>
/// </summary>
/// <example>
/// <code title="Minimalist example">
/// <serverStatisticsPlugin />
/// </code>
/// </example>
/// <title>Server Statistics Plugin</title>
/// <version>1.0.0</version>
[ReflectorType("serverStatisticsPlugin")]
public class ServerStatisticsPlugin : ICruiseAction, IPlugin
{
public static readonly string ACTION_NAME =
"ViewServerStatisticsReport";
private readonly IFarmService farmService;
private readonly IVelocityViewGenerator viewGenerator;
private readonly ICruiseUrlBuilder urlBuilder;
#region Constructor
// Constructor for use with built-in Action class
public ServerStatisticsPlugin(IFarmService farmServer,
IVelocityViewGenerator viewGenerator, ICruiseUrlBuilder urlBuilder)
{
this.farmService = farmServer;
this.viewGenerator = viewGenerator;
this.urlBuilder = urlBuilder;
}
#endregion
#region IPlugin Members
/// <summary>
/// Provide the Menu Link that invokes FarmStatisticsAction
/// </summary>
public string LinkDescription
{
get { return "Server Statistics"; }
}
public INamedAction[] NamedActions
{
get { return new INamedAction[] { new ImmutableNamedAction(
"ViewServerStatistics", this) }; }
}
#endregion
#region ICruiseAction Members
/// <summary>
/// Execute this action after a user clicks the "Server
Statistics" link,
/// to show all projects latest statistics (configured through the
/// ProjectStatistics Plugin).
/// </summary>
/// <param name="request">CruiseControl web request</param>
/// <returns>IResponse page to the web server</returns>
public IResponse Execute(ICruiseRequest request)
{
IProjectSpecifier project;
string statisticsDocument;
Hashtable velocityContext = new Hashtable();
CruiseServerSnapshotListAndExceptions snapshot =
farmService.GetCruiseServerSnapshotListAndExceptions(request.ServerSpecifier,
request.RetrieveSessionToken());
List<QueueSnapshot> queues = new List<QueueSnapshot>();
ArrayList statisticsList;
List<ArrayList> projectStatisticsList = new List<ArrayList>();
for (int idxSnapshot = 0; idxSnapshot <
snapshot.Snapshots.Length; idxSnapshot++)
{
QueueSetSnapshot queueSnapshot =
snapshot.Snapshots[idxSnapshot].QueueSetSnapshot;
for (int idxQueue = 0; idxQueue <
queueSnapshot.Queues.Count; idxQueue++)
{
queues.Add(queueSnapshot.Queues[idxQueue]);
project = GetProjectSpecifier(request,
queueSnapshot.Queues[idxQueue].QueueName);
// Use the ProjectStatisticsPlugin results xml file.
statisticsDocument =
farmService.GetStatisticsDocument(project,
request.RetrieveSessionToken());
Log.Debug(statisticsDocument);
try
{
// Read the ProjectStatisticsPlugin results xml
file
statisticsList = GetEachProjectStatistics(project,
statisticsDocument);
if (statisticsList.Count > 2) // Name, and Status
are expected
{
// Add for single project statisticsList of
Colums
// Columns are in Name-Value pairs
projectStatisticsList.Add(statisticsList);
}
}
catch (XmlException)
{
// The Project does not have Statistics configured
or gathered.
// Nothing to do since not all projects have
Statistics.
//"Missing/Invalid statistics reports. Please
check if you have enabled the Statistics Publisher, and statistics have
been collected atleast once after that.";
}
}
}
// Data for table of Project Statistics
velocityContext["projectStatisticsList"] =
projectStatisticsList;
return viewGenerator.GenerateView(@"ServerStatistics.vm",
velocityContext);
}
#endregion
#region Helper Methods
/// <summary>
/// Get the Project Specifier given the project name
/// Prerequisite: Select a server so request will have the server
name
/// </summary>
/// <param name="request">ICruiseRequest web request information
</param>
/// <returns>DefaultProjectSpecifier</returns>
private IProjectSpecifier GetProjectSpecifier(ICruiseRequest
request, string projectName)
{
string server = request.ServerName;
return new DefaultProjectSpecifier
(farmService.GetServerConfiguration(server), projectName);
}
// Example:
//</statistics>
// <integration build-label="3" status="Success" day="22" month="Dec"
year="2011">
// <statistic name="StartTime">2011-12-22 10:12:55</statistic>
// <statistic name="Duration">00:00:49</statistic>
// <statistic name="TestCount">4</statistic>
// <statistic name="TestFailures">0</statistic>
// <statistic name="TestIgnored">0</statistic>
// <statistic name="BuildErrorType" />
// <statistic name="BuildErrorMessage" />
// </integration>
// <timestamp day="22" month="Dec" year="2011" />
//</statistics>
/// <summary>
/// Read a project statistics xml report, parse, and
/// get an ordered list of project statistics data in Name-Value
pairs/
/// </summary>
/// <param name="project">Project specifier</param>
/// <param name="statisticsDocument">Project Statistics XML string
</param>
/// <returns>ordered list of project statistics data in Name-Value
pairs</returns>
/// <remarks>Uses an XmlDocument</remarks>
private ArrayList GetEachProjectStatistics(IProjectSpecifier
project, string statisticsDocument)
{
// Read the ProjectStatisticsPlugin results xml file
// to duplicate the column names configured for that plugin
// also read the values from the xml file produced by
ProjectStatisticsPlugin
ArrayList statisticsList = new ArrayList();
XmlDocument doc = new XmlDocument();
string href;
using (XmlReader reader = XmlReader.Create(new StringReader
(statisticsDocument)))
{
doc.Load(reader);
//XPathNavigator nav = doc.CreateNavigator();
XmlNode root = doc.DocumentElement;
XmlNodeList integrationNodes = root.SelectNodes(
@"integration");
XmlNode current = null;
if ((integrationNodes != null) &&
(integrationNodes.Count > 0))
{
// Use last integration node
current = integrationNodes[integrationNodes.Count
- 1];
// First Column
Hashtable Col1 = new Hashtable();
// Add a Project Statistics URL
href = @"<a href=" + urlBuilder.BuildProjectUrl(
ProjectStatisticsPlugin.ACTION_NAME, project) + ">" + project.ProjectName
+ "</a>";
Col1.Add(@"Name", href);
statisticsList.Add(Col1);
if (current.Attributes.Count >= 2)
{
// Second Status Attribute
string status = current.Attributes[1].Value;
Hashtable Col2 = new Hashtable();
Col1.Add(@"Status", status);
statisticsList.Add(Col2);
}
// move to the "statistic" nodes
XmlNodeList statisticsNodes = current.SelectNodes(
@"statistic");
Hashtable Coln; // project statistics columns(n)
foreach (XmlNode node in statisticsNodes)
{
Coln = new Hashtable();
if (node.Attributes.Count > 0)
{
string name = node.Attributes[0].Value;
string value = node.InnerText;
Coln.Add(name, value);
statisticsList.Add(Coln);
}
}
}
}
return statisticsList;
}
/// <summary>
/// Read a project statistics xml report, parse, and
/// get an ordered list of project statistics data in Name-Value
pairs/
/// </summary>
/// <param name="project">Project specifier</param>
/// <param name="statisticsDocument">Project Statistics XML string
</param>
/// <returns>ordered list of project statistics data in Name-Value
pairs</returns>
/// <remarks>Uses an XmlReader</remarks>
private ArrayList GetProjectStatistics(IProjectSpecifier project,
string statisticsDocument)
{
// Read the ProjectStatisticsPlugin results xml file
// to duplicate the column names configured for that plugin
// also read the values from the xml file produced by
ProjectStatisticsPlugin
ArrayList statisticsList = new ArrayList();
using (XmlReader reader = XmlReader.Create(new StringReader
(statisticsDocument)))
{
reader.ReadToFollowing("integration");
reader.MoveToFirstAttribute();
string buildLabel = reader.Value;
Hashtable Col0 = new Hashtable();
Col0.Add("Name", project.ProjectName);
// Wait to see if we can read this project statistics
// If we can then start a statisticsList of columns
// for this project.
statisticsList.Add(Col0);
reader.MoveToNextAttribute();
string status = reader.Value;
Hashtable Col1 = new Hashtable();
Col1.Add("Status", status);
statisticsList.Add(Col1);
Hashtable Coln; // project status column n
while (reader.Read())
{
reader.ReadToFollowing("statistic");
string value = reader.Value;
reader.MoveToFirstAttribute();
string name = reader.Value;
// Read the rest of the configured columns
Coln = new Hashtable();
Coln.Add(name, value);
statisticsList.Add(Coln);
}
}
return statisticsList;
}
#endregion
}
}
-------------------------
--------- ServerStatistics.vm Template ---------
<!-- ServerStatistics.vm: Start -->
<script type="text/javascript">
$(document).ready(function(){
$('#ServerStatistics').tablesorter({
sortList:[[0,0]]
});
});
</script>
<table class="SortableGrid" id="ServerStatistics">
<thead>
<tr class="ProjectGridHeader">
##
## Note: Process each project statistics row for the Table Header
##
#foreach ($statisticsList in $projectStatisticsList)
#if ( $velocityCount == 1 )
#foreach ($col in $statisticsList)
#foreach ($key in $col.Keys)<th>$key</th>#end
#end
#end
#end
</tr>
</thead>
<tbody>
##
## Note: Process each project statistics row for the Table Data
##
#foreach ($statisticsList in $projectStatisticsList)
<tr>
#foreach ($col in $statisticsList)
#foreach ($value in $col.Values)
#if ($value == "Success")
<td class="Green">$value</td>
#elseif ($value == "Failure")
<td class="Red">$value</td>
#else
<td>$value</td>
#end
#end
#end
</tr>
#end
</tbody>
</table>
<!-- ServerStatistics.vm: End -->
---------------------------------------------
Thanks,
Stephen
The information contained in this e-mail, and any attachment, is confidential and is intended solely for the use of the intended recipient. Access, copying or re-use of the e-mail or any attachment, or any information contained therein, by any other person is not authorized. If you are not the intended recipient please return the e-mail to the sender and delete it from your computer. Although we attempt to sweep e-mail and attachments for viruses, we do not guarantee that either are virus-free and accept no liability for any damage sustained as a result of viruses.
Please refer to http://disclaimer.bnymellon.com/eu.htm for certain disclosures relating to European legal entities.
------------------------------------------------------------------------------
Ridiculously easy VDI. With Citrix VDI-in-a-Box, you don't need a complex
infrastructure or vast IT resources to deliver seamless, secure access to
virtual desktops. With this all-in-one solution, easily deploy virtual
desktops for less than the cost of PCs and save 60% on VDI infrastructure
costs. Try it free! http://p.sf.net/sfu/Citrix-VDIinabox
_______________________________________________
Cruisecontrol-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/cruisecontrol-devel
(unnamed)
(image/gif, 19.7 KB) - not displayed