示例#1
0
        public void Dispatch_will_send_https_resources_to_subscriptions_without_resource()
        {
            DispatcherEvent ev = new DispatcherEvent(
                new XDoc("msg"),
                new XUri("channel:///foo/bar"),
                new XUri("https://foobar.com/some/page"));
            XUri testUri = new XUri("http:///").At(StringUtil.CreateAlphaNumericKey(4));
            AutoResetEvent resetEvent = new AutoResetEvent(false);
            MockPlug.Register(testUri, delegate(Plug plug, string verb, XUri uri, DreamMessage request, Result<DreamMessage> response) {
                resetEvent.Set();
                response.Return(DreamMessage.Ok());
            });
            Plug owner = Plug.New("mock:///pubsub");
            DreamCookie cookie = DreamCookie.NewSetCookie("foo", "bar", new XUri("http://xyz/abc/"));
            Dispatcher dispatcher = new Dispatcher(new DispatcherConfig { ServiceUri = owner, ServiceAccessCookie = cookie });
            AutoResetEvent setResetEvent = new AutoResetEvent(false);
            dispatcher.CombinedSetUpdated += delegate {
                setResetEvent.Set();
            };
            dispatcher.RegisterSet(
                new XDoc("subscription-set")
                    .Elem("uri.owner", "http:///owner1")
                    .Start("subscription")
                        .Attr("id", "1")
                        .Elem("channel", "channel:///foo/*")
                        .Start("recipient").Elem("uri", testUri).End()
                    .End());

            // combinedset updates happen asynchronously, so give'em a chance
            Assert.IsTrue(setResetEvent.WaitOne(10000, false));
            dispatcher.Dispatch(ev);

            // dispatch happens async on a worker thread
            Assert.IsTrue(resetEvent.WaitOne(10000, false));
            MockPlug.Deregister(testUri);
        }
示例#2
0
        public void Dispatch_based_on_channel_match_with_different_wikiid_patterns_but_same_proxy_destination()
        {
            DispatcherEvent ev = new DispatcherEvent(
                new XDoc("msg"),
                new XUri("event://sales.mindtouch.com/deki/comments/create"),
                new XUri("http://foobar.com/some/comment"));
            List<DreamMessage> dispatches = new List<DreamMessage>();
            XUri testUri = new XUri("http://sales.mindtouch.com/").At(StringUtil.CreateAlphaNumericKey(4));
            AutoResetEvent resetEvent = new AutoResetEvent(false);
            int dispatchCounter = 0;
            int expectedDispatches = 0;
            MockPlug.Register(testUri, delegate(Plug plug, string verb, XUri uri, DreamMessage request, Result<DreamMessage> response) {
                if(testUri == plug.Uri) {
                    dispatches.Add(request);
                    dispatchCounter++;
                    // ReSharper disable AccessToModifiedClosure
                    if(dispatchCounter >= expectedDispatches) {
                        // ReSharper restore AccessToModifiedClosure
                        resetEvent.Set();
                    }
                }
                response.Return(DreamMessage.Ok());
            });
            Plug owner = Plug.New("mock:///pubsub");
            DreamCookie cookie = DreamCookie.NewSetCookie("foo", "bar", new XUri("http://xyz/abc/"));
            Dispatcher dispatcher = new Dispatcher(new DispatcherConfig { ServiceUri = owner, ServiceAccessCookie = cookie });
            int expectedCombinedSetUpdates = 2;
            int combinedSetUpdates = 0;
            AutoResetEvent setResetEvent = new AutoResetEvent(false);
            dispatcher.CombinedSetUpdated += delegate {
                combinedSetUpdates++;
                _log.DebugFormat("combinedset updated ({0})", combinedSetUpdates);
                if(combinedSetUpdates >= expectedCombinedSetUpdates) {
                    setResetEvent.Set();
                }
            };
            dispatcher.RegisterSet(
                new XDoc("subscription-set")
                    .Elem("uri.owner", "http:///owner1")
                    .Start("subscription")
                        .Attr("id", "1")
                        .Elem("channel", "event://sales.mindtouch.com/deki/comments/create")
                        .Elem("channel", "event://sales.mindtouch.com/deki/comments/update")
                        .Elem("uri.proxy", testUri)
                        .Start("recipient").Elem("uri", testUri.At("sub1")).End()
                    .End());
            dispatcher.RegisterSet(
                new XDoc("subscription-set")
                    .Elem("uri.owner", "http:///owner2")
                    .Start("subscription")
                        .Attr("id", "3")
                        .Elem("channel", "event://*/deki/comments/create")
                        .Elem("channel", "event://*/deki/comments/update")
                        .Elem("uri.proxy", testUri)
                        .Start("recipient").Elem("uri", testUri.At("sub2")).End()
                    .End());

            // combinedset updates happen asynchronously, so give'em a chance
            Assert.IsTrue(setResetEvent.WaitOne(10000, false));
            expectedDispatches = 1;
            dispatcher.Dispatch(ev);

            // dispatch happens async on a worker thread
            Assert.IsTrue(resetEvent.WaitOne(10000, false));
            Assert.AreEqual(1, dispatches.Count);
            Assert.AreEqual(ev.AsMessage().ToDocument(), dispatches[0].ToDocument());
            Assert.AreEqual(ev.Id, dispatches[0].Headers.DreamEventId);
            MockPlug.Deregister(testUri);
        }
