diff --git a/Source/Bifrost.MongoDb/Bifrost.MongoDB.csproj b/Source/Bifrost.MongoDb/Bifrost.MongoDB.csproj
index 6e19a63fb..c6783daa4 100644
--- a/Source/Bifrost.MongoDb/Bifrost.MongoDB.csproj
+++ b/Source/Bifrost.MongoDb/Bifrost.MongoDB.csproj
@@ -5,7 +5,7 @@
AnyCPU
8.0.30703
2.0
- {63BBC1F3-E5E0-4902-BADF-1589F91C0BEA}
+ {6AA43B6E-8B56-4B00-AB6E-0F711C432BE8}
Library
Properties
Bifrost.MongoDB
@@ -79,6 +79,7 @@
+
diff --git a/Source/Bifrost.MongoDb/Concepts/ConceptSerializationProvider.cs b/Source/Bifrost.MongoDb/Concepts/ConceptSerializationProvider.cs
index 45e6a3236..ba6b6c94c 100644
--- a/Source/Bifrost.MongoDb/Concepts/ConceptSerializationProvider.cs
+++ b/Source/Bifrost.MongoDb/Concepts/ConceptSerializationProvider.cs
@@ -6,14 +6,14 @@
using Bifrost.Concepts;
using MongoDB.Bson.Serialization;
-namespace Bifrost.MongoDB.Concepts
+namespace Bifrost.MongoDb.Concepts
{
public class ConceptSerializationProvider : IBsonSerializationProvider
{
public IBsonSerializer GetSerializer(Type type)
{
if (type.IsConcept())
- return new ConceptSerializer();
+ return new ConceptSerializer(type);
return null;
}
diff --git a/Source/Bifrost.MongoDb/Concepts/ConceptSerializer.cs b/Source/Bifrost.MongoDb/Concepts/ConceptSerializer.cs
index dd9d8dde0..6a4f02407 100644
--- a/Source/Bifrost.MongoDb/Concepts/ConceptSerializer.cs
+++ b/Source/Bifrost.MongoDb/Concepts/ConceptSerializer.cs
@@ -10,41 +10,59 @@
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Options;
-namespace Bifrost.MongoDB.Concepts
+namespace Bifrost.MongoDb.Concepts
{
public class ConceptSerializer : IBsonSerializer
{
- public object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
+ private Type _valueType;
+ public Type ValueType
{
+ get
+ {
+ return _valueType;
+ }
+ }
+
+ public ConceptSerializer(Type conceptType)
+ {
+ if (!conceptType.IsConcept())
+ throw new ArgumentException("Type is not a concept.", nameof(conceptType));
+
+ _valueType = conceptType;
+ }
+
+ public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
+ {
+ var bsonReader = context.Reader;
+ var actualType = args.NominalType;
+
object value = null;
+
var valueType = actualType.GetConceptValueType();
- if (valueType == typeof(Guid)) {
+ if (valueType == typeof(Guid))
+ {
var binaryData = bsonReader.ReadBinaryData();
value = binaryData.ToGuid();
- } else if (valueType == typeof(double))
- value = bsonReader.ReadDouble ();
+ }
+ else if (valueType == typeof(double))
+ value = bsonReader.ReadDouble();
else if (valueType == typeof(float))
- value = (float)bsonReader.ReadDouble ();
+ value = (float)bsonReader.ReadDouble();
else if (valueType == typeof(Int32))
- value = bsonReader.ReadInt32 ();
+ value = bsonReader.ReadInt32();
else if (valueType == typeof(Int64))
- value = bsonReader.ReadInt64 ();
+ value = bsonReader.ReadInt64();
else if (valueType == typeof(bool))
- value = bsonReader.ReadBoolean ();
+ value = bsonReader.ReadBoolean();
else if (valueType == typeof(string))
- value = bsonReader.ReadString ();
+ value = bsonReader.ReadString();
else if (valueType == typeof(decimal))
- value = decimal.Parse (bsonReader.ReadString ());
-
+ value = decimal.Parse(bsonReader.ReadString());
+
var concept = ConceptFactory.CreateConceptInstance(actualType, value);
return concept;
}
- public object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
- {
- return null;
- }
-
public bool GetDocumentId(object document, out object id, out Type idNominalType, out IIdGenerator idGenerator)
{
id = null;
@@ -52,40 +70,35 @@ public bool GetDocumentId(object document, out object id, out Type idNominalType
idNominalType = null;
return false;
}
-
- public void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
+
+ public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
{
- var underlyingValue = value.GetType().GetProperty("Value").GetValue(value, null);
+ var underlyingValue = value?.GetType().GetProperty("Value").GetValue(value, null);
+ var nominalType = args.NominalType;
var underlyingValueType = nominalType.GetConceptValueType();
- if (underlyingValueType == typeof(Guid)) {
- var guid = (Guid)underlyingValue;
- var guidAsBytes = guid.ToByteArray ();
- bsonWriter.WriteBinaryData (guidAsBytes, BsonBinarySubType.UuidLegacy, GuidRepresentation.CSharpLegacy);
- } else if (underlyingValueType == typeof(double))
- bsonWriter.WriteDouble ((double)underlyingValue);
+
+ var bsonWriter = context.Writer;
+
+ if (underlyingValueType == typeof(Guid))
+ {
+ var guid = (Guid) (underlyingValue ?? default(Guid));
+ var guidAsBytes = guid.ToByteArray();
+ bsonWriter.WriteBinaryData(new BsonBinaryData(guidAsBytes, BsonBinarySubType.UuidLegacy, GuidRepresentation.CSharpLegacy));
+ }
+ else if (underlyingValueType == typeof(double))
+ bsonWriter.WriteDouble((double) (underlyingValue ?? default(double)));
else if (underlyingValueType == typeof(float))
- bsonWriter.WriteDouble ((double)underlyingValue);
+ bsonWriter.WriteDouble((double) (underlyingValue ?? default(double)));
else if (underlyingValueType == typeof(Int32))
- bsonWriter.WriteInt32 ((Int32)underlyingValue);
+ bsonWriter.WriteInt32((Int32) (underlyingValue ?? default(Int32)));
else if (underlyingValueType == typeof(Int64))
- bsonWriter.WriteInt64 ((Int64)underlyingValue);
+ bsonWriter.WriteInt64((Int64) (underlyingValue ?? default(Int64)));
else if (underlyingValueType == typeof(bool))
- bsonWriter.WriteBoolean ((bool)underlyingValue);
+ bsonWriter.WriteBoolean((bool) (underlyingValue ?? default(bool)));
else if (underlyingValueType == typeof(string))
- bsonWriter.WriteString ((string)(underlyingValue ?? string.Empty));
+ bsonWriter.WriteString((string) (underlyingValue ?? string.Empty));
else if (underlyingValueType == typeof(decimal))
- bsonWriter.WriteString (underlyingValue.ToString());
+ bsonWriter.WriteString(underlyingValue?.ToString() ?? default(decimal).ToString());
}
-
- public void SetDocumentId(object document, object id)
- {
- }
-
- public IBsonSerializationOptions GetDefaultSerializationOptions()
- {
- var options = new DocumentSerializationOptions();
- return options;
- }
-
}
}
diff --git a/Source/Bifrost.MongoDb/ConfigurationExtensions.cs b/Source/Bifrost.MongoDb/ConfigurationExtensions.cs
index 8f988ecac..e7ae31f8d 100644
--- a/Source/Bifrost.MongoDb/ConfigurationExtensions.cs
+++ b/Source/Bifrost.MongoDb/ConfigurationExtensions.cs
@@ -3,8 +3,8 @@
* Licensed under the MIT License. See LICENSE in the project root for license information.
*--------------------------------------------------------------------------------------------*/
using System;
-using Bifrost.MongoDB;
-using Bifrost.MongoDB.Events;
+using Bifrost.MongoDb;
+using Bifrost.MongoDb.Events;
namespace Bifrost.Configuration
{
@@ -26,6 +26,12 @@ public static EventStorageConfiguration WithUrl(this EventStorageConfiguration c
return configuration;
}
+ public static EventStorageConfiguration WithSSL(this EventStorageConfiguration configuration)
+ {
+ configuration.UseSSL = true;
+ return configuration;
+ }
+
public static EventStorageConfiguration WithDefaultDatabase(this EventStorageConfiguration configuration, string defaultDatabase)
{
@@ -52,6 +58,12 @@ public static EntityContextConfiguration WithUrl(this EntityContextConfiguration
return configuration;
}
+ public static EntityContextConfiguration WithSSL(this EntityContextConfiguration configuration)
+ {
+ configuration.UseSSL = true;
+ return configuration;
+ }
+
public static EntityContextConfiguration WithDefaultDatabase(this EntityContextConfiguration configuration, string defaultDatabase)
{
diff --git a/Source/Bifrost.MongoDb/EntityContext.cs b/Source/Bifrost.MongoDb/EntityContext.cs
index e268e2540..fbaae71ca 100644
--- a/Source/Bifrost.MongoDb/EntityContext.cs
+++ b/Source/Bifrost.MongoDb/EntityContext.cs
@@ -7,85 +7,91 @@
using Bifrost.Concepts;
using MongoDB.Driver;
using MongoDB.Bson;
-using MongoDB.Driver.Builders;
+using System.Reflection;
-namespace Bifrost.MongoDB
+namespace Bifrost.MongoDb
{
- public class EntityContext : IEntityContext
- {
- EntityContextConnection _connection;
- string _collectionName;
- MongoCollection _collection;
-
- public EntityContext(EntityContextConnection connection)
- {
- _connection = connection;
- _collectionName = typeof(T).Name;
- if( !_connection.Database.CollectionExists(_collectionName) )
- _connection.Database.CreateCollection(_collectionName);
-
- _collection = _connection.Database.GetCollection(_collectionName);
- }
-
-
- public IQueryable Entities
- {
- get { return _collection.FindAll().AsQueryable(); }
- }
-
- public void Attach(T entity)
- {
- }
-
- public void Insert(T entity)
- {
- _collection.Insert(entity);
- }
-
- public void Update(T entity)
- {
- Save(entity);
- }
-
- public void Delete(T entity)
- {
- }
-
- public void Save(T entity)
- {
- _collection.Save(entity);
- }
-
- public void Commit()
- {
- }
-
- public void Dispose()
- {
- }
-
-
- public T GetById(TProperty id)
- {
- var objectId = GetObjectId(id);
- return _collection.FindOneById(objectId);
- }
-
- BsonValue GetObjectId(TProperty id)
- {
- object idValue = id;
-
- if (id.IsConcept()) idValue = id.GetConceptValue();
-
- var idAsValue = BsonValue.Create(idValue);
- return idAsValue;
- }
-
-
- public void DeleteById(TProperty id)
- {
- var objectId = GetObjectId(id);
- _collection.Remove(Query.EQ("_id", objectId));
- }
- }
+ public class EntityContext : IEntityContext
+ {
+ EntityContextConnection _connection;
+ string _collectionName;
+ IMongoCollection _collection;
+
+ public EntityContext(EntityContextConnection connection)
+ {
+ _connection = connection;
+ _collectionName = typeof(T).Name;
+
+ _collection = _connection.Database.GetCollection(_collectionName);
+ }
+
+
+ public IQueryable Entities
+ {
+ get { return _collection.AsQueryable(); }
+ }
+
+ public void Attach(T entity)
+ {
+ }
+
+ public void Insert(T entity)
+ {
+ _collection.InsertOne(entity);
+ }
+
+ public void Update(T entity)
+ {
+ Save(entity);
+ }
+
+ public void Delete(T entity)
+ {
+ }
+
+ public void Save(T entity)
+ {
+ var idProperty = GetIdProperty(entity);
+
+ var filter = Builders.Filter.Eq("_id", idProperty.GetValue(entity));
+ _collection.ReplaceOne(filter, entity, new UpdateOptions() { IsUpsert = true });
+ }
+
+ public void Commit()
+ {
+ }
+
+ public void Dispose()
+ {
+ }
+
+ PropertyInfo GetIdProperty(T entity)
+ {
+ return typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.Name.ToLowerInvariant() == "id").First();
+ }
+
+
+ public T GetById(TProperty id)
+ {
+ var objectId = GetObjectId(id);
+ return _collection.Find(Builders.Filter.Eq("_id", objectId)).FirstOrDefault();
+ }
+
+ BsonValue GetObjectId(TProperty id)
+ {
+ object idValue = id;
+
+ if (id.IsConcept()) idValue = id.GetConceptValue();
+
+ var idAsValue = BsonValue.Create(idValue);
+ return idAsValue;
+ }
+
+
+ public void DeleteById(TProperty id)
+ {
+ var objectId = GetObjectId(id);
+ _collection.DeleteOne(Builders.Filter.Eq("id", objectId));
+ }
+ }
}
diff --git a/Source/Bifrost.MongoDb/EntityContextConfiguration.cs b/Source/Bifrost.MongoDb/EntityContextConfiguration.cs
index 7ac20534b..ae0fea3ef 100644
--- a/Source/Bifrost.MongoDb/EntityContextConfiguration.cs
+++ b/Source/Bifrost.MongoDb/EntityContextConfiguration.cs
@@ -6,11 +6,12 @@
using Bifrost.Configuration;
using Bifrost.Entities;
-namespace Bifrost.MongoDB
+namespace Bifrost.MongoDb
{
public class EntityContextConfiguration : IEntityContextConfiguration
{
public string Url { get; set; }
+ public bool UseSSL { get; set; }
public string DefaultDatabase { get; set; }
public Type EntityContextType { get { return typeof(EntityContext<>); } }
diff --git a/Source/Bifrost.MongoDb/EntityContextConnection.cs b/Source/Bifrost.MongoDb/EntityContextConnection.cs
index df5c9e5ae..036dfffa2 100644
--- a/Source/Bifrost.MongoDb/EntityContextConnection.cs
+++ b/Source/Bifrost.MongoDb/EntityContextConnection.cs
@@ -4,27 +4,33 @@
*--------------------------------------------------------------------------------------------*/
using Bifrost.Entities;
using Bifrost.Execution;
-using Bifrost.MongoDB.Concepts;
+using Bifrost.MongoDb.Concepts;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
-namespace Bifrost.MongoDB
+namespace Bifrost.MongoDb
{
public class EntityContextConnection : IEntityContextConnection
{
- public string ConnectionString { get; private set; }
- public string DatabaseName { get; private set; }
-
- public MongoServer Server { get; private set; }
- public MongoDatabase Database { get; private set; }
+ public MongoClient Server { get; private set; }
+ public IMongoDatabase Database { get; private set; }
public EntityContextConnection(EntityContextConfiguration configuration)
{
- ConnectionString = configuration.Url;
- DatabaseName = configuration.DefaultDatabase;
+ var s = MongoClientSettings.FromUrl(new MongoUrl(configuration.Url));
+ if (configuration.UseSSL)
+ {
+ s.UseSsl = true;
+ s.SslSettings = new SslSettings
+ {
+ EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12,
+ CheckCertificateRevocation = false
+ };
+ }
+
+ Server = new MongoClient(s);
+ Database = Server.GetDatabase(configuration.DefaultDatabase);
- Server = MongoServer.Create(ConnectionString);
- Database = Server.GetDatabase(DatabaseName);
BsonSerializer.RegisterSerializationProvider(new ConceptSerializationProvider());
}
diff --git a/Source/Bifrost.MongoDb/EventClassMap.cs b/Source/Bifrost.MongoDb/EventClassMap.cs
index f072877f7..29d7e0359 100644
--- a/Source/Bifrost.MongoDb/EventClassMap.cs
+++ b/Source/Bifrost.MongoDb/EventClassMap.cs
@@ -5,7 +5,7 @@
using Bifrost.Events;
using MongoDB.Bson.Serialization;
-namespace Bifrost.MongoDB
+namespace Bifrost.MongoDb
{
public class EventClassMap : BsonClassMap
{
diff --git a/Source/Bifrost.MongoDb/Events/BsonSerializationProvider.cs b/Source/Bifrost.MongoDb/Events/BsonSerializationProvider.cs
index 798f2ba20..28da96512 100644
--- a/Source/Bifrost.MongoDb/Events/BsonSerializationProvider.cs
+++ b/Source/Bifrost.MongoDb/Events/BsonSerializationProvider.cs
@@ -6,7 +6,7 @@
using System.Reflection;
using MongoDB.Bson.Serialization;
-namespace Bifrost.MongoDB.Events
+namespace Bifrost.MongoDb.Events
{
public class BsonSerializationProvider : IBsonSerializationProvider
{
diff --git a/Source/Bifrost.MongoDb/Events/EventSourceVersionSerializer.cs b/Source/Bifrost.MongoDb/Events/EventSourceVersionSerializer.cs
index a3c3045d5..3092612b4 100644
--- a/Source/Bifrost.MongoDb/Events/EventSourceVersionSerializer.cs
+++ b/Source/Bifrost.MongoDb/Events/EventSourceVersionSerializer.cs
@@ -8,45 +8,30 @@
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Options;
-namespace Bifrost.MongoDB.Events
+namespace Bifrost.MongoDb.Events
{
- public class EventSourceVersionSerializer : IBsonSerializer
- {
- public object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
- {
- var versionAsDouble = bsonReader.ReadDouble();
- var version = EventSourceVersion.FromCombined(versionAsDouble);
- return version;
- }
-
- public void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
- {
- var version = (EventSourceVersion)value;
- var versionAsDouble = version.Combine();
- bsonWriter.WriteDouble(versionAsDouble);
- }
-
-
- public object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
- {
- throw new NotImplementedException();
- }
-
- public bool GetDocumentId(object document, out object id, out Type idNominalType, out IIdGenerator idGenerator)
- {
- throw new NotImplementedException();
- }
-
- public void SetDocumentId(object document, object id)
- {
- throw new NotImplementedException();
- }
-
- public IBsonSerializationOptions GetDefaultSerializationOptions()
- {
- var options = new DocumentSerializationOptions();
- return options;
- }
-
- }
+ public class EventSourceVersionSerializer : IBsonSerializer
+ {
+ public Type ValueType
+ {
+ get
+ {
+ return typeof(EventSourceVersion);
+ }
+ }
+
+ public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
+ {
+ var versionAsDouble = context.Reader.ReadDouble();
+ var version = EventSourceVersion.FromCombined(versionAsDouble);
+ return version;
+ }
+
+ public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
+ {
+ var version = (EventSourceVersion)value;
+ var versionAsDouble = version.Combine();
+ context.Writer.WriteDouble(versionAsDouble);
+ }
+ }
}
diff --git a/Source/Bifrost.MongoDb/Events/EventStorageConfiguration.cs b/Source/Bifrost.MongoDb/Events/EventStorageConfiguration.cs
index 2b55c1348..6d49ff281 100644
--- a/Source/Bifrost.MongoDb/Events/EventStorageConfiguration.cs
+++ b/Source/Bifrost.MongoDb/Events/EventStorageConfiguration.cs
@@ -4,21 +4,15 @@
*--------------------------------------------------------------------------------------------*/
using System.Net;
-namespace Bifrost.MongoDB.Events
+namespace Bifrost.MongoDb.Events
{
///
/// Represents the configuration for
///
public class EventStorageConfiguration
{
- ///
- /// Gets or sets the Url for the mongo server
- ///
public string Url { get; set; }
-
- ///
- /// Gets or sets the default database to use
- ///
+ public bool UseSSL { get; set; }
public string DefaultDatabase { get; set; }
}
}
diff --git a/Source/Bifrost.MongoDb/Events/EventStore.cs b/Source/Bifrost.MongoDb/Events/EventStore.cs
index d68d35fc5..d30b9c87f 100644
--- a/Source/Bifrost.MongoDb/Events/EventStore.cs
+++ b/Source/Bifrost.MongoDb/Events/EventStore.cs
@@ -9,162 +9,167 @@
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
-using MongoDB.Driver.Builders;
-namespace Bifrost.MongoDB.Events
+namespace Bifrost.MongoDb.Events
{
- public class EventStore : IEventStore
- {
- const string CollectionName = "Events";
- const string IncrementalKeysCollectionName = "_IncrementalKeys";
- const string EventType = "EventType";
- const string Generation = "Generation";
- const string Version = "Version";
- const string LogicalEventType = "LogicalEventType";
- const string CurrentKey = "CurrentKey";
-
- EventStorageConfiguration _configuration;
- MongoServer _server;
- MongoDatabase _database;
- MongoCollection _collection;
- MongoCollection _incrementalKeysCollection;
- IEventMigrationHierarchyManager _eventMigrationHierarchyManager;
-
- static EventStore()
- {
- BsonSerializer.RegisterSerializer(typeof(EventSourceVersion), new EventSourceVersionSerializer());
- }
-
- public EventStore(EventStorageConfiguration configuration, IEventMigrationHierarchyManager eventMigrationHierarchyManager)
- {
- _configuration = configuration;
- _eventMigrationHierarchyManager = eventMigrationHierarchyManager;
- Initialize();
- }
-
- void Initialize()
- {
- _server = MongoServer.Create(_configuration.Url);
- _database = _server.GetDatabase(_configuration.DefaultDatabase);
- if (!_database.CollectionExists(CollectionName))
- _database.CreateCollection(CollectionName);
-
- _collection = _database.GetCollection(CollectionName);
-
- if (!_database.CollectionExists(IncrementalKeysCollectionName))
- _database.CreateCollection(IncrementalKeysCollectionName);
-
- _incrementalKeysCollection = _database.GetCollection(IncrementalKeysCollectionName);
- }
-
- public CommittedEventStream GetForEventSource(EventSource eventSource, Guid eventSourceId)
- {
- var eventSourceType = eventSource.GetType();
- var query = Query.And(
- Query.EQ("EventSourceId", eventSourceId),
- Query.EQ("EventSource", eventSourceType.AssemblyQualifiedName)
- );
-
- var cursor = _collection.FindAs(query);
- var documents = cursor.ToArray();
- var events = ToEvents(documents);
- var stream = new CommittedEventStream(eventSourceId);
- stream.Append(events);
- return stream;
- }
-
- public CommittedEventStream Commit(UncommittedEventStream uncommittedEventStream)
- {
- var eventArray = uncommittedEventStream.ToArray();
- for (var eventIndex = 0; eventIndex < eventArray.Length; eventIndex++)
- {
- var @event = eventArray[eventIndex];
- @event.Id = GetNextEventId();
- var eventDocument = @event.ToBsonDocument();
- AddMetaData(@event, eventDocument);
- _collection.Insert(eventDocument);
- }
-
- var committedEventStream = new CommittedEventStream(uncommittedEventStream.EventSourceId);
- committedEventStream.Append(uncommittedEventStream);
- return committedEventStream;
- }
-
- public EventSourceVersion GetLastCommittedVersion(EventSource eventSource, Guid eventSourceId)
- {
- var query = Query.EQ("EventSourceId", eventSourceId);
- var sort = SortBy.Descending(Version);
- var @event = _collection.FindAs(query).SetSortOrder(sort).FirstOrDefault();
- if (@event == null)
- return EventSourceVersion.Zero;
-
- return EventSourceVersion.FromCombined(@event[Version].AsDouble);
- }
-
- public IEnumerable GetBatch(int batchesToSkip, int batchSize)
- {
- var cursor = _collection.FindAllAs();
- cursor.SetSkip(batchSize * batchesToSkip);
- cursor.SetLimit(batchSize);
- var documents = cursor.ToArray();
- var events = ToEvents(documents);
- return events;
- }
-
- public IEnumerable GetAll()
- {
- var documents = _collection.FindAllAs().ToArray();
- var events = ToEvents(documents);
- return events;
- }
-
- int GetNextEventId()
- {
- var currentValue = 0;
- var query = Query.EQ("_id", CollectionName);
- var result = _incrementalKeysCollection.FindAndModify(query, SortBy.Null, Update.Inc(CurrentKey, 1), true);
- if (result.ModifiedDocument == null)
- {
- var eventsCurrentValue = new BsonDocument();
- eventsCurrentValue["_id"] = CollectionName;
- eventsCurrentValue[CurrentKey] = 1;
- _incrementalKeysCollection.Insert(eventsCurrentValue);
- currentValue = 1;
- }
- else
- currentValue = result.ModifiedDocument[CurrentKey].AsInt32;
- return currentValue;
- }
-
- void AddMetaData(IEvent @event, BsonDocument eventDocument)
- {
- var eventType = @event.GetType();
- var logicalEventType = _eventMigrationHierarchyManager.GetLogicalTypeForEvent(eventType);
- var migrationLevel = _eventMigrationHierarchyManager.GetCurrentMigrationLevelForLogicalEvent(logicalEventType);
- eventDocument[EventType] = string.Format("{0}, {1}", eventType.FullName, eventType.Assembly.GetName().Name);
- eventDocument[LogicalEventType] = string.Format("{0}, {1}", logicalEventType.FullName, logicalEventType.Assembly.GetName().Name);
- eventDocument[Generation] = migrationLevel;
- }
-
- void RemoveMetaData(BsonDocument document)
- {
- document.Remove(EventType);
- document.Remove(LogicalEventType);
- document.Remove(Generation);
- }
-
- IEnumerable ToEvents(IEnumerable documents)
- {
- var events = new List();
-
- foreach (var document in documents)
- {
- var eventType = Type.GetType(document[EventType].AsString);
- RemoveMetaData(document);
- var instance = BsonSerializer.Deserialize(document, eventType) as IEvent;
- events.Add(instance);
- }
- return events;
- }
- }
+ public class EventStore : IEventStore
+ {
+ const string CollectionName = "Events";
+ const string IncrementalKeysCollectionName = "_IncrementalKeys";
+ const string EventType = "EventType";
+ const string Generation = "Generation";
+ const string Version = "Version";
+ const string LogicalEventType = "LogicalEventType";
+ const string CurrentKey = "CurrentKey";
+
+ EventStorageConfiguration _configuration;
+ MongoClient _server;
+ IMongoDatabase _database;
+ IMongoCollection _collection;
+ IMongoCollection _incrementalKeysCollection;
+ IEventMigrationHierarchyManager _eventMigrationHierarchyManager;
+
+ static EventStore()
+ {
+ BsonSerializer.RegisterSerializer(typeof(EventSourceVersion), new EventSourceVersionSerializer());
+ }
+
+ public EventStore(EventStorageConfiguration configuration, IEventMigrationHierarchyManager eventMigrationHierarchyManager)
+ {
+ _configuration = configuration;
+ _eventMigrationHierarchyManager = eventMigrationHierarchyManager;
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ var s = MongoClientSettings.FromUrl(new MongoUrl(_configuration.Url));
+ if (_configuration.UseSSL)
+ {
+ s.UseSsl = true;
+ s.SslSettings = new SslSettings
+ {
+ EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12,
+ CheckCertificateRevocation = false
+ };
+ }
+ _server = new MongoClient(s);
+
+
+ _database = _server.GetDatabase(_configuration.DefaultDatabase);
+
+ _collection = _database.GetCollection(CollectionName);
+
+ _incrementalKeysCollection = _database.GetCollection(IncrementalKeysCollectionName);
+ }
+
+ public CommittedEventStream GetForEventSource(EventSource eventSource, Guid eventSourceId)
+ {
+ var eventSourceType = eventSource.GetType();
+ var builder = Builders.Filter;
+ var filter = builder.Eq("EventSourceId", eventSourceId) & builder.Eq("EventSource", eventSourceType.AssemblyQualifiedName);
+
+ var cursor = _collection.Find(filter);
+ var documents = cursor.ToList();
+ var events = ToEvents(documents);
+ var stream = new CommittedEventStream(eventSourceId);
+ stream.Append(events);
+ return stream;
+ }
+
+ public CommittedEventStream Commit(UncommittedEventStream uncommittedEventStream)
+ {
+ var eventArray = uncommittedEventStream.ToArray();
+ for (var eventIndex = 0; eventIndex < eventArray.Length; eventIndex++)
+ {
+ var @event = eventArray[eventIndex];
+ @event.Id = GetNextEventId();
+ var eventDocument = @event.ToBsonDocument();
+ AddMetaData(@event, eventDocument);
+ _collection.InsertOne(eventDocument);
+ }
+
+ var committedEventStream = new CommittedEventStream(uncommittedEventStream.EventSourceId);
+ committedEventStream.Append(uncommittedEventStream);
+ return committedEventStream;
+ }
+
+ public EventSourceVersion GetLastCommittedVersion(EventSource eventSource, Guid eventSourceId)
+ {
+ var filter = Builders.Filter.Eq("EventSourceId", eventSourceId);
+ var @event = _collection.Find(filter).SortBy(d => d.GetElement(Version)).FirstOrDefault();
+ if (@event == null)
+ return EventSourceVersion.Zero;
+
+ return EventSourceVersion.FromCombined(@event[Version].AsDouble);
+ }
+
+ public IEnumerable GetBatch(int batchesToSkip, int batchSize)
+ {
+ var cursor = _collection.Find(new BsonDocument());
+ cursor.Skip(batchSize * batchesToSkip);
+ cursor.Limit(batchSize);
+ var documents = cursor.ToList();
+ var events = ToEvents(documents);
+ return events;
+ }
+
+ public IEnumerable GetAll()
+ {
+ var documents = _collection.Find(new BsonDocument()).ToList();
+ var events = ToEvents(documents);
+ return events;
+ }
+
+ int GetNextEventId()
+ {
+ var currentValue = 0;
+ var query = Builders.Filter.Eq("_id", CollectionName);
+ var result = _incrementalKeysCollection.FindOneAndUpdate(query, Builders.Update.Inc(CurrentKey, 1), new FindOneAndUpdateOptions() { ReturnDocument = ReturnDocument.After, IsUpsert = true });
+
+ //TODO: Is this really necessary? The above is an upsert?
+ if (result?.AsBsonDocument == null)
+ {
+ var eventsCurrentValue = new BsonDocument();
+ eventsCurrentValue["_id"] = CollectionName;
+ eventsCurrentValue[CurrentKey] = 1;
+ _incrementalKeysCollection.InsertOne(eventsCurrentValue);
+ currentValue = 1;
+ }
+ else
+ currentValue = result.AsBsonDocument[CurrentKey].AsInt32;
+ return currentValue;
+ }
+
+ void AddMetaData(IEvent @event, BsonDocument eventDocument)
+ {
+ var eventType = @event.GetType();
+ var logicalEventType = _eventMigrationHierarchyManager.GetLogicalTypeForEvent(eventType);
+ var migrationLevel = _eventMigrationHierarchyManager.GetCurrentMigrationLevelForLogicalEvent(logicalEventType);
+ eventDocument[EventType] = string.Format("{0}, {1}", eventType.FullName, eventType.Assembly.GetName().Name);
+ eventDocument[LogicalEventType] = string.Format("{0}, {1}", logicalEventType.FullName, logicalEventType.Assembly.GetName().Name);
+ eventDocument[Generation] = migrationLevel;
+ }
+
+ void RemoveMetaData(BsonDocument document)
+ {
+ document.Remove(EventType);
+ document.Remove(LogicalEventType);
+ document.Remove(Generation);
+ }
+
+ IEnumerable ToEvents(IEnumerable documents)
+ {
+ var events = new List();
+
+ foreach (var document in documents)
+ {
+ var eventType = Type.GetType(document[EventType].AsString);
+ RemoveMetaData(document);
+ var instance = BsonSerializer.Deserialize(document, eventType) as IEvent;
+ events.Add(instance);
+ }
+ return events;
+ }
+ }
}
diff --git a/Source/Bifrost.MongoDb/Events/EventSubscriptions.cs b/Source/Bifrost.MongoDb/Events/EventSubscriptions.cs
index 548c43779..f3c24faf6 100644
--- a/Source/Bifrost.MongoDb/Events/EventSubscriptions.cs
+++ b/Source/Bifrost.MongoDb/Events/EventSubscriptions.cs
@@ -9,18 +9,18 @@
using Bifrost.Events;
using MongoDB.Bson.Serialization;
using MongoDB.Driver;
-using MongoDB.Driver.Builders;
+using MongoDB.Bson;
-namespace Bifrost.MongoDB.Events
+namespace Bifrost.MongoDb.Events
{
public class EventSubscriptions : IEventSubscriptions
{
const string CollectionName = "EventSubscriptions";
EventStorageConfiguration _configuration;
- MongoServer _server;
- MongoDatabase _database;
- MongoCollection _collection;
+ MongoClient _server;
+ IMongoDatabase _database;
+ IMongoCollection _collection;
static EventSubscriptions()
{
@@ -37,10 +37,20 @@ public EventSubscriptions(EventStorageConfiguration configuration)
void Initialize()
{
- _server = MongoServer.Create(_configuration.Url);
- _database = _server.GetDatabase(_configuration.DefaultDatabase);
- if (!_database.CollectionExists(CollectionName))
- _database.CreateCollection(CollectionName);
+ var s = MongoClientSettings.FromUrl(new MongoUrl(_configuration.Url));
+ if (_configuration.UseSSL)
+ {
+ s.UseSsl = true;
+ s.SslSettings = new SslSettings
+ {
+ EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12,
+ CheckCertificateRevocation = false
+ };
+ }
+
+ _server = new MongoClient(s);
+
+ _database = _server.GetDatabase(_configuration.DefaultDatabase);
_collection = _database.GetCollection(CollectionName);
}
@@ -48,18 +58,21 @@ void Initialize()
public IEnumerable GetAll()
{
- return _collection.FindAll().ToArray();
+ return _collection.Find(new BsonDocument()).ToList();
}
public void Save(EventSubscription subscription)
{
- _collection.Save(subscription);
+ var filter = Builders.Filter.Eq(s => s.Id, subscription.Id);
+ //var update = Builders.Update.
+ _collection.ReplaceOne(filter, subscription, new UpdateOptions() { IsUpsert = true });
}
public void ResetLastEventForAllSubscriptions()
{
- var update = Update.Set("LastEventId",0);
- _collection.Update(Query.Null, update, UpdateFlags.Multi);
+ var update = Builders.Update.Set(s => s.LastEventId, 0);
+
+ _collection.UpdateMany(new BsonDocument(), update);
}
}
}
diff --git a/Source/Bifrost.MongoDb/Events/MethodInfoSerializer.cs b/Source/Bifrost.MongoDb/Events/MethodInfoSerializer.cs
index 47bdd2d47..1428dc1c5 100644
--- a/Source/Bifrost.MongoDb/Events/MethodInfoSerializer.cs
+++ b/Source/Bifrost.MongoDb/Events/MethodInfoSerializer.cs
@@ -10,79 +10,68 @@
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Options;
-namespace Bifrost.MongoDB.Events
+namespace Bifrost.MongoDb.Events
{
- public class MethodInfoSerializer : IBsonSerializer
- {
- public object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
- {
- bsonReader.ReadStartDocument();
-
- bsonReader.ReadName();
- var typeName = bsonReader.ReadString();
- bsonReader.ReadName();
- var methodSignature = bsonReader.ReadString();
-
- bsonReader.ReadEndDocument();
-
- var type = Type.GetType(typeName);
- if (type != null)
- {
- var method = type.GetMethods().Where(m => GetMethodSignature(m) == methodSignature).SingleOrDefault();
- return method;
- }
-
- return null;
- }
-
- public void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
- {
- var method = (MethodInfo)value;
-
- bsonWriter.WriteStartDocument();
- bsonWriter.WriteName("Type");
- bsonWriter.WriteString(method.DeclaringType.AssemblyQualifiedName);
- bsonWriter.WriteName("Method");
- bsonWriter.WriteString(GetMethodSignature(method));
-
- bsonWriter.WriteEndDocument();
-
- }
-
- string GetMethodSignature(MethodInfo method)
- {
- var builder = new StringBuilder();
- builder.Append(method.Name);
- builder.Append("(");
-
- foreach (var parameter in method.GetParameters())
- builder.AppendFormat("{0} {1}", parameter.ParameterType.Name, parameter.Name);
-
- builder.Append(")");
- return builder.ToString();
- }
-
-
- public object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
- {
- throw new NotImplementedException();
- }
-
- public bool GetDocumentId(object document, out object id, out Type idNominalType, out IIdGenerator idGenerator)
- {
- throw new NotImplementedException();
- }
-
- public void SetDocumentId(object document, object id)
- {
- throw new NotImplementedException();
- }
-
- public IBsonSerializationOptions GetDefaultSerializationOptions()
- {
- var options = new DocumentSerializationOptions();
- return options;
- }
-
- }
+ public class MethodInfoSerializer : IBsonSerializer
+ {
+ public Type ValueType
+ {
+ get
+ {
+ return typeof(MethodInfo);
+ }
+ }
+
+ public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
+ {
+ var bsonReader = context.Reader;
+ bsonReader.ReadStartDocument();
+
+ bsonReader.ReadName();
+ var typeName = bsonReader.ReadString();
+ bsonReader.ReadName();
+ var methodSignature = bsonReader.ReadString();
+
+ bsonReader.ReadEndDocument();
+
+ var type = Type.GetType(typeName);
+ if (type != null)
+ {
+ var method = type.GetMethods().Where(m => GetMethodSignature(m) == methodSignature).SingleOrDefault();
+ return method;
+ }
+
+ return null;
+ }
+
+ public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
+ {
+ var method = (MethodInfo)value;
+ var bsonWriter = context.Writer;
+
+ bsonWriter.WriteStartDocument();
+ bsonWriter.WriteName("Type");
+ bsonWriter.WriteString(method.DeclaringType.AssemblyQualifiedName);
+ bsonWriter.WriteName("Method");
+ bsonWriter.WriteString(GetMethodSignature(method));
+
+ bsonWriter.WriteEndDocument();
+ }
+
+ string GetMethodSignature(MethodInfo method)
+ {
+ var builder = new StringBuilder();
+ builder.Append(method.Name);
+ builder.Append("(");
+
+ foreach (var parameter in method.GetParameters())
+ builder.AppendFormat("{0} {1}", parameter.ParameterType.Name, parameter.Name);
+
+ builder.Append(")");
+ return builder.ToString();
+ }
+
+
+
+ }
}
diff --git a/Source/Bifrost.MongoDb/Events/TypeSerializer.cs b/Source/Bifrost.MongoDb/Events/TypeSerializer.cs
index ed3147071..2f73dcb38 100644
--- a/Source/Bifrost.MongoDb/Events/TypeSerializer.cs
+++ b/Source/Bifrost.MongoDb/Events/TypeSerializer.cs
@@ -7,44 +7,30 @@
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Options;
-namespace Bifrost.MongoDB.Events
+namespace Bifrost.MongoDb.Events
{
- public class TypeSerializer : IBsonSerializer
- {
- public object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
- {
- var typeName = bsonReader.ReadString();
- var type = Type.GetType(typeName);
- return type;
- }
-
- public void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
- {
- var type = (Type)value;
- bsonWriter.WriteString(type.AssemblyQualifiedName);
- }
-
-
-
- public object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
- {
- throw new NotImplementedException();
- }
-
- public bool GetDocumentId(object document, out object id, out Type idNominalType, out IIdGenerator idGenerator)
- {
- throw new NotImplementedException();
- }
-
- public void SetDocumentId(object document, object id)
- {
- throw new NotImplementedException();
- }
-
- public IBsonSerializationOptions GetDefaultSerializationOptions()
- {
- var options = new DocumentSerializationOptions();
- return options;
- }
- }
+ public class TypeSerializer : IBsonSerializer
+ {
+ public Type ValueType
+ {
+ get
+ {
+ return typeof(Type);
+ }
+ }
+ public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
+ {
+ var bsonReader = context.Reader;
+ var typeName = bsonReader.ReadString();
+ var type = Type.GetType(typeName);
+ return type;
+ }
+
+ public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
+ {
+ var type = (Type)value;
+ var bsonWriter = context.Writer;
+ bsonWriter.WriteString(type.AssemblyQualifiedName);
+ }
+ }
}
diff --git a/Source/Bifrost.MongoDb/packages.config b/Source/Bifrost.MongoDb/packages.config
index 5a514137b..75ea6d2ef 100644
--- a/Source/Bifrost.MongoDb/packages.config
+++ b/Source/Bifrost.MongoDb/packages.config
@@ -1,4 +1,25 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/Bifrost.MongoDb/project.json b/Source/Bifrost.MongoDb/project.json
index 52a560256..5c9ffea6d 100644
--- a/Source/Bifrost.MongoDb/project.json
+++ b/Source/Bifrost.MongoDb/project.json
@@ -40,8 +40,8 @@
"debugType": "portable"
},
"dependencies": {
- "Bifrost": "1.0.0-*",
- "mongocsharpdriver": "1.9.2"
+ "Bifrost": "1.0.0-*",
+ "MongoDB.Driver": "2.4.2"
},
"runtimes": {
"win": {}