Line data Source code
1 : #region Copyright
2 : // // -----------------------------------------------------------------------
3 : // // <copyright company="Chinchilla Software Limited">
4 : // // Copyright Chinchilla Software Limited. All rights reserved.
5 : // // </copyright>
6 : // // -----------------------------------------------------------------------
7 : #endregion
8 :
9 : using System;
10 : using System.Collections.Generic;
11 : using System.Linq;
12 : using cdmdotnet.Logging;
13 : using Cqrs.Domain;
14 : using Cqrs.Messages;
15 :
16 : namespace Cqrs.Events
17 : {
18 : /// <summary>
19 : /// Stores instances of <see cref="IEvent{TAuthenticationToken}"/> for replay, <see cref="IAggregateRoot{TAuthenticationToken}"/> and <see cref="ISaga{TAuthenticationToken}"/> rehydration.
20 : /// </summary>
21 : /// <typeparam name="TAuthenticationToken">The <see cref="Type"/> of the authentication token.</typeparam>
22 : public abstract class EventStore<TAuthenticationToken> : IEventStore<TAuthenticationToken>
23 1 : {
24 : /// <summary>
25 : /// The pattern used to generate the stream name.
26 : /// </summary>
27 : protected const string CqrsEventStoreStreamNamePattern = "{0}/{1}";
28 :
29 : /// <summary>
30 : /// The <see cref="IEventBuilder{TAuthenticationToken}"/> used to build events.
31 : /// </summary>
32 : protected IEventBuilder<TAuthenticationToken> EventBuilder { get; set; }
33 :
34 : /// <summary>
35 : /// The <see cref="IEventDeserialiser{TAuthenticationToken}"/> used to deserialise events.
36 : /// </summary>
37 : protected IEventDeserialiser<TAuthenticationToken> EventDeserialiser { get; set; }
38 :
39 : /// <summary>
40 : /// The <see cref="ITelemetryHelper"/> to use.
41 : /// </summary>
42 : protected ITelemetryHelper TelemetryHelper { get; set; }
43 :
44 : /// <summary>
45 : /// The <see cref="ILogger"/> to use.
46 : /// </summary>
47 : protected ILogger Logger { get; private set; }
48 :
49 : /// <summary>
50 : /// Instantiates a new instance of <see cref="EventStore{TAuthenticationToken}"/>.
51 : /// </summary>
52 1 : protected EventStore(IEventBuilder<TAuthenticationToken> eventBuilder, IEventDeserialiser<TAuthenticationToken> eventDeserialiser, ILogger logger)
53 : {
54 : EventBuilder = eventBuilder;
55 : EventDeserialiser = eventDeserialiser;
56 : Logger = logger;
57 : TelemetryHelper = new NullTelemetryHelper();
58 : }
59 :
60 : /// <summary>
61 : /// Saves the provided <paramref name="event"/>.
62 : /// </summary>
63 : /// <typeparam name="T">The <see cref="Type"/> of the <see cref="IAggregateRoot{TAuthenticationToken}"/> the <see cref="IEvent{TAuthenticationToken}"/> was raised in.</typeparam>
64 : /// <param name="event">The <see cref="IEvent{TAuthenticationToken}"/> to be saved.</param>
65 1 : public virtual void Save<T>(IEvent<TAuthenticationToken> @event)
66 : {
67 : Save(typeof(T), @event);
68 : }
69 :
70 : /// <summary>
71 : /// Generate a unique stream name based on the provided <paramref name="aggregateRootType"/> and the <see cref="IEvent{TAuthenticationToken}.Id"/> from the provided <paramref name="event"/>.
72 : /// </summary>
73 : /// <param name="aggregateRootType">The <see cref="Type"/> of the <see cref="IAggregateRoot{TAuthenticationToken}"/>.</param>
74 : /// <param name="event">The <see cref="IEvent{TAuthenticationToken}"/> to extract information from.</param>
75 1 : protected virtual string GenerateStreamName(Type aggregateRootType, IEvent<TAuthenticationToken> @event)
76 : {
77 : return GenerateStreamName(aggregateRootType, @event.Id);
78 : }
79 :
80 : /// <summary>
81 : /// Generate a unique stream name based on the provided <paramref name="aggregateRootType"/> and the <paramref name="aggregateId"/>.
82 : /// </summary>
83 : /// <param name="aggregateRootType">The <see cref="Type"/> of the <see cref="IAggregateRoot{TAuthenticationToken}"/>.</param>
84 : /// <param name="aggregateId">The ID of the <see cref="IAggregateRoot{TAuthenticationToken}"/>.</param>
85 1 : protected virtual string GenerateStreamName(Type aggregateRootType, Guid aggregateId)
86 : {
87 : return string.Format(CqrsEventStoreStreamNamePattern, aggregateRootType.FullName, aggregateId);
88 : }
89 :
90 : /// <summary>
91 : /// Saves the provided <paramref name="event"/>.
92 : /// </summary>
93 : /// <param name="aggregateRootType"> <see cref="Type"/> of the <see cref="IAggregateRoot{TAuthenticationToken}"/> the <see cref="IEvent{TAuthenticationToken}"/> was raised in.</param>
94 : /// <param name="event">The <see cref="IEvent{TAuthenticationToken}"/> to be saved.</param>
95 1 : public virtual void Save(Type aggregateRootType, IEvent<TAuthenticationToken> @event)
96 : {
97 : Logger.LogDebug(string.Format("Saving aggregate root event type '{0}'", @event.GetType().FullName), string.Format("{0}\\Save", GetType().Name));
98 : EventData eventData = EventBuilder.CreateFrameworkEvent(@event);
99 : string streamName = GenerateStreamName(aggregateRootType, @event);
100 : eventData.AggregateId = streamName;
101 : eventData.AggregateRsn = @event.Id;
102 : eventData.Version = @event.Version;
103 : eventData.CorrelationId = @event.CorrelationId;
104 : PersistEvent(eventData);
105 : Logger.LogInfo(string.Format("Saving aggregate root event type '{0}'... done", @event.GetType().FullName), string.Format("{0}\\Save", GetType().Name));
106 : TelemetryHelper.TrackMetric(string.Format("Cqrs/EventStore/Save/{0}", streamName), 1);
107 : }
108 :
109 : /// <summary>
110 : /// Gets a collection of <see cref="IEvent{TAuthenticationToken}"/> for the <typeparamref name="T">aggregate root</typeparamref> with the ID matching the provided <paramref name="aggregateId"/>.
111 : /// </summary>
112 : /// <typeparam name="T">The <see cref="Type"/> of the <see cref="IAggregateRoot{TAuthenticationToken}"/> the <see cref="IEvent{TAuthenticationToken}"/> was raised in.</typeparam>
113 : /// <param name="aggregateId">The <see cref="IAggregateRoot{TAuthenticationToken}.Id"/> of the <see cref="IAggregateRoot{TAuthenticationToken}"/>.</param>
114 : /// <param name="useLastEventOnly">Loads only the last event<see cref="IEvent{TAuthenticationToken}"/>.</param>
115 : /// <param name="fromVersion">Load events starting from this version</param>
116 1 : public virtual IEnumerable<IEvent<TAuthenticationToken>> Get<T>(Guid aggregateId, bool useLastEventOnly = false, int fromVersion = -1)
117 : {
118 : IEnumerable<IEvent<TAuthenticationToken>> results = Get(typeof (T), aggregateId, useLastEventOnly, fromVersion).ToList();
119 : TelemetryHelper.TrackMetric(string.Format("Cqrs/EventStore/Get/{0}", GenerateStreamName(typeof(T), aggregateId)), results.Count());
120 :
121 : return results;
122 : }
123 :
124 : /// <summary>
125 : /// Gets a collection of <see cref="IEvent{TAuthenticationToken}"/> for the <see cref="IAggregateRoot{TAuthenticationToken}"/> of type <paramref name="aggregateRootType"/> with the ID matching the provided <paramref name="aggregateId"/>.
126 : /// </summary>
127 : /// <param name="aggregateRootType"> <see cref="Type"/> of the <see cref="IAggregateRoot{TAuthenticationToken}"/> the <see cref="IEvent{TAuthenticationToken}"/> was raised in.</param>
128 : /// <param name="aggregateId">The <see cref="IAggregateRoot{TAuthenticationToken}.Id"/> of the <see cref="IAggregateRoot{TAuthenticationToken}"/>.</param>
129 : /// <param name="useLastEventOnly">Loads only the last event<see cref="IEvent{TAuthenticationToken}"/>.</param>
130 : /// <param name="fromVersion">Load events starting from this version</param>
131 1 : public abstract IEnumerable<IEvent<TAuthenticationToken>> Get(Type aggregateRootType, Guid aggregateId, bool useLastEventOnly = false, int fromVersion = -1);
132 :
133 : /// <summary>
134 : /// Get all <see cref="IEvent{TAuthenticationToken}"/> instances for the given <paramref name="correlationId"/>.
135 : /// </summary>
136 : /// <param name="correlationId">The <see cref="IMessage.CorrelationId"/> of the <see cref="IEvent{TAuthenticationToken}"/> instances to retrieve.</param>
137 1 : public abstract IEnumerable<EventData> Get(Guid correlationId);
138 :
139 : /// <summary>
140 : /// Persist the provided <paramref name="eventData"/> into storage.
141 : /// </summary>
142 : /// <param name="eventData">The <see cref="EventData"/> to persist.</param>
143 1 : protected abstract void PersistEvent(EventData eventData);
144 : }
145 : }
|