示例#3
0
        public void Dispatch_based_on_recipients()
        {
            int workers;
            int io;
            ThreadPool.GetAvailableThreads(out workers, out io);
            _log.DebugFormat("threadpool threads: {0}/{1}", workers, io);
            string proxyRecipient1 = "mailto:///[email protected]";
            string proxyRecipient2 = "mailto:///[email protected]";
            XDoc msg = new XDoc("foo");
            DispatcherEvent ev = new DispatcherEvent(
                msg,
                new XUri("channel:///foo/bar"),
                new XUri("http://foobar.com/some/page"))
                .WithRecipient(false,
                    new DispatcherRecipient(new XUri(proxyRecipient1)),
                    new DispatcherRecipient(new XUri("mailto:///[email protected]")),
                    new DispatcherRecipient(new XUri(proxyRecipient2)));
            Dictionary<XUri, DreamMessage> dispatches = new Dictionary<XUri, DreamMessage>();
            XUri testUri = new XUri("http:///").At(StringUtil.CreateAlphaNumericKey(4));
            AutoResetEvent resetEvent = new AutoResetEvent(false);
            MockPlug.Register(testUri, delegate(Plug plug, string verb, XUri uri, DreamMessage request, Result<DreamMessage> response) {
                dispatches.Add(plug.Uri, request);
                resetEvent.Set();
                response.Return(DreamMessage.Ok());
            });
            Plug owner = Plug.New("mock:///pubsub");
            DreamCookie cookie = DreamCookie.NewSetCookie("foo", "bar", new XUri("http://xyz/abc/"));
            Dispatcher dispatcher = new Dispatcher(new DispatcherConfig { ServiceUri = owner, ServiceAccessCookie = cookie });
            AutoResetEvent setResetEvent = new AutoResetEvent(false);
            dispatcher.CombinedSetUpdated += delegate {
                _log.DebugFormat("set updated");
                setResetEvent.Set();
            };

            XUri proxy = testUri.At("proxy");
            _log.DebugFormat("registering set");
            dispatcher.RegisterSet(
                new XDoc("subscription-set")
                    .Elem("uri.owner", "http:///owner1")
                    .Start("subscription")
                        .Attr("id", "1")
                        .Elem("channel", "channel:///foo/*")
                        .Elem("uri.proxy", proxy)
                        .Start("recipient").Elem("uri", proxyRecipient1).End()
                        .Start("recipient").Elem("uri", proxyRecipient2).End()
                    .End()
                    .Start("subscription")
                        .Attr("id", "2")
                        .Elem("channel", "channel:///foo/*")
                        .Start("recipient").Elem("uri", testUri.At("sub2")).End()
                    .End());

            //Set updates happen asynchronously, so give it a chance
            _log.DebugFormat("giving registration a chance to manifest");
            Assert.IsTrue(setResetEvent.WaitOne(10000, false));
            _log.DebugFormat("dispatching event");
            dispatcher.Dispatch(ev);

            // dispatch happens async on a worker thread
            Assert.IsTrue(resetEvent.WaitOne(1000, false));
            Thread.Sleep(200);
            Assert.AreEqual(1, dispatches.Count);
            Assert.IsTrue(dispatches.ContainsKey(proxy));
            Assert.AreEqual(msg, dispatches[proxy].ToDocument());
            Assert.AreEqual(ev.Id, dispatches[proxy].Headers.DreamEventId);
            string[] recipients = dispatches[proxy].Headers.DreamEventRecipients;
            Assert.AreEqual(2, recipients.Length);
            Assert.Contains(proxyRecipient1, recipients);
            Assert.Contains(proxyRecipient2, recipients);
            MockPlug.Deregister(testUri);
        }
