public void Can_roundtrip_DispatchItem_with_complex_event() { var body = new XDoc("msg").Elem("foo", "bar"); var channel = new XUri("channel://foo.com/bar"); var resource = new XUri("http://foo.com/baz/0"); var origin1 = new XUri("http://foo.com/baz/1"); var origin2 = new XUri("http://foo.com/baz/2"); var recipient1 = new DispatcherRecipient(new XUri("http://recipient1")); var recipient2 = new DispatcherRecipient(new XUri("http://recipient2")); var via1 = new XUri("http://via1"); var via2 = new XUri("http://via2"); var ev = new DispatcherEvent(body, channel, resource, origin1, origin2); ev = ev.WithRecipient(false, recipient1, recipient2).WithVia(via1).WithVia(via2); var item = new DispatchItem( new XUri("http://foo"), ev, "abc" ); var serializer = new DispatchItemSerializer(); var stream = serializer.ToStream(item); var item2 = serializer.FromStream(stream); Assert.AreEqual(item.Uri, item2.Uri, "uri mismatch"); Assert.AreEqual(item.Location, item2.Location, "location mismatch"); Assert.AreEqual(item.Event.Id, item2.Event.Id, "id mismatch"); Assert.AreEqual(body.ToCompactString(), item2.Event.AsDocument().ToCompactString(), "body mismatch"); Assert.AreEqual(channel, item2.Event.Channel, "channel mismatch"); Assert.AreEqual(resource, item2.Event.Resource, "resource mismatch"); Assert.AreEqual(origin1, item2.Event.Origins[0], "first origin mismatch"); Assert.AreEqual(origin2, item2.Event.Origins[1], "second origin mismatch"); Assert.AreEqual(recipient1.Uri, item2.Event.Recipients[0].Uri, "first recipient mismatch"); Assert.AreEqual(recipient2.Uri, item2.Event.Recipients[1].Uri, "second recipient mismatch"); Assert.AreEqual(via1, item2.Event.Via[0], "first via mismatch"); Assert.AreEqual(via2, item2.Event.Via[1], "second via mismatch"); }
public void Add_recipients_to_event() { XDoc msg = new XDoc("msg"); DispatcherRecipient r1 = new DispatcherRecipient(new XUri("mailto:///[email protected]")); DispatcherRecipient r2 = new DispatcherRecipient(new XUri("mailto:///[email protected]")); DispatcherRecipient r3 = new DispatcherRecipient(new XUri("mailto:///[email protected]")); DispatcherEvent ev1 = new DispatcherEvent(msg, new XUri("channel://foo.com/bar"), new XUri("http://foo.com/baz")); DispatcherEvent ev2 = ev1.WithRecipient(false, r1); Assert.AreEqual(0, ev1.Recipients.Length); Assert.AreEqual(1, ev2.Recipients.Length); Assert.AreEqual(r1, ev2.Recipients[0]); DispatcherEvent ev3 = ev2.WithRecipient(false, r2, r3); Assert.AreEqual(3, ev3.Recipients.Length); Assert.AreEqual(r1, ev3.Recipients[0]); Assert.AreEqual(r2, ev3.Recipients[1]); Assert.AreEqual(r3, ev3.Recipients[2]); DreamMessage ev3msg = ev3.AsMessage(); Assert.AreEqual(msg, ev3msg.ToDocument()); Assert.AreEqual(ev1.Id, ev3.Id); Assert.AreEqual("channel://foo.com/bar", ev3msg.Headers.DreamEventChannel); Assert.AreEqual("http://foo.com/baz", ev3msg.Headers.DreamEventOrigin[0]); string[] recipients = ev3msg.Headers.DreamEventRecipients; Assert.AreEqual(3, recipients.Length); Assert.AreEqual(r1.ToString(), recipients[0]); Assert.AreEqual(r2.ToString(), recipients[1]); Assert.AreEqual(r3.ToString(), recipients[2]); }
protected override Yield DetermineRecipients(DispatcherEvent ev, DispatcherRecipient[] recipients, Result<DispatcherEvent> result) { List<DispatcherRecipient> recipients2 = new List<DispatcherRecipient>(); Dictionary<int, DispatcherRecipient> userIds = new Dictionary<int, DispatcherRecipient>(); foreach(DispatcherRecipient r in recipients) { string authtoken = r.Doc["@authtoken"].AsText; if(string.IsNullOrEmpty(authtoken)) { // if the reciepient has no authtoken, but has a userid, collect the Id so we can authorize it against the page int? userId = r.Doc["@userid"].AsInt; if(userId.HasValue) { userIds.Add(userId.Value, r); } } else if(authtoken == _authtoken) { // authtoken means the recipient doesn't need page level authorization (such as lucene) recipients2.Add(r); } } if(userIds.Count > 0 && (ev.Channel.Segments.Length <= 2 || !StringUtil.EqualsInvariantIgnoreCase(ev.Channel.Segments[2], "delete"))) { // check all userId's against the page to prune set to authorized users XDoc users = new XDoc("users"); foreach(int userid in userIds.Keys) { users.Start("user").Attr("id", userid).End(); } XDoc changeDoc = ev.AsDocument(); uint? pageid = changeDoc["pageid"].AsUInt; string wikiId = changeDoc["@wikiid"].AsText; if(pageid.HasValue) { Result<DreamMessage> userAuthResult; yield return userAuthResult = _deki.At("pages", pageid.Value.ToString(), "allowed") .With("permissions", "read,subscribe") .With("filterdisabled", true) .WithHeader("X-Deki-Site", "id=" + wikiId) .PostAsync(users); DreamMessage userAuth = userAuthResult.Value; if(userAuth.IsSuccessful) { int authorized = 0; foreach(XDoc userid in userAuth.ToDocument()["user/@id"]) { DispatcherRecipient recipient; if(!userIds.TryGetValue(userid.AsInt.GetValueOrDefault(), out recipient)) { continue; } authorized++; recipients2.Add(recipient); } if(authorized != userIds.Count) { _log.DebugFormat("requested auth on {0} users, received auth on {1} for page {2}", userIds.Count, authorized, pageid.Value); } } else { _log.WarnFormat("unable to retrieve user auth for page '{0}': {1}", pageid, userAuth.Status); } } } result.Return(recipients2.Count == 0 ? null : ev.WithRecipient(true, recipients2.ToArray())); yield break; }
/// <summary> /// Override hook for filtering recipients for an event. /// </summary> /// <param name="ev">Event to be dispatched.</param> /// <param name="recipients">List of proposed recipients.</param> /// <param name="result">The <see cref="Result"/>instance to be returned by this method.</param> /// <returns>Synchronization handle for the action's execution.</returns> protected virtual Yield DetermineRecipients(DispatcherEvent ev, DispatcherRecipient[] recipients, Result<DispatcherEvent> result) { if(ev.Recipients.Length == 0) { //if the event has no reciepient list, anyone can receive it result.Return(ev); yield break; } recipients = ArrayUtil.Intersect(ev.Recipients, recipients); result.Return(recipients.Length == 0 ? null : ev.WithRecipient(true, recipients)); yield break; }
public void Speed() { var body = new XDoc("msg").Elem("foo", "bar"); var channel = new XUri("channel://foo.com/bar"); var resource = new XUri("http://foo.com/baz/0"); var origin1 = new XUri("http://foo.com/baz/1"); var origin2 = new XUri("http://foo.com/baz/2"); var recipient1 = new DispatcherRecipient(new XUri("http://recipient1")); var recipient2 = new DispatcherRecipient(new XUri("http://recipient2")); var via1 = new XUri("http://via1"); var via2 = new XUri("http://via2"); var ev = new DispatcherEvent(body, channel, resource, origin1, origin2); ev = ev.WithRecipient(false, recipient1, recipient2).WithVia(via1).WithVia(via2); var item = new DispatchItem( new XUri("http://foo"), ev, "abc" ); var serializer = new DispatchItemSerializer(); Stream stream = null; var n = 100000; var t = Stopwatch.StartNew(); for(var i = 0; i < n; i++) { stream = serializer.ToStream(item); } t.Stop(); Console.WriteLine("serialize {0:0} items/sec", n / t.Elapsed.TotalSeconds); t = Stopwatch.StartNew(); for(var i = 0; i < n; i++) { serializer.FromStream(stream); stream.Seek(0, SeekOrigin.Begin); } t.Stop(); Console.WriteLine("deserialize {0:0} items/sec", n / t.Elapsed.TotalSeconds); }
public void Recipient_can_be_used_as_Dictionary_key() { Dictionary<DispatcherRecipient, string> dictionary = new Dictionary<DispatcherRecipient, string>(); DispatcherRecipient r1 = new DispatcherRecipient(new XUri("http://foo.com/bar")); DispatcherRecipient r2 = new DispatcherRecipient(new XUri("http://foo.com/baz")); DispatcherRecipient r3 = new DispatcherRecipient(new XUri("http://foop.com/bar")); dictionary.Add(r1, "r1"); dictionary.Add(r2, "r2"); dictionary.Add(r3, "r3"); Assert.AreEqual("r1", dictionary[r1]); Assert.AreEqual("r2", dictionary[r2]); Assert.AreEqual("r3", dictionary[r3]); DispatcherRecipient r1_1 = new DispatcherRecipient(new XUri("http://foo.com/bar")); Assert.AreEqual("r1", dictionary[r1_1]); DispatcherRecipient r1_2 = new DispatcherRecipient(new XDoc("recipient").Attr("foo", "bar").Elem("uri", "http://foo.com/bar").Elem("extra", "stuff")); Assert.AreEqual("r1", dictionary[r1_1]); }
/// <summary> /// Add recipients to the message. /// </summary> /// <param name="replace">If <see langword="True"/>, the provide list replaces any existing recipients.</param> /// <param name="recipients">Zero or more recipients.</param> /// <returns>New event instance.</returns> public DispatcherEvent WithRecipient(bool replace, params DispatcherRecipient[] recipients) { if(replace) { return new DispatcherEvent(this, Via, recipients); } DispatcherRecipient[] newRecipients = new DispatcherRecipient[Recipients.Length + recipients.Length]; Array.Copy(Recipients, newRecipients, Recipients.Length); Array.Copy(recipients, 0, newRecipients, Recipients.Length, recipients.Length); return new DispatcherEvent(this, Via, newRecipients); }
private DispatcherEvent(DispatcherEvent ev, XUri[] via, DispatcherRecipient[] recipients) { _message = ev._message; Id = ev.Id; Channel = ev.Channel; Resource = ev.Resource; Origins = ev.Origins; Recipients = recipients; Via = via; }