Querying xDB cloud in Sitecore 8.1

One of the utilization of Sitecore’s analytics at Mathematica is to flush out trending content on our website. With the switchover to utilizing xDB cloud, this meant finding a way to query a data source that I no longer had direct access to. In the past, you could just query analytics/reporting database, but with the cloud based xDB this was no longer possible via database query. Instead we needed to hijack the reporting service that is used in Experience Analytics. After figuring out how Experience Analytics worked, I was able to write a class XdbCloudDataManager which I used for querying the data in the cloud. NOTE: This code was written very quickly and under the pressure of the upgrade. I don't claim this code to be the best but wanted to provide a solution that others can expand upon. I plan to revisit my own implementation to refactor a few things once things settle down. 

Code to execute query

  ReportDataQuery reportDataQuery = new ReportDataQuery(query);
  XdbCloudDataManager xDBCloudDataManager = new XdbCloudDataManager();
  DataTable popularProjectDT = xDBCloudDataManager.ExecuteQuery(reportDataQuery);

XdbCloudDataManager logic

public class XdbCloudDataManager
  public System.Data.DataTable ExecuteQuery(ReportDataQuery reportQuery)
    var webTransportFactory = Sitecore.Configuration.Factory.CreateObject("httpTransportFactory", true) as Sitecore.Analytics.Commons.WebTransportFactoryBase;
    Assert.IsNotNull(webTransportFactory, "httpTransportFactory is required");
    var path = this.GetPath("reporting/remote/paths/Reporting");
    var webRequest = webTransportFactory.CreateWebRequest(path);
    webRequest.Method = "POST";
    webRequest.ContentType = "application/xml";
    using (StreamWriter streamWriter = new StreamWriter(webRequest.GetRequestStream()))
      string xmlString = XdbCloudDataManager.ToXml("reporting",reportQuery);
    using (var response = webRequest.GetResponse())
      var deserializedResponse = Sitecore.Analytics.Reporting.ReportDataSerializer.DeserializeResponse(response.GetResponseStream());
      if (deserializedResponse is Exception)
        throw deserializedResponse as Exception;
      System.Data.DataTable table = (System.Data.DataTable)deserializedResponse;
      return table;