示例#4
0
 public void Dispatcher_replaceset_for_wrong_owner_throws()
 {
     Plug owner = Plug.New("mock:///pubsub");
     DreamCookie cookie = DreamCookie.NewSetCookie("foo", "bar", new XUri("http://xyz/abc/"));
     Dispatcher dispatcher = new Dispatcher(new DispatcherConfig { ServiceUri = owner, ServiceAccessCookie = cookie });
     XDoc subset = new XDoc("subscription-set")
         .Attr("max-failures", 1)
         .Elem("uri.owner", "http:///owner")
         .Start("subscription")
         .Attr("id", "123")
         .Elem("channel", "channel:///foo")
         .Start("recipient").Attr("auth-token", "abc").Elem("uri", "mailto://[email protected]").End()
         .End();
     Tuplet<PubSubSubscriptionSet, bool> location = dispatcher.RegisterSet(subset);
     XDoc subset2 = new XDoc("subscription-set")
         .Attr("max-failures", 1)
         .Elem("uri.owner", "http:///ownerx")
         .Start("subscription")
         .Attr("id", "123")
         .Elem("channel", "channel:///foo")
         .Start("recipient").Attr("auth-token", "abc").Elem("uri", "mailto://[email protected]").End()
         .End();
     try {
         dispatcher.ReplaceSet(location.Item1.Location, subset2);
     } catch(ArgumentException) {
         return;
     }
     Assert.Fail();
 }
示例#5
0
        public void Dispatch_based_on_channel_and_resource_match()
        {
            DispatcherEvent ev = new DispatcherEvent(
                new XDoc("msg"),
                new XUri("channel:///foo/bar"),
                new XUri("http://foobar.com/some/page"));
            Dictionary<XUri, DreamMessage> dispatches = new Dictionary<XUri, DreamMessage>();
            XUri testUri = new XUri("http:///").At(StringUtil.CreateAlphaNumericKey(4));
            AutoResetEvent resetEvent = new AutoResetEvent(false);
            int expectedDispatches = 0;
            MockPlug.Register(testUri, delegate(Plug plug, string verb, XUri uri, DreamMessage request, Result<DreamMessage> response) {
                dispatches.Add(plug.Uri, request);
                // ReSharper disable AccessToModifiedClosure
                if(dispatches.Count >= expectedDispatches) {
                    // ReSharper restore AccessToModifiedClosure
                    resetEvent.Set();
                }
                response.Return(DreamMessage.Ok());
            });
            Plug owner = Plug.New("mock:///pubsub");
            DreamCookie cookie = DreamCookie.NewSetCookie("foo", "bar", new XUri("http://xyz/abc/"));
            Dispatcher dispatcher = new Dispatcher(new DispatcherConfig { ServiceUri = owner, ServiceAccessCookie = cookie });
            int expectedCombinedSetUpdates = 2;
            int combinedSetUpdates = 0;
            AutoResetEvent setResetEvent = new AutoResetEvent(false);
            dispatcher.CombinedSetUpdated += delegate {
                combinedSetUpdates++;
                _log.DebugFormat("combinedset updated ({0})", combinedSetUpdates);
                if(combinedSetUpdates >= expectedCombinedSetUpdates) {
                    setResetEvent.Set();
                }
            };
            dispatcher.RegisterSet(
                new XDoc("subscription-set")
                    .Elem("uri.owner", "http:///owner1")
                    .Start("subscription")
                        .Attr("id", "1")
                        .Elem("channel", "channel:///foo/*")
                        .Elem("uri.resource", "http://*/some/*")
                        .Start("recipient").Elem("uri", testUri.At("sub1")).End()
                    .End()
                    .Start("subscription")
                        .Attr("id", "2")
                        .Elem("channel", "channel:///foo/baz")
                        .Elem("uri.resource", "http://*/some/*")
                        .Start("recipient").Elem("uri", testUri.At("sub2")).End()
                    .End());
            dispatcher.RegisterSet(
                new XDoc("subscription-set")
                    .Elem("uri.owner", "http:///owner2")
                    .Start("subscription")
                        .Attr("id", "3")
                        .Elem("channel", "channel:///foo/bar")
                        .Elem("uri.resource", "http://foobar.com/some/page")
                        .Start("recipient").Elem("uri", testUri.At("sub3")).End()
                    .End()
                    .Start("subscription")
                        .Attr("id", "4")
                        .Elem("channel", "channel:///foo/bar")
                        .Elem("uri.resource", "http://baz.com/some/*")
                        .Start("recipient").Elem("uri", testUri.At("sub4")).End()
                    .End());

            // combinedset updates happen asynchronously, so give'em a chance
            Assert.IsTrue(setResetEvent.WaitOne(10000, false));
            expectedDispatches = 2;
            dispatcher.Dispatch(ev);

            // dispatch happens async on a worker thread
            Assert.IsTrue(resetEvent.WaitOne(10000, false));
            Thread.Sleep(200);
            Assert.AreEqual(2, dispatches.Count);
            Assert.IsTrue(dispatches.ContainsKey(testUri.At("sub1")));
            Assert.AreEqual(ev.AsMessage().ToDocument(), dispatches[testUri.At("sub1")].ToDocument());
            Assert.AreEqual(ev.Id, dispatches[testUri.At("sub1")].Headers.DreamEventId);
            Assert.IsTrue(dispatches.ContainsKey(testUri.At("sub3")));
            MockPlug.Deregister(testUri);
        }
示例#6
0
 public void Dispatcher_removeset_returns_false_on_missing_set()
 {
     DreamCookie cookie = DreamCookie.NewSetCookie("foo", "bar", new XUri("http://xyz/abc/"));
     Plug owner = Plug.New("mock:///pubsub");
     Dispatcher dispatcher = new Dispatcher(new DispatcherConfig { ServiceUri = owner, ServiceAccessCookie = cookie });
     XDoc subset = new XDoc("subscription-set")
         .Attr("max-failures", 1)
         .Elem("uri.owner", "http:///owner")
         .Start("subscription")
         .Attr("id", "123")
         .Elem("channel", "channel:///foo")
         .Start("recipient").Attr("auth-token", "abc").Elem("uri", "mailto://[email protected]").End()
         .End();
     Tuplet<PubSubSubscriptionSet, bool> location = dispatcher.RegisterSet(subset);
     Assert.IsFalse(location.Item2);
     Assert.IsNotNull(dispatcher[location.Item1.Location]);
     Assert.IsTrue(dispatcher.RemoveSet(location.Item1.Location));
     Assert.IsNull(dispatcher[location.Item1.Location]);
     Assert.IsFalse(dispatcher.RemoveSet(location.Item1.Location));
 }
示例#7
0
 public void Dispatcher_replaceset_for_unknown_location_returns_false()
 {
     DreamCookie cookie = DreamCookie.NewSetCookie("foo", "bar", new XUri("http://xyz/abc/"));
     Plug owner = Plug.New("mock:///pubsub");
     Dispatcher dispatcher = new Dispatcher(new DispatcherConfig { ServiceUri = owner, ServiceAccessCookie = cookie });
     XDoc subset = new XDoc("subscription-set")
         .Attr("max-failures", 1)
         .Elem("uri.owner", "http:///owner")
         .Start("subscription")
         .Attr("id", "123")
         .Elem("channel", "channel:///foo")
         .Start("recipient").Attr("auth-token", "abc").Elem("uri", "mailto://[email protected]").End()
         .End();
     Assert.IsNull(dispatcher.ReplaceSet("ABCD", subset));
 }
示例#8
0
 public void Dispatcher_creates_set_at_location()
 {
     DreamCookie cookie = DreamCookie.NewSetCookie("foo", "bar", new XUri("http://xyz/abc/"));
     Plug owner = Plug.New("mock:///pubsub");
     Dispatcher dispatcher = new Dispatcher(new DispatcherConfig { ServiceUri = owner, ServiceAccessCookie = cookie });
     XDoc subset = new XDoc("subscription-set")
         .Attr("max-failures", 1)
         .Elem("uri.owner", "http:///owner")
         .Start("subscription")
         .Attr("id", "123")
         .Elem("channel", "channel:///foo")
         .Start("recipient").Attr("auth-token", "abc").Elem("uri", "mailto://[email protected]").End()
         .End();
     Tuplet<PubSubSubscriptionSet, bool> location = dispatcher.RegisterSet(subset);
     Assert.IsFalse(location.Item2);
     PubSubSubscriptionSet set = dispatcher[location.Item1.Location];
     Assert.AreEqual(subset, set.AsDocument());
     Tuplet<PubSubSubscriptionSet, bool> location2 = dispatcher.RegisterSet(subset);
     Assert.IsTrue(location2.Item2);
     Assert.AreEqual(location.Item1.Location, location2.Item1.Location);
 }
示例#9
0
        public void Repeated_dispatch_failure_kicks_subscription_set()
        {
            // TODO (steveb): test fails under Mono 2.8.2

            var sub1Uri = new XUri("http://sub1/foo");
            var sub1Mock = MockPlug.Register(sub1Uri);
            sub1Mock.Expect().Verb("POST").Response(DreamMessage.BadRequest("nobody home"));
            var sub2Uri = new XUri("http://sub2/foo");
            var sub2Mock = MockPlug.Register(sub2Uri);
            sub2Mock.Expect().Verb("POST").Response(DreamMessage.BadRequest("nobody home"));
            var ev = new DispatcherEvent(
                new XDoc("msg"),
                new XUri("channel:///foo/bar"),
                new XUri("http://foobar.com/some/page"));
            var cookie = DreamCookie.NewSetCookie("foo", "bar", new XUri("http://xyz/abc/"));
            var dispatcher = new Dispatcher(new DispatcherConfig { ServiceUri = Plug.New("mock:///pubsub"), ServiceAccessCookie = cookie });
            var expectedCombinedSetUpdates = 2;
            var combinedSetUpdates = 0;
            var setResetEvent = new ManualResetEvent(false);
            dispatcher.CombinedSetUpdated += delegate {
                combinedSetUpdates++;
                _log.DebugFormat("combinedset updated ({0})", combinedSetUpdates);
                if(combinedSetUpdates >= expectedCombinedSetUpdates) {
                    setResetEvent.Set();
                }
            };
            var location1 = dispatcher.RegisterSet(new XDoc("subscription-set")
                .Attr("max-failures", 0)
                .Elem("uri.owner", "http:///owner1")
                .Start("subscription")
                    .Attr("id", "1")
                    .Elem("channel", "channel:///foo/*")
                    .Start("recipient").Elem("uri", sub1Uri).End()
                .End()).Item1.Location;
            var location2 = dispatcher.RegisterSet(new XDoc("subscription-set")
                .Attr("max-failures", 0)
                .Elem("uri.owner", "http:///owner2")
                .Start("subscription")
                    .Attr("id", "1")
                    .Elem("channel", "channel:///foo/*")
                    .Start("recipient").Elem("uri", sub2Uri).End()
                .End()).Item1.Location;
            Assert.IsTrue(setResetEvent.WaitOne(10000, false), "combined set didn't change expected number of times");
            Assert.IsNotNull(dispatcher[location1]);
            Assert.IsNotNull(dispatcher[location2]);
            dispatcher.Dispatch(ev);
            Assert.IsTrue(sub1Mock.WaitAndVerify(TimeSpan.FromSeconds(10)), sub1Mock.VerificationFailure);
            Assert.IsTrue(sub2Mock.WaitAndVerify(TimeSpan.FromSeconds(10)), sub1Mock.VerificationFailure);
            Assert.IsTrue(Wait.For(() => dispatcher[location2] == null, TimeSpan.FromSeconds(10)), "Second set wasn't kicked");
            Assert.IsTrue(Wait.For(() => dispatcher[location1] == null, TimeSpan.FromSeconds(10)), "First set wasn't kicked");
        }
