public async Task CanUnpublishFacts() { // There is a room published to the domain. long domainId = AddDomain(); long roomId = AddRoom(domainId); // Client 1 unpublishes the room. FactTreeMemento tree = new FactTreeMemento(0); tree.Add(new IdentifiedFactMemento( new FactID { key = 3333 }, CreateDomain())); tree.Add(new IdentifiedFactMemento( new FactID { key = 9879 }, CreateRoom(3333))); _service.Post(ClientGuid1, "domain", tree, new List<UnpublishMemento>() { new UnpublishMemento(new FactID { key = 9879 }, RoleRoomDomain) }); // Client 2 subscribes to the domain. FactTreeMemento pivots = new FactTreeMemento(0); pivots.Add(new IdentifiedFactMemento( new FactID { key = 2222 }, CreateDomain())); Dictionary<long, long> pivotIds = new Dictionary<long, long>() { { 2222, 0 } }; var result = await _service.GetManyAsync(ClientGuid2, "domain", pivots, pivotIds, 0); // The room is conspicuously absent. Assert.AreEqual(0, result.Tree.Facts.Count()); }
public void SkipsFactsToSourceClient() { FactTreeMemento postTree = new FactTreeMemento(0); postTree.Add(new IdentifiedFactMemento( new FactID { key = 3961 }, CreateDomain())); postTree.Add(new IdentifiedFactMemento( new FactID { key = 4979 }, CreateRoom(3961))); _service.Post(ClientGuid1, "domain", postTree, new List <UnpublishMemento>()); FactTreeMemento getTree = new FactTreeMemento(0); getTree.Add(new IdentifiedFactMemento( new FactID { key = 9898 }, CreateDomain())); Dictionary <long, long> pivotIds = new Dictionary <long, long>(); pivotIds[9898] = 0; var result = _service.GetManyAsync(ClientGuid1, "domain", getTree, pivotIds, 0).Result.Tree; Assert.AreEqual(0, result.Facts.Count()); }
public void CanPublishFacts() { FactTreeMemento postTree = new FactTreeMemento(0); postTree.Add(new IdentifiedFactMemento( new FactID { key = 3961 }, CreateDomain())); postTree.Add(new IdentifiedFactMemento( new FactID { key = 4979 }, CreateRoom(3961))); _service.Post(ClientGuid1, "domain", postTree, new List<UnpublishMemento>()); FactTreeMemento getTree = new FactTreeMemento(0); getTree.Add(new IdentifiedFactMemento( new FactID { key = 9898 }, CreateDomain())); Dictionary<long, long> pivotIds = new Dictionary<long, long>(); pivotIds[9898] = 0; var result = _service.GetManyAsync(ClientGuid2, "domain", getTree, pivotIds, 0).Result.Tree; Assert.AreEqual(2, result.Facts.Count()); IdentifiedFactMemento resultDomain = (IdentifiedFactMemento)result.Facts.ElementAt(0); IdentifiedFactMemento resultRoom = (IdentifiedFactMemento)result.Facts.ElementAt(1); Assert.AreEqual(TypeDomain, resultDomain.Memento.FactType); Assert.IsFalse(resultDomain.Memento.Predecessors.Any()); Assert.AreEqual(TypeRoom, resultRoom.Memento.FactType); Assert.AreEqual(resultDomain.Id, resultRoom.Memento.Predecessors.ElementAt(0).ID); }
public void CanGetPublishedFact() { long domainId = AddDomain(); long roomId = AddRoom(domainId); FactTreeMemento tree = new FactTreeMemento(0); tree.Add(new IdentifiedFactMemento( new FactID { key = 4124 }, new FactMemento(TypeDomain))); Dictionary <long, long> pivotIds = new Dictionary <long, long>(); pivotIds.Add(4124, 0); var result = _service.GetManyAsync(ClientGuid1, "domain", tree, pivotIds, 0).Result.Tree; Assert.AreEqual(2, result.Facts.Count()); IdentifiedFactMemento resultDomain = (IdentifiedFactMemento)result.Facts.ElementAt(0); IdentifiedFactMemento resultRoom = (IdentifiedFactMemento)result.Facts.ElementAt(1); Assert.AreEqual(TypeDomain, resultDomain.Memento.FactType); Assert.IsFalse(resultDomain.Memento.Predecessors.Any()); Assert.AreEqual(TypeRoom, resultRoom.Memento.FactType); Assert.AreEqual(resultDomain.Id, resultRoom.Memento.Predecessors.ElementAt(0).ID); Assert.AreEqual(roomId, pivotIds[4124]); }
public Task<GetManyResult> GetManyAsync( Guid clientGuid, string domain, FactTreeMemento tree, Dictionary<long, long> pivotIds, int timeoutSeconds) { GetManyResult result = GetManyInternal(clientGuid, domain, tree, pivotIds); if (timeoutSeconds > 0 && !result.Tree.Facts.Any()) { CancellationTokenSource cancellation = new CancellationTokenSource(); int session = _messageBus.Register( domain, result.LocalPivotIds, clientGuid, () => cancellation.Cancel()); return Task .Delay(timeoutSeconds * 1000, cancellation.Token) .ContinueWith(t => t.IsCanceled ? GetManyInternal(clientGuid, domain, tree, pivotIds) : result) .ContinueWith(t => { _messageBus.Unregister(session); cancellation.Dispose(); return t.Result; }); } return Task.FromResult(result); }
public Task <GetManyResult> GetManyAsync( Guid clientGuid, string domain, FactTreeMemento tree, Dictionary <long, long> pivotIds, int timeoutSeconds) { GetManyResult result = GetManyInternal(clientGuid, domain, tree, pivotIds); if (timeoutSeconds > 0 && !result.Tree.Facts.Any()) { CancellationTokenSource cancellation = new CancellationTokenSource(); int session = _messageBus.Register( domain, result.LocalPivotIds, clientGuid, () => cancellation.Cancel()); return(Task .Delay(timeoutSeconds * 1000, cancellation.Token) .ContinueWith(t => t.IsCanceled ? GetManyInternal(clientGuid, domain, tree, pivotIds) : result) .ContinueWith(t => { _messageBus.Unregister(session); cancellation.Dispose(); return t.Result; })); } return(Task.FromResult(result)); }
private static Dictionary <FactID, FactID> ForEachFact(FactTreeMemento tree, Func <FactMemento, FactID?> processFact) { Dictionary <FactID, FactID> localIdByRemoteId = new Dictionary <FactID, FactID>(); foreach (IdentifiedFactBase identifiedFact in tree.Facts) { if (identifiedFact is IdentifiedFactMemento) { FactMemento translatedMemento = TranslateMemento(localIdByRemoteId, (IdentifiedFactMemento)identifiedFact); if (translatedMemento != null) { FactID?localId = processFact(translatedMemento); if (localId != null) { localIdByRemoteId.Add(identifiedFact.Id, localId.Value); } } } else if (identifiedFact is IdentifiedFactRemote) { localIdByRemoteId.Add(identifiedFact.Id, ((IdentifiedFactRemote)identifiedFact).RemoteId); } } return(localIdByRemoteId); }
public void SerlializeFactTree(FactTreeMemento factTreeMemento, BinaryWriter factWriter) { CollectFactTypesAndRoles(factTreeMemento); BinaryHelper.WriteLong(factTreeMemento.DatabaseId, factWriter); BinaryHelper.WriteShort((short)_factTypes.Count, factWriter); foreach (var factType in _factTypes) { BinaryHelper.WriteString(factType.TypeName, factWriter); BinaryHelper.WriteInt(factType.Version, factWriter); } BinaryHelper.WriteShort((short)_roles.Count, factWriter); foreach (var role in _roles) { BinaryHelper.WriteShort(GetFactTypeId(role.DeclaringType), factWriter); BinaryHelper.WriteString(role.RoleName, factWriter); } short factCount = (short)factTreeMemento.Facts.Count(); BinaryHelper.WriteShort(factCount, factWriter); foreach (var fact in factTreeMemento.Facts) { if (fact is IdentifiedFactMemento) { SerializeIdentifiedFactMemento((IdentifiedFactMemento)fact, factWriter); } else { SerializeIdentifiedFactRemote((IdentifiedFactRemote)fact, factWriter); } } }
public void Notify( Guid clientGuid, string domain, FactTreeMemento pivotTree, long pivotId, string text1, string text2) { Dictionary <FactID, FactID> localIdByRemoteId = ForEachFact(pivotTree, fact => _repository.FindExistingFact(domain, fact)); FactID localPivotId; if (localIdByRemoteId.TryGetValue(new FactID { key = pivotId }, out localPivotId)) { var subscribers = _repository.LoadWindowsPhoneSubscriptions( new List <FactID> { localPivotId }, clientGuid); if (subscribers.Any()) { SendWindowsPhoneToastNotifications(subscribers, text1, text2); } } }
private async Task <GetManyResponse> GetManyAsync(GetManyRequest request) { var pivotIds = request.PivotIds .ToDictionary(p => p.FactId, p => p.TimestampId); var result = await _service.GetManyAsync( request.ClientGuid, request.Domain, request.PivotTree, pivotIds, request.TimeoutSeconds); FactTreeMemento factTree = result.Tree; return(new GetManyResponse { FactTree = factTree, PivotIds = pivotIds .Select(pair => new FactTimestamp { FactId = pair.Key, TimestampId = pair.Value }) .ToList() }); }
public void CanGetWithNoPivots() { FactTreeMemento tree = new FactTreeMemento(0); Dictionary<long, long> pivotIds = new Dictionary<long, long>(); var result = _service.GetManyAsync(Guid.Empty, "domain", tree, pivotIds, 0).Result.Tree; Assert.IsFalse(result.Facts.Any()); }
public FactTreeMemento DeserializeFactTree(BinaryReader factReader) { long databaseId = BinaryHelper.ReadLong(factReader); FactTreeMemento factTreeMemento = new FactTreeMemento(databaseId); short factTypeCount = BinaryHelper.ReadShort(factReader); if (factTypeCount > MaxFactTypeCount) throw new CorrespondenceException("Maximum number of fact types exceeded."); for (short i = 0; i < factTypeCount; i++) { string typeName = BinaryHelper.ReadString(factReader); int version = BinaryHelper.ReadInt(factReader); _factTypes.Add(new CorrespondenceFactType(typeName, version)); } short roleCount = BinaryHelper.ReadShort(factReader); if (roleCount > MaxRoleCount) throw new CorrespondenceException("Maximum number of roles exceeded."); for (short i = 0; i < roleCount; i++) { short factTypeId = BinaryHelper.ReadShort(factReader); string roleName = BinaryHelper.ReadString(factReader); _roles.Add(new RoleMemento(GetFactType(factTypeId), roleName, null, false)); } short factCount = BinaryHelper.ReadShort(factReader); if (factCount > MaxFactCount) throw new CorrespondenceException("Maximum number of facts exceeded."); for (short i = 0; i < factCount; i++) { factTreeMemento.Add(DeserlializeFact(factReader)); } return factTreeMemento; }
public void CanGetWithNoPivots() { FactTreeMemento tree = new FactTreeMemento(0); Dictionary <long, long> pivotIds = new Dictionary <long, long>(); var result = _service.GetManyAsync(Guid.Empty, "domain", tree, pivotIds, 0).Result.Tree; Assert.IsFalse(result.Facts.Any()); }
public void Post( Guid clientGuid, string domain, FactTreeMemento factTree, List <UnpublishMemento> unpublishMessages) { ForEachFact(factTree, fact => _repository.Save(domain, fact, clientGuid)); }
public void WindowsUnsubscribe( string domain, FactTreeMemento pivotTree, long pivotId, string deviceUri) { throw new NotImplementedException(); }
public void Notify( Guid clientGuid, string domain, FactTreeMemento pivotTree, long pivotId, string text1, string text2) { throw new NotImplementedException(); }
private byte[] GetRawPayload(FactTreeMemento factTree) { byte[] bytes = SerializeRawMessage(factTree); // If the message is too big, just send an empty tree. if (bytes.Length > RawNotificationSize) { bytes = SerializeRawMessage(new FactTreeMemento(factTree.DatabaseId)); } return bytes; }
private byte[] GetRawPayload(FactTreeMemento factTree) { byte[] bytes = SerializeRawMessage(factTree); // If the message is too big, just send an empty tree. if (bytes.Length > RawNotificationSize) { bytes = SerializeRawMessage(new FactTreeMemento(factTree.DatabaseId)); } return(bytes); }
private static FactTreeMemento CreateTreeWithSingleFact() { FactTreeMemento tree = new FactTreeMemento(0); tree.Add(new IdentifiedFactMemento( new FactID { key = 42 }, new FactMemento(new CorrespondenceFactType("TestModel.Domain", 1)))); return(tree); }
private void AddToFactTree(string domain, FactTreeMemento messageBody, FactID factId, Dictionary <FactID, FactID> localIdByRemoteId) { if (!messageBody.Contains(factId)) { FactMemento fact = _repository.Load(domain, factId); foreach (PredecessorMemento predecessor in fact.Predecessors) { AddToFactTree(domain, messageBody, predecessor.ID, localIdByRemoteId); } messageBody.Add(new IdentifiedFactMemento(factId, fact)); } }
public async Task<List<string>> SendPushNotifications(FactTreeMemento factTree, IEnumerable<string> subscriberDeviceUris) { var payload = GetRawPayload(factTree); var tasks = subscriberDeviceUris .Select(deviceUri => SendRawNotification(payload, deviceUri)); bool[] succeses = await Task.WhenAll(tasks); var failedDeviceUris = subscriberDeviceUris .Zip(succeses, (deviceUri, success) => new { deviceUri, success }) .Where(pair => !pair.success) .Select(pair => pair.deviceUri) .ToList(); return failedDeviceUris; }
public void Post( Guid clientGuid, string domain, FactTreeMemento factTree, List <UnpublishMemento> unpublishMessages) { Dictionary <FactID, FactID> localIdByRemoteId = ForEachFact(factTree, fact => _repository.Save(domain, fact, clientGuid)); var unpublishMementos = unpublishMessages .SelectMany(m => MapUnpublishMemento(localIdByRemoteId, m)) .ToList(); _repository.DeleteMessages(domain, unpublishMementos); }
private static byte[] SerializeRawMessage(FactTreeMemento factTree) { MemoryStream memory = new MemoryStream(); using (var factWriter = new BinaryWriter(memory)) { byte version = 1; BinaryHelper.WriteByte(version, factWriter); new FactTreeSerializer().SerlializeFactTree(factTree, factWriter); factWriter.Flush(); } var bytes = memory.ToArray(); return(bytes); }
private void CollectFactTypesAndRoles(FactTreeMemento factTreeMemento) { foreach (var fact in factTreeMemento.Facts) { if (fact is IdentifiedFactMemento) { AddFactType(((IdentifiedFactMemento)fact).Memento.FactType); foreach (var predecessor in ((IdentifiedFactMemento)fact).Memento.Predecessors) { AddFactType(predecessor.Role.DeclaringType); AddRole(predecessor.Role); } } } }
private void Repository_PivotAffected(string domain, FactID pivotId, FactID factId, Guid clientGuid) { _messageBus.Notify(domain, pivotId); var subscribers = _repository.LoadWindowsPhoneSubscriptions(new List <FactID> { pivotId }, clientGuid); if (subscribers.Any()) { var messageBody = new FactTreeMemento(0); AddToFactTree(domain, messageBody, factId, null); SendWindowsPhonePushNotifications(subscribers, messageBody); } }
private Task <GetManyResult> GetFromClient1() { FactTreeMemento tree = new FactTreeMemento(0); tree.Add(new IdentifiedFactMemento( new FactID { key = 4124 }, CreateDomain())); Dictionary <long, long> pivotIds = new Dictionary <long, long>(); pivotIds[4124] = 0; _service.Post(ClientGuid1, "domain", tree, new List <UnpublishMemento>()); return(_service.GetManyAsync(ClientGuid1, "domain", tree, pivotIds, 1)); }
private void PostFromClient2() { FactTreeMemento tree = new FactTreeMemento(0); tree.Add(new IdentifiedFactMemento( new FactID { key = 12 }, CreateDomain())); tree.Add(new IdentifiedFactMemento( new FactID { key = 13 }, CreateRoom(12))); _service.Post(ClientGuid2, "domain", tree, new List <UnpublishMemento>()); }
public async Task <List <string> > SendPushNotifications(FactTreeMemento factTree, IEnumerable <string> subscriberDeviceUris) { var payload = GetRawPayload(factTree); var tasks = subscriberDeviceUris .Select(deviceUri => SendRawNotification(payload, deviceUri)); bool[] succeses = await Task.WhenAll(tasks); var failedDeviceUris = subscriberDeviceUris .Zip(succeses, (deviceUri, success) => new { deviceUri, success }) .Where(pair => !pair.success) .Select(pair => pair.deviceUri) .ToList(); return(failedDeviceUris); }
private async void SendWindowsPhonePushNotifications( List <WindowsPhoneSubscription> subscribers, FactTreeMemento messageBody) { try { var devicesNotFound = await _windowsPhoneBroker.SendPushNotifications( messageBody, subscribers.Select(s => s.DeviceUri)); _repository.DeleteWindowsPhoneSubscriptionsByDeviceId(devicesNotFound); } catch (Exception x) { Trace.Fail(x.Message); } }
public async Task CanUnpublishFacts() { // There is a room published to the domain. long domainId = AddDomain(); long roomId = AddRoom(domainId); // Client 1 unpublishes the room. FactTreeMemento tree = new FactTreeMemento(0); tree.Add(new IdentifiedFactMemento( new FactID { key = 3333 }, CreateDomain())); tree.Add(new IdentifiedFactMemento( new FactID { key = 9879 }, CreateRoom(3333))); _service.Post(ClientGuid1, "domain", tree, new List <UnpublishMemento>() { new UnpublishMemento(new FactID { key = 9879 }, RoleRoomDomain) }); // Client 2 subscribes to the domain. FactTreeMemento pivots = new FactTreeMemento(0); pivots.Add(new IdentifiedFactMemento( new FactID { key = 2222 }, CreateDomain())); Dictionary <long, long> pivotIds = new Dictionary <long, long>() { { 2222, 0 } }; var result = await _service.GetManyAsync(ClientGuid2, "domain", pivots, pivotIds, 0); // The room is conspicuously absent. Assert.AreEqual(0, result.Tree.Facts.Count()); }
private GetManyResult GetManyInternal(Guid clientGuid, string domain, FactTreeMemento tree, Dictionary <long, long> pivotIds) { var localPivotIds = new List <FactID>(); FactTreeMemento messageBody = new FactTreeMemento(0); Dictionary <FactID, FactID> localIdByRemoteId = ForEachFact(tree, fact => _repository.Save(domain, fact, clientGuid)); Dictionary <long, long> newPivotIds = new Dictionary <long, long>(); foreach (var pivot in pivotIds) { long remotePivotId = pivot.Key; FactID localPivotId; long pivotValue = pivot.Value; TimestampID timestamp = new TimestampID(0, pivotValue); if (localIdByRemoteId.TryGetValue(new FactID { key = remotePivotId }, out localPivotId)) { List <FactID> recentMessages = _repository.LoadRecentMessages(domain, localPivotId, clientGuid, timestamp); foreach (FactID recentMessage in recentMessages) { AddToFactTree(domain, messageBody, recentMessage, localIdByRemoteId); if (recentMessage.key > pivotValue) { pivotValue = recentMessage.key; } } newPivotIds[remotePivotId] = pivotValue; localPivotIds.Add(localPivotId); } } foreach (var pivot in newPivotIds) { pivotIds[pivot.Key] = pivot.Value; } var result = new GetManyResult() { Tree = messageBody, PivotIds = pivotIds, LocalPivotIds = localPivotIds }; return(result); }
public FactTreeMemento DeserializeFactTree(BinaryReader factReader) { long databaseId = BinaryHelper.ReadLong(factReader); FactTreeMemento factTreeMemento = new FactTreeMemento(databaseId); short factTypeCount = BinaryHelper.ReadShort(factReader); if (factTypeCount > MaxFactTypeCount) { throw new CorrespondenceException("Maximum number of fact types exceeded."); } for (short i = 0; i < factTypeCount; i++) { string typeName = BinaryHelper.ReadString(factReader); int version = BinaryHelper.ReadInt(factReader); _factTypes.Add(new CorrespondenceFactType(typeName, version)); } short roleCount = BinaryHelper.ReadShort(factReader); if (roleCount > MaxRoleCount) { throw new CorrespondenceException("Maximum number of roles exceeded."); } for (short i = 0; i < roleCount; i++) { short factTypeId = BinaryHelper.ReadShort(factReader); string roleName = BinaryHelper.ReadString(factReader); _roles.Add(new RoleMemento(GetFactType(factTypeId), roleName, null, false)); } short factCount = BinaryHelper.ReadShort(factReader); if (factCount > MaxFactCount) { throw new CorrespondenceException("Maximum number of facts exceeded."); } for (short i = 0; i < factCount; i++) { factTreeMemento.Add(DeserlializeFact(factReader)); } return(factTreeMemento); }
private static FactTreeMemento CreateTreeWithMultipleFacts() { FactTreeMemento tree = CreateTreeWithSingleFact(); var game = new FactMemento( new CorrespondenceFactType("TestModel.Game", 1)) .AddPredecessor( CreateRoleDomain(), new FactID { key = 42 }, true); game.Data = new byte[] { 1, 2, 3, 4 }; tree.Add(new IdentifiedFactMemento( new FactID { key = 73 }, game)); return(tree); }
public void SkipsFactsAlreadyReceived() { long domainId = AddDomain(); long roomId = AddRoom(domainId); FactTreeMemento tree = new FactTreeMemento(0); tree.Add(new IdentifiedFactMemento( new FactID { key = 4124 }, CreateDomain())); Dictionary <long, long> pivotIds = new Dictionary <long, long>(); pivotIds.Add(4124, roomId); var result = _service.GetManyAsync(Guid.Empty, "domain", tree, pivotIds, 0).Result.Tree; Assert.AreEqual(0, result.Facts.Count()); }
public void WindowsPhoneUnsubscribe( string domain, FactTreeMemento factTree, long pivotId, string deviceUri) { Dictionary <FactID, FactID> localIdByRemoteId = ForEachFact(factTree, fact => _repository.FindExistingFact(domain, fact)); FactID localId; if (localIdByRemoteId.TryGetValue(new FactID { key = pivotId }, out localId)) { _repository.DeleteWindowsPhoneSubscriptions( new List <FactID> { localId }, deviceUri); } }
public void CanGetPublishedFact() { long domainId = AddDomain(); long roomId = AddRoom(domainId); FactTreeMemento tree = new FactTreeMemento(0); tree.Add(new IdentifiedFactMemento( new FactID { key = 4124 }, new FactMemento(TypeDomain))); Dictionary<long, long> pivotIds = new Dictionary<long, long>(); pivotIds.Add(4124, 0); var result = _service.GetManyAsync(ClientGuid1, "domain", tree, pivotIds, 0).Result.Tree; Assert.AreEqual(2, result.Facts.Count()); IdentifiedFactMemento resultDomain = (IdentifiedFactMemento)result.Facts.ElementAt(0); IdentifiedFactMemento resultRoom = (IdentifiedFactMemento)result.Facts.ElementAt(1); Assert.AreEqual(TypeDomain, resultDomain.Memento.FactType); Assert.IsFalse(resultDomain.Memento.Predecessors.Any()); Assert.AreEqual(TypeRoom, resultRoom.Memento.FactType); Assert.AreEqual(resultDomain.Id, resultRoom.Memento.Predecessors.ElementAt(0).ID); Assert.AreEqual(roomId, pivotIds[4124]); }
public void WindowsPhoneSubscribe( Guid clientGuid, string domain, FactTreeMemento factTree, long pivotId, string deviceUri) { Dictionary <FactID, FactID> localIdByRemoteId = ForEachFact(factTree, fact => _repository.Save(domain, fact, clientGuid)); FactID localId; if (localIdByRemoteId.TryGetValue(new FactID { key = pivotId }, out localId)) { _repository.SaveWindowsPhoneSubscription( new List <FactID> { localId }, deviceUri, clientGuid); } }
public void CanPublishFacts() { FactTreeMemento postTree = new FactTreeMemento(0); postTree.Add(new IdentifiedFactMemento( new FactID { key = 3961 }, CreateDomain())); postTree.Add(new IdentifiedFactMemento( new FactID { key = 4979 }, CreateRoom(3961))); _service.Post(ClientGuid1, "domain", postTree, new List <UnpublishMemento>()); FactTreeMemento getTree = new FactTreeMemento(0); getTree.Add(new IdentifiedFactMemento( new FactID { key = 9898 }, CreateDomain())); Dictionary <long, long> pivotIds = new Dictionary <long, long>(); pivotIds[9898] = 0; var result = _service.GetManyAsync(ClientGuid2, "domain", getTree, pivotIds, 0).Result.Tree; Assert.AreEqual(2, result.Facts.Count()); IdentifiedFactMemento resultDomain = (IdentifiedFactMemento)result.Facts.ElementAt(0); IdentifiedFactMemento resultRoom = (IdentifiedFactMemento)result.Facts.ElementAt(1); Assert.AreEqual(TypeDomain, resultDomain.Memento.FactType); Assert.IsFalse(resultDomain.Memento.Predecessors.Any()); Assert.AreEqual(TypeRoom, resultRoom.Memento.FactType); Assert.AreEqual(resultDomain.Id, resultRoom.Memento.Predecessors.ElementAt(0).ID); }
private GetManyResult GetManyInternal(Guid clientGuid, string domain, FactTreeMemento tree, Dictionary<long, long> pivotIds) { var localPivotIds = new List<FactID>(); FactTreeMemento messageBody = new FactTreeMemento(0); Dictionary<FactID, FactID> localIdByRemoteId = ForEachFact(tree, fact => _repository.Save(domain, fact, clientGuid)); Dictionary<long, long> newPivotIds = new Dictionary<long, long>(); foreach (var pivot in pivotIds) { long remotePivotId = pivot.Key; FactID localPivotId; long pivotValue = pivot.Value; TimestampID timestamp = new TimestampID(0, pivotValue); if (localIdByRemoteId.TryGetValue(new FactID { key = remotePivotId }, out localPivotId)) { List<FactID> recentMessages = _repository.LoadRecentMessages(domain, localPivotId, clientGuid, timestamp); foreach (FactID recentMessage in recentMessages) { AddToFactTree(domain, messageBody, recentMessage, localIdByRemoteId); if (recentMessage.key > pivotValue) pivotValue = recentMessage.key; } newPivotIds[remotePivotId] = pivotValue; localPivotIds.Add(localPivotId); } } foreach (var pivot in newPivotIds) pivotIds[pivot.Key] = pivot.Value; var result = new GetManyResult() { Tree = messageBody, PivotIds = pivotIds, LocalPivotIds = localPivotIds }; return result; }
private async void SendWindowsPhonePushNotifications( List<WindowsPhoneSubscription> subscribers, FactTreeMemento messageBody) { try { var devicesNotFound = await _windowsPhoneBroker.SendPushNotifications( messageBody, subscribers.Select(s => s.DeviceUri)); _repository.DeleteWindowsPhoneSubscriptionsByDeviceId(devicesNotFound); } catch (Exception x) { Trace.Fail(x.Message); } }
public void Notify( Guid clientGuid, string domain, FactTreeMemento pivotTree, long pivotId, string text1, string text2) { Dictionary<FactID, FactID> localIdByRemoteId = ForEachFact(pivotTree, fact => _repository.FindExistingFact(domain, fact)); FactID localPivotId; if (localIdByRemoteId.TryGetValue(new FactID { key = pivotId }, out localPivotId)) { var subscribers = _repository.LoadWindowsPhoneSubscriptions( new List<FactID> { localPivotId }, clientGuid); if (subscribers.Any()) { SendWindowsPhoneToastNotifications(subscribers, text1, text2); } } }
public void SkipsFactsAlreadyReceived() { long domainId = AddDomain(); long roomId = AddRoom(domainId); FactTreeMemento tree = new FactTreeMemento(0); tree.Add(new IdentifiedFactMemento( new FactID { key = 4124 }, CreateDomain())); Dictionary<long, long> pivotIds = new Dictionary<long, long>(); pivotIds.Add(4124, roomId); var result = _service.GetManyAsync(Guid.Empty, "domain", tree, pivotIds, 0).Result.Tree; Assert.AreEqual(0, result.Facts.Count()); }
public void Post( Guid clientGuid, string domain, FactTreeMemento factTree, List<UnpublishMemento> unpublishMessages) { Dictionary<FactID, FactID> localIdByRemoteId = ForEachFact(factTree, fact => _repository.Save(domain, fact, clientGuid)); var unpublishMementos = unpublishMessages .SelectMany(m => MapUnpublishMemento(localIdByRemoteId, m)) .ToList(); _repository.DeleteMessages(domain, unpublishMementos); }
private static Dictionary<FactID, FactID> ForEachFact(FactTreeMemento tree, Func<FactMemento, FactID?> processFact) { Dictionary<FactID, FactID> localIdByRemoteId = new Dictionary<FactID, FactID>(); foreach (IdentifiedFactBase identifiedFact in tree.Facts) { if (identifiedFact is IdentifiedFactMemento) { FactMemento translatedMemento = TranslateMemento(localIdByRemoteId, (IdentifiedFactMemento)identifiedFact); if (translatedMemento != null) { FactID? localId = processFact(translatedMemento); if (localId != null) { localIdByRemoteId.Add(identifiedFact.Id, localId.Value); } } } else if (identifiedFact is IdentifiedFactRemote) { localIdByRemoteId.Add(identifiedFact.Id, ((IdentifiedFactRemote)identifiedFact).RemoteId); } } return localIdByRemoteId; }
public void SerlializeFactTree(FactTreeMemento factTreeMemento, BinaryWriter factWriter) { CollectFactTypesAndRoles(factTreeMemento); BinaryHelper.WriteLong(factTreeMemento.DatabaseId, factWriter); BinaryHelper.WriteShort((short)_factTypes.Count, factWriter); foreach (var factType in _factTypes) { BinaryHelper.WriteString(factType.TypeName, factWriter); BinaryHelper.WriteInt(factType.Version, factWriter); } BinaryHelper.WriteShort((short)_roles.Count, factWriter); foreach (var role in _roles) { BinaryHelper.WriteShort(GetFactTypeId(role.DeclaringType), factWriter); BinaryHelper.WriteString(role.RoleName, factWriter); } short factCount = (short)factTreeMemento.Facts.Count(); BinaryHelper.WriteShort(factCount, factWriter); foreach (var fact in factTreeMemento.Facts) { if (fact is IdentifiedFactMemento) SerializeIdentifiedFactMemento((IdentifiedFactMemento)fact, factWriter); else SerializeIdentifiedFactRemote((IdentifiedFactRemote)fact, factWriter); } }
public void WindowsPhoneSubscribe( Guid clientGuid, string domain, FactTreeMemento factTree, long pivotId, string deviceUri) { Dictionary<FactID, FactID> localIdByRemoteId = ForEachFact(factTree, fact => _repository.Save(domain, fact, clientGuid)); FactID localId; if (localIdByRemoteId.TryGetValue(new FactID { key = pivotId }, out localId)) { _repository.SaveWindowsPhoneSubscription( new List<FactID> { localId }, deviceUri, clientGuid); } }
private void PostFromClient2() { FactTreeMemento tree = new FactTreeMemento(0); tree.Add(new IdentifiedFactMemento( new FactID { key = 12 }, CreateDomain())); tree.Add(new IdentifiedFactMemento( new FactID { key = 13 }, CreateRoom(12))); _service.Post(ClientGuid2, "domain", tree, new List<UnpublishMemento>()); }
private Task<GetManyResult> GetFromClient1() { FactTreeMemento tree = new FactTreeMemento(0); tree.Add(new IdentifiedFactMemento( new FactID { key = 4124 }, CreateDomain())); Dictionary<long, long> pivotIds = new Dictionary<long, long>(); pivotIds[4124] = 0; _service.Post(ClientGuid1, "domain", tree, new List<UnpublishMemento>()); return _service.GetManyAsync(ClientGuid1, "domain", tree, pivotIds, 1); }
private void AddToFactTree(string domain, FactTreeMemento messageBody, FactID factId, Dictionary<FactID, FactID> localIdByRemoteId) { if (!messageBody.Contains(factId)) { FactMemento fact = _repository.Load(domain, factId); foreach (PredecessorMemento predecessor in fact.Predecessors) AddToFactTree(domain, messageBody, predecessor.ID, localIdByRemoteId); messageBody.Add(new IdentifiedFactMemento(factId, fact)); } }
private static byte[] SerializeRawMessage(FactTreeMemento factTree) { MemoryStream memory = new MemoryStream(); using (var factWriter = new BinaryWriter(memory)) { byte version = 1; BinaryHelper.WriteByte(version, factWriter); new FactTreeSerializer().SerlializeFactTree(factTree, factWriter); factWriter.Flush(); } var bytes = memory.ToArray(); return bytes; }
public void SkipsFactsToSourceClient() { FactTreeMemento postTree = new FactTreeMemento(0); postTree.Add(new IdentifiedFactMemento( new FactID { key = 3961 }, CreateDomain())); postTree.Add(new IdentifiedFactMemento( new FactID { key = 4979 }, CreateRoom(3961))); _service.Post(ClientGuid1, "domain", postTree, new List<UnpublishMemento>()); FactTreeMemento getTree = new FactTreeMemento(0); getTree.Add(new IdentifiedFactMemento( new FactID { key = 9898 }, CreateDomain())); Dictionary<long, long> pivotIds = new Dictionary<long, long>(); pivotIds[9898] = 0; var result = _service.GetManyAsync(ClientGuid1, "domain", getTree, pivotIds, 0).Result.Tree; Assert.AreEqual(0, result.Facts.Count()); }
public void WindowsPhoneUnsubscribe( string domain, FactTreeMemento factTree, long pivotId, string deviceUri) { Dictionary<FactID, FactID> localIdByRemoteId = ForEachFact(factTree, fact => _repository.FindExistingFact(domain, fact)); FactID localId; if (localIdByRemoteId.TryGetValue(new FactID { key = pivotId }, out localId)) { _repository.DeleteWindowsPhoneSubscriptions( new List<FactID> { localId }, deviceUri); } }
public void ReadInternal(string domain, BinaryReader requestReader) { Domain = domain; PivotTree = new FactTreeSerializer().DeserializeFactTree(requestReader); PivotId = BinaryHelper.ReadLong(requestReader); DeviceUri = BinaryHelper.ReadString(requestReader); }
private void Repository_PivotAffected(string domain, FactID pivotId, FactID factId, Guid clientGuid) { _messageBus.Notify(domain, pivotId); var subscribers = _repository.LoadWindowsPhoneSubscriptions(new List<FactID> { pivotId }, clientGuid); if (subscribers.Any()) { var messageBody = new FactTreeMemento(0); AddToFactTree(domain, messageBody, factId, null); SendWindowsPhonePushNotifications(subscribers, messageBody); } }