Skip to content

Instantly share code, notes, and snippets.

@andy-uq
Created May 16, 2017 21:19
Show Gist options
  • Save andy-uq/327875ad048fdae958aafbd00622c834 to your computer and use it in GitHub Desktop.
Save andy-uq/327875ad048fdae958aafbd00622c834 to your computer and use it in GitHub Desktop.
public class DocumentDb
{
private readonly DocumentClient _documentDb;
private readonly string _databaseId;
public DocumentDb(string endPoint, string authKey, string databaseId)
{
_databaseId = databaseId;
_documentDb = new DocumentClient(new Uri(endPoint), authKey);
}
public async Task CreateCollectionIfNotExistsAsync(string name)
{
try
{
await _documentDb.ReadDocumentCollectionAsync(UriFactory.CreateDocumentCollectionUri(_databaseId, name));
}
catch (DocumentClientException e)
{
if (e.StatusCode == System.Net.HttpStatusCode.NotFound)
{
await _documentDb.CreateDocumentCollectionAsync(
UriFactory.CreateDatabaseUri(_databaseId),
new DocumentCollection {Id = name, IndexingPolicy = new IndexingPolicy() { IndexingMode = IndexingMode.Lazy }, PartitionKey = new PartitionKeyDefinition() { Paths = new Collection<string>() { "/TrackingId" } }},
new RequestOptions {OfferThroughput = 8000});
}
else
{
throw;
}
}
}
public async Task<bool> CreateItemAsync(string collectionName, object value, PartitionKey partitionKey)
{
try
{
await _documentDb.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(_databaseId, collectionName), value);
return true;
}
catch (DocumentClientException e)
{
Serilog.Log.Warning(e, "Failed to write document to partition {collectionName}/{partitionKey}", collectionName, partitionKey);
return false;
}
}
}
public class DocumentDbTrackingIdBlockWriter : ITrackingIdBlockWriter
{
private readonly DocumentDb _documentDb;
private readonly PublisherId _publisherId;
private readonly ulong _trackingId;
public DocumentDbTrackingIdBlockWriter(DocumentDb documentDb, PublisherId publisherId, ulong trackingId)
{
_documentDb = documentDb;
_publisherId = publisherId;
_trackingId = trackingId;
}
public async Task<StoredTrackingEvents> AppendEventsAsync(TrackingIdBlock block)
{
var success = await Task.WhenAll(block.Select(InsertEvent));
return new StoredTrackingEvents(block.Count, success.Count(x => x == true));
}
private Task<bool> InsertEvent(StoredTrackingEvent arg)
{
return _documentDb.CreateItemAsync("TrackingData3", new { PublisherId = _publisherId.HexString, arg.TrackingId, Data = new TrackingEvent(arg) }, new PartitionKey(arg.TrackingId.ToString()));
}
}
public class TrackingEvent
{
private readonly StoredTrackingEvent _trackingEvent;
public string TrackingId { get { return Convert.ToString(_trackingEvent.TrackingId); } }
public ulong SessionId { get { return _trackingEvent.SessionId; } }
public ushort SessionLengthSeconds { get { return _trackingEvent.SessionLengthSeconds; } }
public string Title { get { return _trackingEvent.Title; } }
public string UserAgent { get { return _trackingEvent.UserAgent; } }
public short ScreenWidth { get { return _trackingEvent.ScreenWidth; } }
public short BrowserWidth { get { return _trackingEvent.BrowserWidth; } }
public short BrowserHeight { get { return _trackingEvent.BrowserHeight; } }
public string Referrer { get { return _trackingEvent.Referrer; } }
public string RequestId { get { return _trackingEvent.RequestId; } }
public string Url { get { return _trackingEvent.Url; } }
public Guid StoredEngageId { get; set; }
public string IpAddress { get; set; }
public DateTime RequestDateUtc { get; set; }
public TrackingEvent(StoredTrackingEvent trackingEvent)
{
if (trackingEvent == null)
throw new ArgumentNullException();
_trackingEvent = trackingEvent;
RequestDateUtc = ToDateTime(trackingEvent);
IpAddress = ToIpAddress(trackingEvent.IpAddress);
StoredEngageId = ToEngageId(trackingEvent.EngageId);
}
private static DateTime ToDateTime(StoredTrackingEvent trackingEvent)
{
return DateTime.FromBinary(trackingEvent.RequestDateUtc);
}
private static Guid ToEngageId(byte[] engageId)
{
if (engageId == null || engageId.Length != 16)
return Guid.Empty;
return new Guid(engageId);
}
private static string ToIpAddress(byte[] ipAddress)
{
if (ipAddress == null || ipAddress.Length == 0)
return null;
try
{
return new IPAddress(ipAddress).ToString();
}
catch (ArgumentException)
{
return ipAddress.Count(b => (char)b == '.') == 3
? new string(ipAddress.Select(b => (char)b).ToArray())
: null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment