public async Task <bool> AppendToStreamAsync(EventUserInfo eventUserInfo, string streamId, int expectedVersion, IEnumerable <IEvent> events) { var lockObject = new object(); lock (lockObject) { // Load stream and verify version hasn't been changed yet. var eventStream = LoadStreamAsync(streamId).GetAwaiter().GetResult(); if (eventStream.Version != expectedVersion) { return(false); } var wrappers = PrepareEvents(eventUserInfo, streamId, expectedVersion, events); var stream = _eventsContainer.ContainsKey(streamId) ? this._eventsContainer[streamId] : new List <string>(); foreach (var wrapper in wrappers) { stream.Add(JsonConvert.SerializeObject(wrapper)); } if (!_eventsContainer.ContainsKey(streamId)) { _eventsContainer.Add(streamId, stream); } else { _eventsContainer[streamId] = stream; } } return(true); }
private static string SerializeEvents(EventUserInfo eventUserInfo, string streamId, int expectedVersion, IEnumerable <IEvent> events) { if (string.IsNullOrEmpty(eventUserInfo.AuthServiceUserId)) { throw new Exception("UserInfo.Id must be set to a value."); } var items = events.Select(e => new EventWrapper { //Id = $"{streamId}:{++expectedVersion}:{e.GetType().Name}", // I'm changing Id because I think there is a flaw in using // stream:version:eventName // I had a problem where I found 2 items in the stream with the same version number. // After they got added I couldn't add more items because the version number was not // the expected number. It expected the version number to one more the the count of events, // but the count of events was already one more than the last event. The last 2 items on the stream // were like [Guid:12:RenamedFileType, Guid:12:ActivatedFileType]. // I think this is possible if 2 items hit the SP at the same time and both checked // the version number was ok, and then both added. By changing the name to not include the event, // I'm guaranteeing that each version of the event has a unique streamId, but that I would // duplicate and fail if 2 items with the same version try to get added at the same time. Id = $"{streamId}:{++expectedVersion}", StreamInfo = new StreamInfo { Id = streamId, Version = expectedVersion }, EventType = e.GetType().Name, EventData = JObject.FromObject(e), UserInfo = JObject.FromObject(eventUserInfo) }); return(JsonConvert.SerializeObject(items)); }
public async Task RegisterCustomerAndChangeLastName() { _testOutputHelper.WriteLine($"Registering new customer"); var eventUserId = "test|abcd123xx456efg"; var userInfo = new EventUserInfo(eventUserId); var id = Guid.NewGuid(); var firstName = $"First_{id}"; var lastName = $"Last_{id}"; var middleName = $"Middle_{id}"; var repo = GetOrderSystemRepository(); // things/events occur var customer = new Customer(id, firstName, lastName, middleName); string newLastName = lastName + "_changed"; customer.ChangeLastName(newLastName); var saved = await repo.SaveCustomer(userInfo, customer); var reloadedCustomer = await repo.LoadCustomer(id); Assert.Equal(id, reloadedCustomer.Id); Assert.Equal(firstName, reloadedCustomer.FirstName); Assert.Equal(newLastName, reloadedCustomer.LastName); Assert.Equal(middleName, reloadedCustomer.MiddleName); }
public PlaceOrder(EventUserInfo eventUserInfo, Guid id, string orderName, List <OrderItem> items) { EventUserInfo = eventUserInfo; Id = id; OrderName = orderName; Items = items; }
public async Task PlaceOrder() { _testOutputHelper.WriteLine($"PlacingOrder"); var userId = "test|abcd123xx456efg"; var userInfo = new EventUserInfo(userId); var id = Guid.NewGuid(); var orderName = "Joey"; var items = new List <OrderItem> { new OrderItem(DateTime.UtcNow, "Ham Sandwich", 12.00m), new OrderItem(DateTime.UtcNow, "Clam Chowder", 6.59m), new OrderItem(DateTime.UtcNow, "French Fries", 4.85m) }; var order = new Order(id, orderName, items); var repo = GetOrderSystemRepository(); var saved = await repo.SaveOrder(userInfo, order); var order2 = await repo.LoadOrder(id); Assert.Equal(id, order2.Id); Assert.Equal(orderName, order2.OrderName); Assert.Equal(items, order2.Items); Assert.Equal(3, order2.Items.Count); }
public async Task <bool> SaveCustomer(EventUserInfo eventUserInfo, Customer aggregate) { if (!aggregate.Changes.Any()) { return(true); } var streamId = aggregate.Id.ToString(); return(await _eventStore.AppendToStreamAsync(eventUserInfo, streamId, aggregate.Version, aggregate.Changes)); }
public async Task <bool> AppendToStreamAsync(EventUserInfo eventUserInfo, string streamId, int expectedVersion, IEnumerable <IEvent> events) { Container container = _client.GetContainer(_databaseId, _containerId); PartitionKey partitionKey = new PartitionKey(streamId); dynamic[] parameters = new dynamic[] { streamId, expectedVersion, SerializeEvents(eventUserInfo, streamId, expectedVersion, events) }; return(await container.Scripts.ExecuteStoredProcedureAsync <bool>("spAppendToStream", partitionKey, parameters)); }
public IActionResult UserDetails([FromForm] EventUserInfo UserInfo) { try { EventUserInfo user = new EventUserInfo(); user.UserName = UserInfo.UserName; user.Password = UserInfo.Password; user.Email_Id = UserInfo.Email_Id; _context.EventUserInfos.Add(user); _context.SaveChanges(); return(Ok(UserInfo)); } catch (Exception ex) { return(Problem(ex.GetType().Name + " : UserName Already Exists")); } }
public async Task <bool> SaveOrder(EventUserInfo eventUserInfo, Order aggregate, OrderSnapshot snapshot = null) { if (aggregate.Changes.Any()) { var streamId = aggregate.Id.ToString(); // save all events bool savedEvents = await _eventStore.AppendToStreamAsync(eventUserInfo, streamId, aggregate.Version, aggregate.Changes); // save snapshot if (savedEvents && snapshot != null && _snapshotStore != null) { await SaveOrderSnapshot(snapshot); } return(savedEvents); } return(true); }
public async Task PlaceOrderAndAddItem() { var userId = "test|abcd123xx456efg"; var userInfo = new EventUserInfo(userId); var id = Guid.NewGuid(); var orderName = "Joey"; var items = new List <OrderItem> { new OrderItem(DateTime.UtcNow, "Ham Sandwich", 12.00m), new OrderItem(DateTime.UtcNow, "Clam Chowder", 6.59m), new OrderItem(DateTime.UtcNow, "French Fries", 4.85m) }; var order = new Order(id, orderName, items); var repo = GetOrderSystemRepository(); // add another item: var addItem = new OrderItem(DateTime.UtcNow, "Fish Sandwich", 6.95m); order.AddItem(addItem); var saved = await repo.SaveOrder(userInfo, order); // update items so we can use it for comparison items.Add(addItem); var order2 = await repo.LoadOrder(id); Assert.Equal(id, order2.Id); Assert.Equal(orderName, order2.OrderName); Assert.Equal(items, order2.Items); Assert.Equal(4, order2.Items.Count); }
private static List <EventWrapper> PrepareEvents(EventUserInfo eventUserInfo, string streamId, int expectedVersion, IEnumerable <IEvent> events) { if (string.IsNullOrEmpty(eventUserInfo.AuthServiceUserId)) { throw new Exception("UserInfo.Id must be set to a value."); } var items = events.Select(e => new EventWrapper { // Id = $"{streamId}:{++expectedVersion}:{e.GetType().Name}", Id = $"{streamId}:{++expectedVersion}", //:{e.GetType().Name}", StreamInfo = new StreamInfo { Id = streamId, Version = expectedVersion }, EventType = e.GetType().Name, EventData = JObject.FromObject(e), UserInfo = JObject.FromObject(eventUserInfo) }); return(items.ToList()); }
public RemoveItemFromOrder(EventUserInfo eventUserInfo, Guid id, string name) { EventUserInfo = eventUserInfo; Id = id; Name = name; }
public AddItemToOrder(EventUserInfo eventUserInfo, Guid id, OrderItem item) { EventUserInfo = eventUserInfo; Id = id; Item = item; }