示例#10
0
        public void Failed_dispatch_followed_by_success_should_reset_fail_count()
        {
            bool fail = true;
            DispatcherEvent ev = new DispatcherEvent(
             new XDoc("msg"),
             new XUri("channel:///foo/bar"),
             new XUri("http://foobar.com/some/page"));
            XUri testUri = new XUri("http:///").At(StringUtil.CreateAlphaNumericKey(4));
            AutoResetEvent resetEvent = new AutoResetEvent(false);
            int mockCalled = 0;
            MockPlug.Register(testUri, delegate(Plug plug, string verb, XUri uri, DreamMessage request, Result<DreamMessage> response) {
                mockCalled++;
                // ReSharper disable AccessToModifiedClosure
                _log.DebugFormat("mock called {0} times (fail={1}): {2}", mockCalled, fail, uri);
                // ReSharper restore AccessToModifiedClosure
                resetEvent.Set();
                // ReSharper disable AccessToModifiedClosure
                response.Return(fail ? DreamMessage.InternalError() : DreamMessage.Ok());
                // ReSharper restore AccessToModifiedClosure
            });
            DreamCookie cookie = DreamCookie.NewSetCookie("foo", "bar", new XUri("http://xyz/abc/"));
            Dispatcher dispatcher = new Dispatcher(new DispatcherConfig { ServiceUri = Plug.New("mock:///pubsub"), ServiceAccessCookie = cookie });
            int expectedCombinedSetUpdates = 1;
            int combinedSetUpdates = 0;
            AutoResetEvent setResetEvent = new AutoResetEvent(false);
            dispatcher.CombinedSetUpdated += delegate {
                combinedSetUpdates++;
                _log.DebugFormat("combinedset updated ({0})", combinedSetUpdates);
                if(combinedSetUpdates >= expectedCombinedSetUpdates) {
                    setResetEvent.Set();
                }
            };
            string location = dispatcher.RegisterSet(
                new XDoc("subscription-set")
                    .Attr("max-failures", 1)
                    .Elem("uri.owner", "http:///owner1")
                    .Start("subscription")
                        .Attr("id", "1")
                        .Elem("channel", "channel:///foo/*")
                        .Start("recipient").Elem("uri", testUri.At("foo")).End()
                    .End()).Item1.Location;
            Assert.IsTrue(setResetEvent.WaitOne(10000, false));
            Assert.IsNotNull(dispatcher[location]);

            _log.DebugFormat("first dispatch (fail={0})", fail);
            dispatcher.Dispatch(ev);
            Assert.IsTrue(resetEvent.WaitOne(10000, false));
            Thread.Sleep(1000); // failure gets dealt with async
            Assert.IsNotNull(dispatcher[location]);
            fail = false;

            _log.DebugFormat("second dispatch (fail={0})", fail);
            dispatcher.Dispatch(ev);
            Assert.IsTrue(resetEvent.WaitOne(10000, false));
            Thread.Sleep(1000); // failure reset gets dealt with async
            Assert.IsNotNull(dispatcher[location]);
            fail = true;

            _log.DebugFormat("third dispatch (fail={0})", fail);
            dispatcher.Dispatch(ev);
            Assert.IsTrue(resetEvent.WaitOne(10000, false));
            Thread.Sleep(1000); // failure gets dealt with async
            Assert.IsNotNull(dispatcher[location]);

            _log.DebugFormat("fourth dispatch (fail={0})", fail);
            dispatcher.Dispatch(ev);
            Assert.IsTrue(resetEvent.WaitOne(10000, false));
            Thread.Sleep(1000); // failure gets dealt with async
            Assert.IsNull(dispatcher[location]);
            MockPlug.Deregister(testUri);
        }
示例#11
0
 public void Dispatch_with_owners_via_throws()
 {
     XUri loopService = new XUri("local:///infinite/loop-dispatcher");
     DispatcherEvent ev = new DispatcherEvent(new XDoc("foo"), new XUri("channel:///foo"), new XUri("http:///foo"))
         .WithVia(loopService)
         .WithVia(new XUri("local://12345/a"));
     Plug owner = Plug.New(loopService);
     DreamCookie cookie = DreamCookie.NewSetCookie("foo", "bar", new XUri("http://xyz/abc/"));
     Dispatcher dispatcher = new Dispatcher(new DispatcherConfig { ServiceUri = owner, ServiceAccessCookie = cookie });
     try {
         dispatcher.Dispatch(ev);
         Assert.Fail("should not have gotten here");
     } catch(DreamBadRequestException) {
         return;
     }
     Assert.Fail("should not have gotten here");
 }
示例#12
0
 public void Setup()
 {
     MockPlug.DeregisterAll();
     var cookie = DreamCookie.NewSetCookie("foo", "bar", new XUri("http://xyz/abc/"));
     var owner = Plug.New("mock:///pubsub");
     _queueRepositoryMock = new Mock<IPubSubDispatchQueueRepository>();
     _queueRepositoryMock.Setup(x => x.InitializeRepository(It.IsAny<Func<DispatchItem, Result<bool>>>()))
         .Callback((Func<DispatchItem, Result<bool>> handler) => _dequeueHandler = handler);
     _queueRepositoryMock.Setup(x => x.GetUninitializedSets())
         .Returns(new PubSubSubscriptionSet[0]);
     _dispatcher = new Dispatcher(new DispatcherConfig { ServiceUri = owner, ServiceAccessCookie = cookie }, _queueRepositoryMock.Object);
 }