-
-
Notifications
You must be signed in to change notification settings - Fork 283
Custom history storage
ReportGenerator supports coverage trend charts. By default a XML file, containing the coverage information, is stored in a local directory. Each execution of ReportGenerator results in one additional XML file.
If you want to store these files in a custom storage (e.g. Amazon S3 or Azure Blob Storage) you can write a plugin. This may be helpful, when you use services like Bamboo.
To create a custom history storage you have to place a DLL, which contains one implementation of the IHistoryStorage interface, in the installation directory of ReportGenerator.
The interface has the following methods:
-
IEnumerable<string> GetHistoryFilePaths();
Returns all existing history file paths. The file paths should end with the names that have been passed to theSaveFile(Stream stream, string fileName)
in the past. -
Stream LoadFile(string filePath);
Load the file with given path. The path is one the paths that are returned byIEnumerable<string> GetHistoryFilePaths();
. -
SaveFile(Stream stream, string fileName);
Saves a new historic file with the given file name. The stream contains the file and does not have to be disposed.
In this example the historic files are retrieved and stored in an Amazon S3 Bucket.
-
Create a new Class Library project in Visual Studio
-
Add a reference to ReportGenerator.exe and to System.ComponentModel.Composition
-
Add the NuGet package AWSSDK.S3 to your project
-
Create a new class that implements the IHistoryStorage interface.
-
Add the following implementation (or change it as you like):
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.S3.Transfer;
using Palmmedia.ReportGenerator.Reporting.History;
namespace MyCompany.CustomHistoryStorage
{
[System.ComponentModel.Composition.Export(typeof(IHistoryStorage))]
public class AmazonS3HistoryStorage : IHistoryStorage
{
private readonly string MyBucketName = "*** Provide bucket name ***";
private readonly string AwsAccessKeyId = "*** Provide AwsAccessKeyId ***";
private readonly string AwsSecretAccessKey = "*** Provide AwsSecretAccessKey ***";
public AmazonS3HistoryStorage()
{
Dictionary<string, string> arguments = this.GetCommandLineArgumentsByKey();
string value = null;
if (arguments.TryGetValue("BUCKETNAME", out value))
{
this.MyBucketName = value;
}
if (arguments.TryGetValue("AWSACCESSKEYID", out value))
{
this.AwsAccessKeyId = value;
}
if (arguments.TryGetValue("AWSSECRETACCESSKEY", out value))
{
this.AwsSecretAccessKey = value;
}
}
public IEnumerable<string> GetHistoryFilePaths()
{
using (var client = new AmazonS3Client(AwsAccessKeyId, AwsSecretAccessKey))
{
ListObjectsV2Request request = new ListObjectsV2Request
{
BucketName = MyBucketName,
MaxKeys = 200
};
ListObjectsV2Response response;
do
{
response = client.ListObjectsV2(request);
// Process response.
foreach (S3Object entry in response.S3Objects)
{
yield return entry.Key;
}
request.ContinuationToken = response.NextContinuationToken;
}
while (response.IsTruncated == true);
}
}
public Stream LoadFile(string filePath)
{
TransferUtility fileTransferUtility = new TransferUtility(AwsAccessKeyId, AwsSecretAccessKey);
return fileTransferUtility.OpenStream(MyBucketName, filePath);
}
public void SaveFile(Stream stream, string fileName)
{
TransferUtility fileTransferUtility = new TransferUtility(AwsAccessKeyId, AwsSecretAccessKey);
fileTransferUtility.Upload(stream, MyBucketName, fileName);
}
private Dictionary<string, string> GetCommandLineArgumentsByKey()
{
var namedArguments = new Dictionary<string, string>();
foreach (var arg in Environment.GetCommandLineArgs())
{
var match = Regex.Match(arg, "-(?<key>\\w{2,}):(?<value>.+)");
if (match.Success)
{
namedArguments[match.Groups["key"].Value.ToUpperInvariant()] = match.Groups["value"].Value;
}
}
return namedArguments;
}
}
}
Attention: Don't forget to add the Export
attribute, otherwise ReportGenerator will not recognize your report builder.
- Compile
- Drop the DLL in the installation directory of ReportGenerator.
Attention: You have to make sure, that only a single custom IHistoryStorage implementation exists in that directory. Otherwise ReportGenerator would not be able to chose the correct one.
Download: Sample project