public void read_store_all_records() { var stream = Guid.NewGuid().ToString(); using (var store = new FileAppendOnlyStore(new DirectoryInfo(_storePath))) { store.Initialize(); var currentVersion = store.GetCurrentVersion(); for (int i = 0; i < 2; i++) { store.Append(stream, Encoding.UTF8.GetBytes("test message" + i)); } var records = store.ReadRecords(-1, Int32.MaxValue).ToArray(); Assert.AreEqual(currentVersion + 2, records.Length); for (var i = currentVersion; i < currentVersion + 2; i++) { Assert.AreEqual("test message" + (i - currentVersion), Encoding.UTF8.GetString(records[i].Data)); Assert.AreEqual(i - currentVersion + 1, records[i].StreamVersion); Assert.AreEqual(i + 1, records[i].StoreVersion); } } }
public void REGISTER_PROJECTIONS() { var appendStore = new FileAppendOnlyStore(@"C:\Users\wydev\Documents\GitHub\Clones\lokad-iddd-sample\DomainTests\Store\"); var eventStore = new EventStore(appendStore); var publisher = new DomainEventPublisher(eventStore, 0, 500); var store = new FileDocumentReaderWriter <CustomerId, CustomerTransactions>(@"C:\Users\wydev\Documents\GitHub\Clones\lokad-iddd-sample\DomainTests\Store\", new ViewStrategy(@"C:\Users\wydev\Documents\GitHub\Clones\lokad-iddd-sample\DomainTests\Views\")); IDocumentWriter <CustomerId, CustomerTransactions> writer = store; var projection = new CustomerTransactionsProjection(writer); publisher.RegisterProjection(projection); var id = new CustomerId(2); var @event = new CustomerCreated { Id = id, Name = "Microsoft", Currency = Currency.Eur }; IList <IEvent> Changes = new List <IEvent>(); Changes.Add(@event); eventStore.AppendToStream(id, 0, Changes); publisher.ProcessNewEvents(); }
public void REGISTER_PROJECTIONS() { var appendStore = new FileAppendOnlyStore( @"C:\Users\wydev\Documents\GitHub\Clones\lokad-iddd-sample\DomainTests\Store\"); var eventStore = new EventStore(appendStore); var publisher = new DomainEventPublisher(eventStore,0,500); var store = new FileDocumentReaderWriter<CustomerId,CustomerTransactions>(@"C:\Users\wydev\Documents\GitHub\Clones\lokad-iddd-sample\DomainTests\Store\", new ViewStrategy(@"C:\Users\wydev\Documents\GitHub\Clones\lokad-iddd-sample\DomainTests\Views\")); IDocumentWriter<CustomerId,CustomerTransactions> writer = store; var projection = new CustomerTransactionsProjection(writer); publisher.RegisterProjection(projection); var id = new CustomerId(2); var @event = new CustomerCreated { Id = id, Name = "Microsoft", Currency = Currency.Eur }; IList<IEvent> Changes = new List<IEvent>(); Changes.Add(@event); eventStore.AppendToStream(id,0,Changes); publisher.ProcessNewEvents(); }
static IAppendOnlyStore CreateFileStore() { var store = new FileAppendOnlyStore(Path.Combine(Directory.GetCurrentDirectory(), "store")); return(store); }
public static FileAppendOnlyStore CreateAppendOnlyStore(this FileStorageConfig cfg, string name) { var store = new FileAppendOnlyStore(new DirectoryInfo(Path.Combine(cfg.FullPath, name))); store.Initialize(); return(store); }
public void load_cache_when_incorrect_data_file() { var currentPath = Path.Combine(_storePath, "EmptyCache"); Directory.CreateDirectory(currentPath); var store = new FileAppendOnlyStore(new DirectoryInfo(currentPath)); //write frame using (var stream = new FileStream(Path.Combine(currentPath, "0.dat"), FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite)) StorageFramesEvil.WriteFrame("test-key", 0, Encoding.UTF8.GetBytes("test message"), stream); //write incorrect frame using (var sw = new StreamWriter(Path.Combine(currentPath, "1.dat"))) sw.Write("incorrect frame data"); store.LoadCaches(); var data = store.ReadRecords(0, Int32.MaxValue).ToArray(); Assert.AreEqual(1, data.Length); Assert.AreEqual("test-key", data[0].Key); Assert.AreEqual(0, data[0].StreamVersion); Assert.AreEqual("test message", Encoding.UTF8.GetString(data[0].Data)); Assert.IsTrue(File.Exists(Path.Combine(currentPath, "1.dat"))); }
public void get_current_version() { using (var store = new FileAppendOnlyStore(new DirectoryInfo(_storePath))) { store.Initialize(); var currentVersion = store.GetCurrentVersion(); store.Append("versiontest", Encoding.UTF8.GetBytes("test message1")); store.Append("versiontest", Encoding.UTF8.GetBytes("test message2")); store.Append("versiontest", Encoding.UTF8.GetBytes("test message3")); Assert.AreEqual(currentVersion + 3, store.GetCurrentVersion()); } }
public void append_data_when_set_version_where_does_not_correspond_real_version() { var key = Guid.NewGuid().ToString(); using (var store = new FileAppendOnlyStore(new DirectoryInfo(_storePath))) { store.Initialize(); store.Append(key, Encoding.UTF8.GetBytes("test message1"), 100); var data = store.ReadRecords(key, -1, 2).ToArray(); CollectionAssert.IsEmpty(data); } }
public void SetUp() { _serializer = new TestMessageSerializer(new[] { typeof(TestEvent) }); _path = Path.Combine(Path.GetTempPath(), "MessageStore", Guid.NewGuid().ToString()); if (!Directory.Exists(_path)) { Directory.CreateDirectory(_path); } _appendOnlyStore = new FileAppendOnlyStore(new DirectoryInfo(_path)); _appendOnlyStore.Initialize(); _messageStore = new MessageStore(_appendOnlyStore, _serializer); }
static IAppendOnlyStore CreateFileStoreForTesting() { var combine = Path.Combine(Directory.GetCurrentDirectory(), "store"); if (Directory.Exists(combine)) { Console.WriteLine(); Console.WriteLine("Wiping file event store for demo purposes."); Console.WriteLine("You can switch to Azure or SQL event stores by modifying Program.cs"); Console.WriteLine(); Directory.Delete(combine, true); } var store = new FileAppendOnlyStore(combine); store.Initialize(); return store; }
static IAppendOnlyStore CreateFileStoreForTesting() { var combine = Path.Combine(Directory.GetCurrentDirectory(), "store"); if (Directory.Exists(combine)) { Console.WriteLine(); Console.WriteLine("Wiping file event store for demo purposes."); Console.WriteLine("You can switch to Azure or SQL event stores by modifying Program.cs"); Console.WriteLine(); Directory.Delete(combine, true); } var store = new FileAppendOnlyStore(combine); store.Initialize(); return(store); }
public void SetUp() { _storeRecords = new List <StoreRecord>(); this._serializer = new TestMessageSerializer(new[] { typeof(SerializerTest1), typeof(SerializerTest2), typeof(string) }); this._path = Path.Combine(Path.GetTempPath(), "MessageStorePublisher", Guid.NewGuid().ToString()); this._appendOnlyStore = new FileAppendOnlyStore(new DirectoryInfo(this._path)); this._appendOnlyStore.Initialize(); this._store = new MessageStore(this._appendOnlyStore, this._serializer); var streamer = new EnvelopeStreamer(this._serializer); var queueWriter = new TestQueueWriter(); this._sender = new MessageSender(streamer, queueWriter); var store = new FileDocumentStore(Path.Combine(this._path, "lokad-cqrs-test"), new DocumentStrategy()); this._nuclearStorage = new NuclearStorage(store); this._publisher = new MessageStorePublisher("test-tape", this._store, this._sender, this._nuclearStorage, DoWePublishThisRecord); }
public static ConsoleEnvironment Build() { var handler = new SynchronousEventHandler(); var inbox = new InboxProjection(); handler.RegisterHandler(inbox); //var store = new InMemoryStore(handler); var store = new FileAppendOnlyStore(new DirectoryInfo(Directory.GetCurrentDirectory())); store.Initialize(); var messageStore = new MessageStore(store); messageStore.LoadDataContractsFromAssemblyOf(typeof(ActionDefined)); var currentVersion = store.GetCurrentVersion(); var log = LogManager.GetLoggerFor<ConsoleEnvironment>(); log.Debug("Event Store ver {0}", currentVersion); if (currentVersion > 0) { log.Debug("Running in-memory replay"); foreach (var record in messageStore.EnumerateAllItems(0, int.MaxValue)) { foreach (var item in record.Items.OfType<Event>()) { handler.Handle(item); } } log.Debug("Replay complete"); } var events = new EventStore(messageStore,handler); var tenant = new TenantAppService(events, new RealTimeProvider()); var build = new ConsoleEnvironment { Store = events, Tenant = tenant, Commands = ConsoleCommands.Actions, Id = new TenantId(1), Inbox = inbox }; return build; }
public void load_cache() { CreateCacheFiles(); using (var store = new FileAppendOnlyStore(new DirectoryInfo(_storePath))) { store.LoadCaches(); for (int j = 0; j < DataFileCount; j++) { var key = "test-key" + j; var data = store.ReadRecords(key, -1, Int32.MaxValue); int i = 0; foreach (var dataWithKey in data) { Assert.AreEqual("test messages" + i, Encoding.UTF8.GetString(dataWithKey.Data)); i++; } Assert.AreEqual(FileMessagesCount, i); } } }
public void append_data() { using (var store = new FileAppendOnlyStore(new DirectoryInfo(_storePath))) { store.Initialize(); var currentVersion = store.GetCurrentVersion(); const int messagesCount = 3; for (int i = 0; i < messagesCount; i++) { store.Append("stream1", Encoding.UTF8.GetBytes("test message" + i)); } var data = store.ReadRecords("stream1", currentVersion, Int32.MaxValue).ToArray(); for (int i = 0; i < messagesCount; i++) { Assert.AreEqual("test message" + i, Encoding.UTF8.GetString(data[i].Data)); } Assert.AreEqual(messagesCount, data.Length); } }
public void SetUp() { _serializer = new TestMessageSerializer(new[] { typeof(SerializerTest1), typeof(SerializerTest2), typeof(string) }); _path = Path.Combine(Path.GetTempPath(), "MessageStore", Guid.NewGuid().ToString()); if (!Directory.Exists(_path)) { Directory.CreateDirectory(_path); } _appendOnlyStore = new FileAppendOnlyStore(new DirectoryInfo(_path)); var store = new MessageStore(_appendOnlyStore, _serializer); store.AppendToStore("stream1", MessageAttribute.Empty, -1, new[] { new SerializerTest1("msg1") }); store.AppendToStore("stream2", MessageAttribute.Empty, -1, new[] { new SerializerTest1("msg1"), new SerializerTest1("msg2") }); store.AppendToStore("stream3", MessageAttribute.Empty, -1, new[] { new SerializerTest1("msg1"), new SerializerTest1("msg2"), new SerializerTest1("msg3") }); store.RecordMessage("stream4", new ImmutableEnvelope("EnvId", DateTime.UtcNow, new SerializerTest1("msg1"), MessageAttribute.Empty)); _appendOnlyStore.Close(); _appendOnlyStore = new FileAppendOnlyStore(new DirectoryInfo(_path)); _appendOnlyStore.Initialize(); _store = new MessageStore(_appendOnlyStore, _serializer); }
public void Setup() { _store = new FileAppendOnlyStore(new DirectoryInfo(_storePath)); }
static void Main() { // this Client App uses a standard "Windows Forms" application as its host Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); #region This WinForms host uses its own in-memory message bus to manage the UI... // It uses this in-memory bus to wire user-interface "UI" elements ("controls") to the // logic (in controllers) that will be triggered when the user interacts with those elements. // This allows us to send messages to the uiBus so that interested UI classes can // subscribe to the messages they care about, and react to them // when the bus publishes the messages to tell the UI controls what happened. #endregion var uiBus = new InMemoryBus("UI"); // .dat file to write Domain Events to this session var fileToStoreEventsIn = new FileAppendOnlyStore(new DirectoryInfo(Directory.GetCurrentDirectory())); fileToStoreEventsIn.Initialize(); // provide serialization stuff for our file storage var messageStore = new MessageStore(fileToStoreEventsIn); messageStore.LoadDataContractsFromAssemblyOf(typeof(ActionDefined)); // this WinForm App's own local file-based event storage var appEventStore = new AppEventStore(messageStore); #region Does App care about this msg? This class controls the App's "main message loop"... // It reads all msgs from in-memory queue (mainQueue below) and determines which messages // the App will/will not handle at a given time (based on specific app state). // For each queued message that it determines should be handled by // uiBus subscribers, it passes the messages through to our in-memory uiBus, // so bus subscribers can be called to react to the current message when the bus publishes it. #endregion var appController = new AppController(uiBus, appEventStore); #region In-memory structure that all events we defined will go through... // All domain & system messages we defined are captured // and accumulated in this queue until some code picks up // each message and processes it. // (ex: AppController, declared above, will do that processing in this case). #endregion var mainQueue = new QueuedHandler(appController, "Main Queue"); appController.SetMainQueue(mainQueue); appEventStore.SetDispatcher(mainQueue); var provider = new ClientPerspective(); ClientModelController.WireTo(appEventStore, provider, uiBus, mainQueue); // create services and bind them to the bus // we wire all controls together in a native way. // then we add adapters on top of that var form = new MainForm(); var navigation = new NavigationView(); form.NavigationRegion.RegisterDock(navigation, "nav"); form.NavigationRegion.SwitchTo("nav"); LogController.Wire(form, uiBus); #region View Controllers - Decoupling (UI) Views from their Controllers... // The intent with this design was to enable us to // write components or UI elements in a separated manner. // Provide the ability to develop new functionality independently and // it will sit in its own kind of "sandbox" so you can work on your stuff // without impacting everyone else. // It also sets us up for potential controller/code reuse and sharing in the future. // The UI is broken down into kinda "SEDA standalone controllers" // that communicate with each other via events. This event-driven // separation allows for cleanly implementing logic like: // "If the Inbox is selected, then only display these two menu items, // but if a project is displayed, then display these additional menu items." // See the Handle methods inside of MainFormController.cs for an example. // Event-centric approaches are one of the nicest ways to build // plug-in systems because plug-ins have services and contracts which are linked // to behaviors (and in our case, these are events). // Example: All CaptureThoughtController knows is that it gets handed a View // that it controls (CaptureThoughtForm) and then it has two other injections points, // a Bus and a MainQueue. // See CaptureThoughtController for more comments on how this design works. // The big idea here is that in the future, a controller can be passed an // INTERFACE (say, ICaptureThoughtForm) INSTEAD OF a concrete Windows Forms // implementation (CaptureThoughtForm) like it currently uses. // So we may have a WPF form in the future that implements ICaptureThoughtForm // and we could use that View implementation with the SAME CONTROLLER we already have. // Very similar to how you could use the MVVM pattern with MvvmCross to // reuse common code from the ViewModel down, but implement // platform-specific Views on top of that common/shared code. #endregion #region Wiring up our Views to Controllers... // A "Controller" or "Service" in this client-side ecosystem would usually // define at least two parameters: // MainQueue // and // "Bus" // MainQueue is the place where it would send events that happen inside of it. // Bus is what it subscribes to so that it will be called when specifc events happen. // "Wire" is a static method defined on these controllers that our setup // can call to let them know which form they control, // the bus they can use as a source to subscribe to UI events to react to, // and the target queue that they can use tell the rest of the world about events they generate. #endregion MainFormController.Wire(form, mainQueue, uiBus); AddStuffToInboxController.Wire(new AddStuffToInboxForm(form), uiBus, mainQueue); AddActionToProjectController.Wire(new AddActionToProjectForm(form),uiBus, mainQueue ); DefineProjectController.Wire(new DefineProjectForm(form), uiBus, mainQueue); InboxController.Wire(form.MainRegion, mainQueue, uiBus, provider); NavigationController.Wire(navigation, mainQueue, uiBus, provider); ProjectController.Wire(form.MainRegion, mainQueue, uiBus, provider); NavigateBackController.Wire(uiBus, mainQueue, form); mainQueue.Enqueue(new AppInit()); mainQueue.Start(); Application.Run(form); }
public static void WireControlLogic(UserInterface ui) { #region This WinForms host uses its own in-memory message bus to manage the UI... // It uses this in-memory bus to wire user-interface "UI" elements ("controls") to the // logic (in controllers) that will be triggered when the user interacts with those elements. // This allows us to send messages to the uiBus so that interested UI classes can // subscribe to the messages they care about, and react to them // when the bus publishes the messages to tell the UI controls what happened. #endregion var uiBus = new InMemoryBus("UI"); // .dat file to write Domain Events to this session var fileToStoreEventsIn = new FileAppendOnlyStore(new DirectoryInfo(Directory.GetCurrentDirectory())); fileToStoreEventsIn.Initialize(); // provide serialization stuff for our file storage var messageStore = new MessageStore(fileToStoreEventsIn); messageStore.LoadDataContractsFromAssemblyOf(typeof(ActionDefined)); // this WinForm App's own local file-based event storage var appEventStore = new AppEventStore(messageStore); #region Does App care about this msg? This class controls the App's "main message loop"... // It reads all msgs from in-memory queue (mainQueue below) and determines which messages // the App will/will not handle at a given time (based on specific app state). // For each queued message that it determines should be handled by // uiBus subscribers, it passes the messages through to our in-memory uiBus, // so bus subscribers can be called to react to the current message when the bus publishes it. #endregion var appController = new AppController(uiBus, appEventStore); #region In-memory structure that all events we defined will go through... // All domain & system messages we defined are captured // and accumulated in this queue until some code picks up // each message and processes it. // (ex: AppController, declared above, will do that processing in this case). #endregion var mainQueue = new QueuedHandler(appController, "Main Queue"); appController.SetMainQueue(mainQueue); appEventStore.SetDispatcher(mainQueue); var provider = new ClientPerspective(); ClientModelController.WireTo(appEventStore, provider, uiBus, mainQueue); // create services and bind them to the bus // we wire all controls together in a native way. // then we add adapters on top of that LogController.Wire(ui.Log, uiBus); #region View Controllers - Decoupling (UI) Views from their Controllers... // The intent with this design was to enable us to // write components or UI elements in a separated manner. // Provide the ability to develop new functionality independently and // it will sit in its own kind of "sandbox" so you can work on your stuff // without impacting everyone else. // It also sets us up for potential controller/code reuse and sharing in the future. // The UI is broken down into kinda "SEDA standalone controllers" // that communicate with each other via events. This event-driven // separation allows for cleanly implementing logic like: // "If the Inbox is selected, then only display these two menu items, // but if a project is displayed, then display these additional menu items." // See the Handle methods inside of MainFormController.cs for an example. // Event-centric approaches are one of the nicest ways to build // plug-in systems because plug-ins have services and contracts which are linked // to behaviors (and in our case, these are events). // Example: All CaptureThoughtController knows is that it gets handed a View // that it controls (CaptureThoughtForm) and then it has two other injections points, // a Bus and a MainQueue. // See CaptureThoughtController for more comments on how this design works. // The big idea here is that in the future, a controller can be passed an // INTERFACE (say, ICaptureThoughtForm) INSTEAD OF a concrete Windows Forms // implementation (CaptureThoughtForm) like it currently uses. // So we may have a WPF form in the future that implements ICaptureThoughtForm // and we could use that View implementation with the SAME CONTROLLER we already have. // Very similar to how you could use the MVVM pattern with MvvmCross to // reuse common code from the ViewModel down, but implement // platform-specific Views on top of that common/shared code. #endregion #region Wiring up our Views to Controllers... // A "Controller" or "Service" in this client-side ecosystem would usually // define at least two parameters: // MainQueue // and // "Bus" // MainQueue is the place where it would send events that happen inside of it. // Bus is what it subscribes to so that it will be called when specifc events happen. // "Wire" is a static method defined on these controllers that our setup // can call to let them know which form they control, // the bus they can use as a source to subscribe to UI events to react to, // and the target queue that they can use tell the rest of the world about events they generate. #endregion MainMenuController.Wire(ui.Menu, mainQueue, uiBus); AddStuffToInboxController.Wire(ui.AddStuffToInboxWizard, uiBus, mainQueue); AddActionToProjectController.Wire(ui.AddActionToProjectWizard, uiBus, mainQueue); DefineProjectController.Wire(ui.DefineProjectWizard, uiBus, mainQueue); InboxController.Wire(ui.InboxView, mainQueue, uiBus, provider); NavigationController.Wire(ui.Navigation, mainQueue, uiBus, provider); ProjectController.Wire(ui.ProjectView, mainQueue, uiBus, provider); NavigateBackController.Wire(uiBus, mainQueue, ui.BackView); mainQueue.Enqueue(new AppInit()); mainQueue.Start(); }