private static void EventAppeared(EventStoreCatchUpSubscription s, ResolvedEvent e) { if (e.Event.EventType != "withdrew") { return; } var o = e.Deserialze(); var withdrew = o as V1.Withdrew; var withdrewFix = new V1.WithdrewFix { Id = withdrew.Id, Amount = new Account().CalculateFee(withdrew.Amount), Description = "my fix", ChangedAt = DateTime.Now, WithdrewId = e.Event.EventId }; var data = new EventData( Guid.NewGuid(), EventTypeMapper.GetTypeName(withdrewFix.GetType()), true, Encoding.Default.GetBytes(JsonConvert.SerializeObject(withdrewFix)), null); eventStoreConnection.AppendToStreamAsync(e.OriginalStreamId, ExpectedVersion.Any, data); Console.WriteLine($"Last position of fix=> {e.OriginalPosition.Value.CommitPosition}"); }
//https://eventstore.org/blog/20130306/getting-started-part-3-subscriptions/ //SubscribeToAllFrom(this IEventStoreConnection target, // Position? lastCheckpoint, // CatchUpSubscriptionSettings settings, // Action<EventStoreCatchUpSubscription, ResolvedEvent> eventAppeared, // Action<EventStoreCatchUpSubscription> liveProcessingStarted = null, // Action<EventStoreCatchUpSubscription, SubscriptionDropReason, Exception> subscriptionDropped = null, // UserCredentials userCredentials = null) private Action <EventStoreCatchUpSubscription, ResolvedEvent> eventAppeared(Projection projection) => async(_, e) => { // check system events and ignore them... if (e.OriginalEvent.EventType.StartsWith("$")) { return; } // find event type var eventType = EventTypeMapper.GetType(e.Event.EventType); if (eventType == null) { return; } // deserialize the event. var domainEvent = e.Deserialze(); //build your projection await projection.Handle(domainEvent); //store current checkpoint await checkpointStore.SetCheckpoint(e.OriginalPosition.Value, projection); Console.WriteLine($"{domainEvent} projected into {projection}"); };
public static object Deserialize(this ResolvedEvent resolvedEvent) { // get type var eventType = EventTypeMapper.ToType(resolvedEvent.Event.EventType); // deserialize event return(JsonConvert.DeserializeObject(Encoding.UTF8.GetString(resolvedEvent.Event.Data.Span), eventType !) !); }
public static object Deserialze(this ResolvedEvent resolvedEvent) { var dataType = EventTypeMapper.GetType(resolvedEvent.Event.EventType); var jsonData = Encoding.UTF8.GetString(resolvedEvent.Event.Data); var data = JsonConvert.DeserializeObject(jsonData, dataType); return(data); }
private async Task BuildEventStore(IServiceCollection services) { //Create EventStore Connection var eventStoreConnection = EventStoreConnection.Create( Configuration["EventStore:ConnectionString"], ConnectionSettings.Create() .KeepReconnecting() .EnableVerboseLogging() .SetHeartbeatInterval(TimeSpan.FromMilliseconds(5 * 1000)) .UseDebugLogger(), Environment.ApplicationName ); eventStoreConnection.Connected += (sender, args) => Console.WriteLine($"Connection to {args.RemoteEndPoint} event store established."); eventStoreConnection.ErrorOccurred += (sender, args) => Console.WriteLine($"Connection error : {args.Exception}"); await eventStoreConnection.ConnectAsync(); var serializer = new JsonNetSerializer(); var eventMapper = new EventTypeMapper() .Map <Domain.Events.V1.ReviewCreated>("reviewCreated") .Map <Domain.Events.V1.CaptionAndContentChanged>("reviewUpdated") .Map <Domain.Events.V1.ReviewPublished>("reviewPublished") .Map <Domain.Events.V1.ReviewApproved>("reviewApproved"); //Dont forget to add ReviewSnapshot event to eventmapper! //.Map<Domain.ReviewSnapshot>("reviewSnapshot"); var aggregateStore = new GesAggrigateStore( eventStoreConnection, serializer, eventMapper, (type, id) => $"{type.Name}-{id}", null); services.AddSingleton(new ApplicationService(aggregateStore)); IAsyncDocumentSession GetSession() => BuildRevenDb().OpenAsyncSession(); await ProjectionManager.With .Connection(eventStoreConnection) .CheckpointStore(new RavenDbChecklpointStore(GetSession)) .Serializer(serializer) .TypeMapper(eventMapper) .SetProjections(new Projection[] { new ActiveReviews(GetSession), new ReviewsByOwner(GetSession) }) .StartAll(); }
public GesSnapshotStoreTest(ITestOutputHelper outputHelper) : base() { this.outputHelper = outputHelper; EventTypeMapper = new EventTypeMapper() .Map <Domain.Events.V1.ReviewCreated>("reviewCreated") .Map <Domain.Events.V1.ReviewApproved>("reviewApproved") .Map <Domain.ReviewSnapshot>("reviewSnapshot"); }
public GesAggregateStoreTest() { Connection = GetConnection().GetAwaiter().GetResult(); Serializer = new JsonNetSerializer(); AutoFixture = new Fixture(); EventTypeMapper = new EventTypeMapper() .Map <Domain.Events.V1.ReviewCreated>("reviewCreated") .Map <Domain.Events.V1.ReviewApproved>("reviewApproved"); }
protected GesBaseTest() { Connection = GetConnection().GetAwaiter().GetResult(); Serializer = new JsonNetSerializer(); AutoFixture = new Fixture(); EventTypeMapper = new EventTypeMapper() .Map <Domain.Events.V1.ReviewCreated>("reviewCreated") .Map <Domain.Events.V1.CaptionAndContentChanged>("reviewUpdated") .Map <Domain.Events.V1.ReviewPublished>("reviewPublished") .Map <Domain.Events.V1.ReviewApproved>("reviewApproved") .Map <Domain.ReviewSnapshot>("reviewSnapshot"); }
public GesSnapshotStore(IEventStoreConnection eventStoreConnection, ISerializer serializer, EventTypeMapper eventTypeMapper, GetStreamName getStreamName, UserCredentials userCredentials = null) { this.eventStoreConnection = eventStoreConnection ?? throw new ArgumentNullException(nameof(eventStoreConnection));; this.serializer = serializer ?? throw new ArgumentException(nameof(serializer)); this.eventTypeMapper = eventTypeMapper ?? throw new ArgumentException(nameof(eventTypeMapper)); this.getStreamName = getStreamName ?? throw new ArgumentException(nameof(getStreamName)); this.userCredentials = userCredentials; }
public async Task <long> SaveSnapshotAsync <T>(Snapshot snapshot) where T : Aggregate { var stream = GetStreamName <T>(snapshot.AggregateId); var snapshotEvent = new EventData( snapshot.Id, EventTypeMapper.GetTypeName(snapshot.GetType()), EventSerializer.IsJsonSerializer, EventSerializer.Serialize(snapshot), null); var result = await eventStoreConnection.AppendToStreamAsync(stream, ExpectedVersion.Any, snapshotEvent); return(result.LogPosition.CommitPosition); }
private async Task BuildEventStore(IServiceCollection services) { //Create EventStore Connection var gesConnection = EventStoreConnection.Create( Configuration["EventStore:ConnectionString"], ConnectionSettings.Create() .KeepReconnecting() .EnableVerboseLogging() .SetHeartbeatInterval(TimeSpan.FromMilliseconds(5 * 1000)) .UseDebugLogger(), Environment.ApplicationName ); gesConnection.Connected += (sender, args) => Console.WriteLine($"Connection to {args.RemoteEndPoint} event store established."); gesConnection.ErrorOccurred += (sender, args) => Console.WriteLine($"Connection error : {args.Exception}"); await gesConnection.ConnectAsync(); var serializer = new JsonNetSerializer(); var eventMapper = new EventTypeMapper() .Map <Domain.Events.V1.ReviewCreated>("reviewCreated"); //Events will be registered to evetTypeMappers //.Map<Domain.Events.V1.CaptionAndContentChanged>("reviewUpdated") //.Map<Domain.Events.V1.ReviewPublished>("reviewPublished") //.Map<Domain.Events.V1.ReviewApproved>("reviewApproved"); var aggregateStore = new GesAggrigateStore( gesConnection, serializer, eventMapper, (type, id) => $"{type.Name}-{id}", null); services.AddSingleton(new ApplicationService(aggregateStore)); }
internal ProjectionManager(IEventStoreConnection eventStoreConnection, ICheckpointStore checkpointStore, ISerializer serializer, EventTypeMapper eventTypeMapper, Projection[] projections, int maxLiveQueueSize, int readBatchSize, bool verboseLogging, UserCredentials userCredentials = null ) { this.eventStoreConnection = eventStoreConnection ?? throw new ArgumentNullException(nameof(eventStoreConnection)); this.checkpointStore = checkpointStore ?? throw new ArgumentNullException(nameof(checkpointStore)); this.serializer = serializer ?? throw new ArgumentNullException(nameof(serializer)); this.eventTypeMapper = eventTypeMapper ?? throw new ArgumentException(nameof(eventTypeMapper)); this.projections = projections; this.userCredentials = userCredentials; this.maxLiveQueueSize = maxLiveQueueSize; this.readBatchSize = readBatchSize; this.verboseLogging = verboseLogging; }
public ProjectionManagerBuilder TypeMapper(EventTypeMapper typeMapper) { this.eventTypeMapper = typeMapper; return(this); }