public override Task Invoke(IIncomingLogicalMessageContext context, Func <Task> next) { var command = context.Message.Instance as ICommand; if (command == null) { return(next()); } Commands.Mark(context.Message.MessageType.FullName); var mutators = context.Builder.BuildAll <ICommandMutator>(); if (!mutators.Any()) { return(next()); } IMutating mutated = new Mutating(command, context.Headers); foreach (var mutator in mutators) { Logger.Write(LogLevel.Debug, () => $"Mutating incoming command {context.Message.MessageType.FullName} with mutator {mutator.GetType().FullName}"); mutated = mutator.MutateIncoming(mutated); } // Todo: maybe have a small bool to set if they actually changed headers, save some cycles foreach (var header in mutated.Headers) { context.Headers[header.Key] = header.Value; } context.UpdateMessageInstance(mutated.Message); return(next()); }
public override Task Invoke(IOutgoingLogicalMessageContext context, Func <Task> next) { var @event = context.Message.Instance as IEvent; if (@event == null) { return(next()); } Events.Mark(context.Message.MessageType.FullName); var mutators = context.Builder.BuildAll <IEventMutator>(); if (!mutators.Any()) { return(next()); } IMutating mutated = new Mutating(@event, context.Headers ?? new Dictionary <string, string>()); foreach (var mutator in mutators) { Logger.Write(LogLevel.Debug, () => $"Mutating outgoing event {context.Message.MessageType.FullName} with mutator {mutator.GetType().FullName}"); mutated = mutator.MutateOutgoing(mutated); } foreach (var header in mutated.Headers) { context.Headers[header.Key] = header.Value; } context.UpdateMessage(mutated.Message); return(next()); }
public override Task Invoke(IOutgoingLogicalMessageContext context, Func <Task> next) { // Set aggregates.net message and corr id if (context.Headers.ContainsKey(Headers.MessageId)) { context.Headers[$"{Defaults.PrefixHeader}.{Defaults.MessageIdHeader}"] = context.Headers[Headers.MessageId]; } if (context.Headers.ContainsKey(Headers.CorrelationId)) { context.Headers[$"{Defaults.PrefixHeader}.{Defaults.CorrelationIdHeader}"] = context.Headers[Headers.CorrelationId]; } if (context.GetMessageIntent() == MessageIntentEnum.Reply) { return(next()); } IMutating mutated = new Mutating(context.Message.Instance, context.Headers ?? new Dictionary <string, string>()); var mutators = MutationManager.Registered.ToList(); if (!mutators.Any()) { return(next()); } IContainer container; if (!context.Extensions.TryGet <IContainer>(out container)) { container = Configuration.Settings.Container.GetChildContainer(); } foreach (var type in mutators) { try { var mutator = (IMutate)container.Resolve(type); mutated = mutator.MutateOutgoing(mutated); } catch (Exception e) { Logger.WarnEvent("MutateFailure", e, "Failed to run mutator {Mutator}", type.FullName); } } foreach (var header in mutated.Headers) { context.Headers[header.Key] = header.Value; } context.UpdateMessage(mutated.Message); return(next()); }
public override Task Invoke(IIncomingLogicalMessageContext context, Func <Task> next) { if (context.GetMessageIntent() == MessageIntentEnum.Reply) { return(next()); } IMutating mutated = new Mutating(context.Message.Instance, context.Headers ?? new Dictionary <string, string>()); var mutators = MutationManager.Registered.ToList(); if (!mutators.Any()) { return(next()); } IContainer container; if (!context.Extensions.TryGet <IContainer>(out container)) { container = Configuration.Settings.Container; } foreach (var type in mutators) { try { var mutator = (IMutate)container.Resolve(type); mutated = mutator.MutateIncoming(mutated); } catch (Exception e) { Logger.WarnEvent("MutateFailure", e, "Failed to run mutator {Mutator}", type.FullName); } } foreach (var header in mutated.Headers) { context.Headers[header.Key] = header.Value; } context.UpdateMessageInstance(mutated.Message); return(next()); }
private IWritableEvent MakeWritableEvent(IEvent @event, IDictionary <string, string> headers, bool version = true) { var writable = new WritableEvent { Descriptor = new EventDescriptor { EntityType = typeof(T).AssemblyQualifiedName, StreamType = StreamType, Bucket = Bucket, StreamId = StreamId, Timestamp = DateTime.UtcNow, Version = version ? StreamVersion + 1 : StreamVersion, Headers = headers ?? new Dictionary <string, string>() }, EventId = UnitOfWork.NextEventId(_commitId), Event = @event }; var mutators = _builder.BuildAll <IEventMutator>(); if (!mutators.Any()) { return(writable); } IMutating mutated = new Mutating(writable.Event, writable.Descriptor.Headers); foreach (var mutate in mutators) { Logger.Write(LogLevel.Debug, () => $"Mutating outgoing event {@event.GetType().FullName} with mutator {mutate.GetType().FullName}"); mutated = mutate.MutateOutgoing(mutated); } foreach (var header in mutated.Headers) { writable.Descriptor.Headers[header.Key] = header.Value; } writable.Event = mutated.Message; return(writable); }
public override Task Invoke(IIncomingLogicalMessageContext context, Func <Task> next) { _metrics.Mark("Incoming Messages", Unit.Message); IMutating mutated = new Mutating(context.Message.Instance, context.Headers ?? new Dictionary <string, string>()); var mutators = MutationManager.Registered.ToList(); if (!mutators.Any()) { return(next()); } IContainer container; if (!context.Extensions.TryGet <IContainer>(out container)) { container = Configuration.Settings.Container; } foreach (var type in mutators) { var mutator = (IMutate)container.TryResolve(type); if (mutator == null) { continue; } Logger.Write(LogLevel.Debug, () => $"Mutating incoming message {context.Message.MessageType.FullName} with mutator {type.FullName}"); mutated = mutator.MutateIncoming(mutated); } foreach (var header in mutated.Headers) { context.Headers[header.Key] = header.Value; } context.UpdateMessageInstance(mutated.Message); return(next()); }
public async Task WriteStream <T>(Guid commitId, IEventStream stream, IDictionary <string, string> commitHeaders) where T : class, IEventSource { var streamName = _streamGen(typeof(T), StreamTypes.Domain, stream.Bucket, stream.StreamId, stream.Parents); Logger.Write(LogLevel.Debug, () => $"Writing {stream.Uncommitted.Count()} events to stream {stream.StreamId} bucket {stream.Bucket} with commit id {commitId}"); if (await CheckFrozen <T>(stream.Bucket, stream.StreamId, stream.Parents).ConfigureAwait(false)) { throw new FrozenException(); } Saved.Mark(); var events = stream.Uncommitted.Select(writable => { IMutating mutated = new Mutating(writable.Event, writable.Descriptor.Headers); foreach (var mutate in _mutators) { Logger.Write(LogLevel.Debug, () => $"Mutating outgoing event {writable.Event.GetType()} with mutator {mutate.GetType().FullName}"); mutated = mutate.MutateOutgoing(mutated); } // Todo: have some bool that is set true if they modified headers if (_mutators.Any()) { foreach (var header in mutated.Headers) { writable.Descriptor.Headers[header.Key] = header.Value; } } return((IFullEvent) new WritableEvent { Descriptor = writable.Descriptor, Event = mutated.Message, EventId = UnitOfWork.NextEventId(commitId) }); }).ToList(); var oobs = stream.Oobs.ToDictionary(x => x.Id, x => x); foreach (var oob in stream.PendingOobs) { oobs[oob.Id] = oob; } var domainEvents = events.Where(x => x.Descriptor.StreamType == StreamTypes.Domain); var oobEvents = events.Where(x => x.Descriptor.StreamType == StreamTypes.OOB); if (domainEvents.Any()) { _cache.Evict(streamName); Logger.Write(LogLevel.Debug, () => $"Event stream [{stream.StreamId}] in bucket [{stream.Bucket}] committing {domainEvents.Count()} events"); await _store.WriteEvents(streamName, domainEvents, commitHeaders, expectedVersion : stream.CommitVersion) .ConfigureAwait(false); } if (stream.PendingOobs.Any()) { await _store.WriteMetadata(streamName, custom : new Dictionary <string, string> { [OobMetadataKey] = JsonConvert.SerializeObject(oobs.Values) }).ConfigureAwait(false); } if (stream.PendingSnapshot != null) { Logger.Write(LogLevel.Debug, () => $"Event stream [{stream.StreamId}] in bucket [{stream.Bucket}] committing snapshot"); await _snapstore.WriteSnapshots <T>(stream.Bucket, stream.StreamId, stream.Parents, stream.StreamVersion, stream.PendingSnapshot, commitHeaders).ConfigureAwait(false); } if (oobEvents.Any()) { Logger.Write(LogLevel.Debug, () => $"Event stream [{stream.StreamId}] in bucket [{stream.Bucket}] publishing {oobEvents.Count()} out of band events"); foreach (var group in oobEvents.GroupBy(x => x.Descriptor.Headers[Defaults.OobHeaderKey])) { // OOB events of the same stream name don't need to all be written to the same stream // if we parallelize the events into 10 known streams we can take advantage of internal // ES optimizations and ES sharding var vary = _random.Next(10) + 1; var oobstream = $"{streamName}-{group.Key}.{vary}"; var definition = oobs[group.Key]; if (definition.Transient ?? false) { await _publisher.Publish <T>(oobstream, group, commitHeaders).ConfigureAwait(false); } else if (definition.DaysToLive.HasValue) { var version = await _store.WriteEvents(oobstream, group, commitHeaders).ConfigureAwait(false); // if new stream, write metadata if (version == (group.Count() - 1)) { await _store.WriteMetadata(oobstream, maxAge : TimeSpan.FromDays(definition.DaysToLive.Value)).ConfigureAwait(false); } } else { await _store.WriteEvents(oobstream, group, commitHeaders).ConfigureAwait(false); } } } }
public Task <long> WriteEvents(string stream, IFullEvent[] events, IDictionary <string, string> commitHeaders, long?expectedVersion = null) { var mutators = MutationManager.Registered.ToList(); var translatedEvents = events.Select(e => { IMutating mutated = new Mutating(e.Event, e.Descriptor.Headers ?? new Dictionary <string, string>()); // use async local container first if one exists // (is set by unit of work - it creates a child container which mutators might need) IContainer container = Configuration.Settings.LocalContainer.Value; if (container == null) { container = Configuration.Settings.Container; } foreach (var type in mutators) { var mutator = (IMutate)container.TryResolve(type); if (mutator == null) { Logger.WarnEvent("MutateFailure", "Failed to construct mutator {Mutator}", type.FullName); continue; } mutated = mutator.MutateOutgoing(mutated); } var mappedType = e.Event.GetType(); if (!mappedType.IsInterface) { mappedType = _mapper.GetMappedTypeFor(mappedType) ?? mappedType; } var descriptor = new EventDescriptor { EventId = e.EventId ?? Guid.NewGuid(), CommitHeaders = (commitHeaders ?? new Dictionary <string, string>()).Merge(new Dictionary <string, string> { [Defaults.InstanceHeader] = Defaults.Instance.ToString(), [Defaults.EndpointHeader] = Configuration.Settings.Endpoint, [Defaults.EndpointVersionHeader] = Configuration.Settings.EndpointVersion.ToString(), [Defaults.AggregatesVersionHeader] = Configuration.Settings.AggregatesVersion.ToString(), [Defaults.MachineHeader] = Environment.MachineName, }), Compressed = _compress.HasFlag(Compression.Events), EntityType = e.Descriptor.EntityType, StreamType = e.Descriptor.StreamType, Bucket = e.Descriptor.Bucket, StreamId = e.Descriptor.StreamId, Parents = e.Descriptor.Parents, Version = e.Descriptor.Version, Timestamp = e.Descriptor.Timestamp, Headers = e.Descriptor.Headers, }; var eventType = _registrar.GetVersionedName(mappedType); foreach (var header in mutated.Headers) { e.Descriptor.Headers[header.Key] = header.Value; } var @event = _serializer.Serialize(mutated.Message); if (_compress.HasFlag(Compression.Events)) { descriptor.Compressed = true; @event = @event.Compress(); } var metadata = _serializer.Serialize(descriptor); return(new EventData( descriptor.EventId, eventType, !descriptor.Compressed, @event, metadata )); }).ToArray(); return(DoWrite(stream, translatedEvents, expectedVersion)); }